Commit 9191eb75 authored by Kimber's avatar Kimber

'init'

parents
Pipeline #326 failed with stages
# https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
ENV = 'production'
# 如果使用 Nginx 代理后端接口,那么此处需要改为 '/',文件查看 Docker 部署篇,Nginx 配置
# 接口地址,注意协议,如果你没有配置 ssl,需要将 https 改为 http
# 如果接口是 http 形式, wss 需要改为 ws
# 山西柳林安泰洗煤边坡 ------------------------
VUE_APP_BASE_API = 'http://192.168.26.8:9045'
VUE_APP_LOCAL_API = 'http://192.168.26.8:9001'
# 冯克贞 ------------------------
#VUE_APP_BASE_API = 'http://192.168.27.147:9045'
#VUE_APP_LOCAL_API = 'http://192.168.27.147:9001'
# 山西柳林 ------------------------
#VUE_APP_BASE_API = 'http://192.168.1.10:9045'
#VUE_APP_LOCAL_API = 'http://192.168.1.10:9001'
# 线上环境 --------------------------
#VUE_APP_BASE_API = 'http://8.142.46.126:9045'
#VUE_APP_LOCAL_API = 'http://8.142.46.126:9000'
#VUE_APP_BASE_API = 'http://192.168.4.61:9046'
#VUE_APP_LOCAL_API = 'http://192.168.4.61:9001'
#VUE_APP_LOCAL_API = 'http://192.168.4.61:9000'
#VUE_APP_LOCAL_API2 = 'http://192.168.4.61:9000'
#VUE_APP_LOCAL_b3dms = 'http://192.168.1.3:8045'
\ No newline at end of file
build/*.js
src/assets
public
dist
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
extends: ['plugin:vue/recommended', 'eslint:recommended'],
// add your custom rules here
//it is base on https://github.com/vuejs/eslint-config-vue
rules: {
"vue/max-attributes-per-line": [2, {
"singleline": 10,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}],
"vue/singleline-html-element-content-newline": "off",
"vue/multiline-html-element-content-newline":"off",
"vue/name-property-casing": ["error", "PascalCase"],
"vue/no-v-html": "off",
'accessor-pairs': 2,
'arrow-spacing': [2, {
'before': true,
'after': true
}],
'block-spacing': [2, 'always'],
'brace-style': [2, '1tbs', {
'allowSingleLine': true
}],
'camelcase': [0, {
'properties': 'always'
}],
'comma-dangle': [2, 'never'],
'comma-spacing': [2, {
'before': false,
'after': true
}],
'comma-style': [2, 'last'],
'constructor-super': 2,
'curly': [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
'eqeqeq': ["error", "always", {"null": "ignore"}],
'generator-star-spacing': [2, {
'before': true,
'after': true
}],
'handle-callback-err': [2, '^(err|error)$'],
'indent': [2, 2, {
'SwitchCase': 1
}],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [2, {
'beforeColon': false,
'afterColon': true
}],
'keyword-spacing': [2, {
'before': true,
'after': true
}],
'new-cap': [2, {
'newIsCap': true,
'capIsNew': false
}],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-console': 'off',
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [2, {
'allowLoop': false,
'allowSwitch': false
}],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [2, {
'max': 1
}],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [2, {
'defaultAssignment': false
}],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [2, {
'vars': 'all',
'args': 'none'
}],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [2, {
'initialized': 'never'
}],
'operator-linebreak': [2, 'after', {
'overrides': {
'?': 'before',
':': 'before'
}
}],
'padded-blocks': [2, 'never'],
'quotes': [2, 'single', {
'avoidEscape': true,
'allowTemplateLiterals': true
}],
'semi': [2, 'never'],
'semi-spacing': [2, {
'before': false,
'after': true
}],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [2, {
'words': true,
'nonwords': false
}],
'spaced-comment': [2, 'always', {
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
'yoda': [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [2, 'always', {
objectsInObjects: false
}],
'array-bracket-spacing': [2, 'never']
}
}
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
**/*.log
tests/**/coverage/
tests/e2e/reports
selenium-debug.log
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.local
*.env.development
*dist.rar
package-lock.json
yarn.lock
language: node_js
node_js: 10
script: npm run test
notifications:
email: false
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "{}" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright 2019 Zheng Jie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
const plugins = ['@vue/babel-plugin-transform-vue-jsx']
// 生产环境移除console
if (process.env.NODE_ENV === 'production') {
plugins.push('transform-remove-console')
}
module.exports = {
plugins: plugins,
presets: [
'@vue/app'
]
}
var ServiceURL = 'http://192.168.26.8:9002';
window.VUE_APP_API = {ServiceURL:ServiceURL}
[.ShellClassInfo]
ConfirmFileOp=0
IconFile=C:\Users\zhr\AppData\Local\SynologyDrive\SynologyDrive.app\bin\cloud-drive-ui.exe
IconIndex=3
InfoTip=Synology Drive Client.
module.exports = {
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub',
'^.+\\.jsx?$': 'babel-jest'
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
snapshotSerializers: ['jest-serializer-vue'],
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
coverageDirectory: '<rootDir>/tests/unit/coverage',
// 'collectCoverage': true,
'coverageReporters': [
'lcov',
'text-summary'
],
testURL: 'http://localhost/'
}
{
"name": "gemho",
"version": "1.0.0",
"description": "ADMIN-source-code",
"main": "index.js",
"author": "kimber",
"license": "ISC",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "vue-cli-service serve --open",
"build": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview"
},
"keywords": [
"admin"
],
"dependencies": {
"@riophae/vue-treeselect": "0.4.0",
"axios": "^0.21.1",
"clipboard": "2.0.4",
"codemirror": "^5.49.2",
"connect": "3.6.6",
"core-js": "^2.6.12",
"element-ui": "^2.13.2",
"file-saver": "1.3.8",
"fuse.js": "3.4.4",
"js-beautify": "^1.10.2",
"js-cookie": "2.2.0",
"jsencrypt": "^3.0.0-rc.1",
"jszip": "3.1.5",
"mavon-editor": "^2.9.0",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"path-to-regexp": "2.4.0",
"qs": "^6.9.1",
"screenfull": "4.2.0",
"sortablejs": "1.8.4",
"vue": "2.6.10",
"vue-count-to": "1.0.13",
"vue-cropper": "0.4.9",
"vue-echarts": "^5.0.0-beta.0",
"vue-highlightjs": "^1.3.3",
"vue-image-crop-upload": "^2.5.0",
"vue-router": "3.0.2",
"vue-splitpane": "1.0.4",
"vuedraggable": "2.20.0",
"vuex": "3.1.0",
"wangeditor": "^3.1.1",
"xlsx": "^0.17.1"
},
"devDependencies": {
"@babel/core": "7.0.0",
"@babel/parser": "^7.7.4",
"@babel/register": "7.0.0",
"@vue/babel-plugin-transform-vue-jsx": "^1.2.1",
"@vue/cli-plugin-babel": "3.5.3",
"@vue/cli-plugin-eslint": "^3.9.1",
"@vue/cli-plugin-unit-jest": "3.5.3",
"@vue/cli-service": "3.5.3",
"@vue/test-utils": "1.0.0-beta.29",
"autoprefixer": "^9.5.1",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "10.0.1",
"babel-jest": "23.6.0",
"babel-plugin-dynamic-import-node": "2.3.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"chalk": "2.4.2",
"chokidar": "2.1.5",
"connect": "3.6.6",
"copy-webpack-plugin": "^4.5.2",
"eslint": "5.15.3",
"eslint-plugin-vue": "5.2.2",
"ezuikit-js": "^0.3.0",
"highcharts": "^9.2.2",
"html-webpack-plugin": "3.2.0",
"http-proxy-middleware": "^0.19.1",
"husky": "1.3.1",
"lint-staged": "8.1.5",
"plop": "2.3.0",
"print-js": "^1.6.0",
"runjs": "^4.3.2",
"sass": "~1.26.5",
"sass-loader": "^10.2.0",
"script-ext-html-webpack-plugin": "2.1.3",
"script-loader": "0.7.2",
"serve-static": "^1.13.2",
"svg-sprite-loader": "4.1.3",
"svgo": "1.2.0",
"vue-template-compiler": "2.6.10"
}
}
const viewGenerator = require('./plop-templates/view/prompt')
const componentGenerator = require('./plop-templates/component/prompt')
module.exports = function(plop) {
plop.setGenerator('view', viewGenerator)
plop.setGenerator('component', componentGenerator)
}
module.exports = {
plugins: {
autoprefixer: {}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<meta http-equiv="Access-Control-Allow-Origin">
<title><%= webpackConfig.name %></title>
<style type="text/css">
html, body, #edge{height:100%;}
body{overflow-x:hidden;}
*, :after, :before{box-sizing:border-box;}
</style>
<script src="/config/settings.js"></script>
<script src="/static/js/qf_web_1.04179_core.js"></script>
</head>
<body class="body2X">
<div id="edge"></div>
</body>
<script type="text/javascript">
window._AMapSecurityConfig = {securityJsCode:'fd66b714a7db0dca113ea6c913f6858f',}
</script>
<!-- <script src="/static/js/AMap/maps2.0.js"></script> -->
<!-- <script src="/static/js/Cesium/Cesium.js"></script> -->
<script src="/static/js/qf_web_ui_1.093.min.js"></script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<meta http-equiv="Access-Control-Allow-Origin">
<title><%= webpackConfig.name %></title>
<script src="/config/settings.js"></script>
<script src="/static/js/qf_web_1.04179_core.js"></script>
</head>
<body class="body2X">
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
<script type="text/javascript">
window._AMapSecurityConfig = {securityJsCode:'fd66b714a7db0dca113ea6c913f6858f',}
</script>
<script src="/static/js/AMap/maps2.0.js"></script>
<script src="/static/js/qf_web_ui_1.093.min.js"></script>
</html>
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default{
name: 'App'
}
</script>
<template>
<div id="edge">
<router-view />
</div>
</template>
<script>
export default{
name: 'Edge'
}
</script>
import request from '@/utils/request'
import qs from 'qs'
export function initData(url, params) {
return request({
url: url + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
export function download(url, params) {
return request({
url: url + '?' + qs.stringify(params, { indices: false }),
method: 'get',
responseType: 'blob'
})
}
import request from '@/utils/request'
export function getDepts(params) {
return request({
url: 'api/dept',
method: 'get',
params
})
}
export function add(data) {
return request({
url: 'api/dept',
method: 'post',
data
})
}
export function del(id) {
return request({
url: 'api/dept/' + id,
method: 'delete'
})
}
export function edit(data) {
return request({
url: 'api/dept',
method: 'put',
data
})
}
export function deptByUseridNoPage() {
return request({
url: 'api/deptByUseridNoPage',
method: 'get'
})
}
import request from '@/utils/request'
export function login(data) {
var param = {
username: data.username,
password: data.password,
code: data.code,
uuid: data.uuid,
areaId: data.areaId,
};
return request({
url: 'auth/login',
method: 'post',
data: param
})
}
export function getInfo() {
return request({
url: 'auth/info',
method: 'get'
})
}
export function setInfo(areaId) {
return request({
url: 'auth/updateInfo',
method: 'post',
data: {
areaId:areaId
}
})
}
export function getCodeImg() {
return request({
url: 'auth/code',
method: 'get'
})
}
export function logout() {
return request({
url: 'auth/logout',
method: 'delete'
})
}
import request from '@/utils/request'
export function getErrDetail(id) {
return request({
url: 'api/logs/error/' + id,
method: 'get'
})
}
export function delAllError() {
return request({
url: 'api/logs/del/error',
method: 'delete'
})
}
export function delAllInfo() {
return request({
url: 'api/logs/del/info',
method: 'delete'
})
}
import request from '@/utils/request'
export function resetEmail(data) {
return request({
url: 'api/code/resetEmail?email=' + data,
method: 'post'
})
}
export function updatePass(pass) {
return request({
url: 'api/users/updatePass/' + pass,
method: 'get'
})
}
import request from '@/utils/request'
export function getDepts(params) {
return request({
url: 'api/dept',
method: 'get',
params
})
}
export function getDeptSuperior(ids) {
const data = ids.length || ids.length === 0 ? ids : Array.of(ids)
return request({
url: 'api/dept/superior',
method: 'post',
data
})
}
export function add(data) {
return request({
url: 'api/dept',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/dept',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: 'api/dept',
method: 'put',
data
})
}
export default { add, edit, del, getDepts, getDeptSuperior }
import request from '@/utils/request'
export function getDicts() {
return request({
url: 'api/dict/all',
method: 'get'
})
}
export function add(data) {
return request({
url: 'api/dict',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/dict/',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: 'api/dict',
method: 'put',
data
})
}
export default { add, edit, del }
import request from '@/utils/request'
export function get(dictName) {
const params = {
dictName,
page: 0,
size: 9999
}
return request({
url: 'api/dictDetail',
method: 'get',
params
})
}
export function getDictMap(dictName) {
const params = {
dictName,
page: 0,
size: 9999
}
return request({
url: 'api/dictDetail/map',
method: 'get',
params
})
}
export function add(data) {
return request({
url: 'api/dictDetail',
method: 'post',
data
})
}
export function del(id) {
return request({
url: 'api/dictDetail/' + id,
method: 'delete'
})
}
export function edit(data) {
return request({
url: 'api/dictDetail',
method: 'put',
data
})
}
export default { add, edit, del }
import request from '@/utils/request'
export function getAllJob() {
const params = {
page: 0,
size: 9999,
enabled: true
}
return request({
url: 'api/job',
method: 'get',
params
})
}
export function add(data) {
return request({
url: 'api/job',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/job',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: 'api/job',
method: 'put',
data
})
}
export default { add, edit, del }
import request from '@/utils/request'
export function reqQuery(params) {
return request({
url: 'api/tabZigbee',
method: 'get',
params
})
}
export function reqAdd(params) {
return request({
url: 'api/tabZigbee',
method: 'post',
params
})
}
export function reqEdit(params) {
return request({
url: 'api/tabZigbee',
method: 'put',
params
})
}
export function reqDelete(params) {
return request({
url: 'api/tabZigbee',
method: 'delete',
params
})
}
export default {reqQuery, reqAdd, reqEdit, reqDelete}
import request from '@/utils/request'
export function getMenusTree(pid) {
return request({
url: 'api/menus/lazy?pid=' + pid,
method: 'get'
})
}
export function getMenus(params) {
return request({
url: 'api/menus',
method: 'get',
params
})
}
export function getMenuSuperior(ids) {
const data = Array.isArray(ids) || ids.length === 0 ? ids : Array.of(ids)
return request({
url: 'api/menus/superior',
method: 'post',
data
})
}
export function getChild(id) {
return request({
url: 'api/menus/child?id=' + id,
method: 'get'
})
}
export function buildMenus() {
return request({
url: 'api/menus/build',
method: 'get'
})
}
export function add(data) {
return request({
url: 'api/menus',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/menus',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: 'api/menus',
method: 'put',
data
})
}
export default { add, edit, del, getMenusTree, getMenuSuperior, getMenus, getChild }
import request from '@/utils/request'
// 获取所有的Role
export function getAll() {
return request({
url: 'api/roles/all',
method: 'get'
})
}
export function add(data) {
return request({
url: 'api/roles',
method: 'post',
data
})
}
export function get(id) {
return request({
url: 'api/roles/' + id,
method: 'get'
})
}
export function getLevel() {
return request({
url: 'api/roles/level',
method: 'get'
})
}
export function del(ids) {
return request({
url: 'api/roles',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: 'api/roles',
method: 'put',
data
})
}
export function editMenu(data) {
return request({
url: 'api/roles/menu',
method: 'put',
data
})
}
export function getUserOnPonds(data) {
return request({
url: 'tab/usertailpon/byuser',
method: 'get',
data:data,
params:data,
})
}
export default { add, edit, del, get, editMenu, getLevel, getUserOnPonds }
import request from '@/utils/request'
export function add(data) {
return request({
url: 'api/jobs',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/jobs',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: 'api/jobs',
method: 'put',
data
})
}
export function updateIsPause(id) {
return request({
url: 'api/jobs/' + id,
method: 'put'
})
}
export function execution(id) {
return request({
url: 'api/jobs/exec/' + id,
method: 'put'
})
}
export default { del, updateIsPause, execution, add, edit }
import request from '@/utils/request'
import { encrypt } from '@/utils/rsaEncrypt'
export function add(data) {
return request({
url: 'api/users',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/users',
method: 'delete',
data: ids
})
}
export function edit(data) {
return request({
url: 'api/users',
method: 'put',
data
})
}
export function editUser(data) {
return request({
url: 'api/users/center',
method: 'put',
data
})
}
// ޸
export function updatePass(user) {
const data = {
oldPass: encrypt(user.oldPass),
newPass: encrypt(user.newPass)
}
return request({
url: 'api/users/updatePass',
method: 'post',
data:data,
})
}
// ûע
export function register(user) {
return request({
url: 'auth/users/register',
method: 'POST',
data:user,
}).then((res) => {
return res
})
}
export function updateEmail(form) {
const data = {
password: encrypt(form.pass),
email: form.email
}
return request({
url: 'api/users/updateEmail/' + form.code,
method: 'post',
data
})
}
export default { add, edit, del }
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.586" height="200" class="icon" p-id="2886" t="1553488917000" version="1.1" viewBox="0 0 1027 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M512 750.933333c-112.64 0-211.626667-119.466667-245.76-242.346666-34.133333 0-61.44-44.373333-61.44-102.4 0-17.066667 3.413333-34.133333 6.826667-47.786667-3.413333-20.48-6.826667-47.786667-6.826667-68.266667C204.8 129.706667 341.333333 0 508.586667 0S819.2 133.12 819.2 290.133333c0 20.48-3.413333 47.786667-6.826667 68.266667 3.413333 13.653333 6.826667 30.72 6.826667 47.786667 0 58.026667-27.306667 102.4-61.44 102.4-34.133333 122.88-133.12 242.346667-245.76 242.346666z m-235.52-279.893333h6.826667c3.413333 3.413333 10.24 6.826667 10.24 10.24 30.72 129.706667 129.706667 235.52 218.453333 235.52s187.733333-105.813333 218.453333-235.52c0-6.826667 6.826667-10.24 10.24-10.24 3.413333-3.413333 10.24 0 17.066667 0h3.413333c10.24 0 27.306667-27.306667 27.306667-68.266667 0-13.653333-3.413333-30.72-6.826667-40.96v-10.24c0-13.653333 3.413333-40.96 3.413334-61.44C785.066667 150.186667 658.773333 34.133333 508.586667 34.133333 358.4 34.133333 238.933333 150.186667 238.933333 290.133333c0 20.48 3.413333 47.786667 6.826667 64.853334v10.24c-3.413333 10.24-6.826667 23.893333-6.826667 40.96 0 40.96 17.066667 68.266667 27.306667 68.266666h3.413333c0-3.413333 3.413333-3.413333 6.826667-3.413333z" p-id="2887"/><path fill="#bfbfbf" d="M1006.933333 1024H17.066667c-10.24 0-17.066667-6.826667-17.066667-17.066667v-40.96c0-116.053333 75.093333-218.453333 184.32-259.413333l112.64-30.72c6.826667 0 13.653333 0 17.066667 3.413333 51.2 58.026667 122.88 136.533333 197.973333 136.533334s143.36-78.506667 197.973333-136.533334c3.413333-3.413333 10.24-6.826667 17.066667-3.413333l109.226667 30.72c112.64 37.546667 191.146667 150.186667 191.146666 266.24v30.72c-3.413333 13.653333-10.24 20.48-20.48 20.48zM34.133333 989.866667h955.733334v-13.653334c0-98.986667-71.68-201.386667-167.253334-235.52l-98.986666-27.306666c-54.613333 61.44-129.706667 139.946667-215.04 139.946666s-160.426667-78.506667-215.04-139.946666l-98.986667 27.306666c-95.573333 34.133333-160.426667 122.88-160.426667 225.28v23.893334zM785.066667 375.466667h-51.2c-6.826667 0-13.653333-6.826667-17.066667-13.653334 0-3.413333-23.893333-109.226667-30.72-184.32-3.413333-30.72-30.72-58.026667-61.44-58.026666-23.893333 0-40.96 13.653333-58.026667 30.72-17.066667 13.653333-34.133333 20.48-54.613333 20.48-27.306667 0-47.786667 0-64.853333-20.48s-34.133333-30.72-47.786667-30.72c-40.96 0-71.68 30.72-75.093333 68.266666l-17.066667 170.666667c0 3.413333-3.413333 10.24-6.826667 10.24s-6.826667 6.826667-13.653333 6.826667c0 0-23.893333-3.413333-51.2-3.413334-10.24 0-17.066667-6.826667-17.066667-17.066666s10.24-17.066667 20.48-17.066667c13.653333 0 27.306667 0 37.546667 3.413333l17.066667-153.6c3.413333-58.026667 54.613333-102.4 109.226666-102.4 27.306667 0 54.613333 23.893333 71.68 44.373334 6.826667 6.826667 17.066667 6.826667 37.546667 6.826666 10.24 0 20.48-3.413333 30.72-13.653333 20.48-17.066667 47.786667-37.546667 81.92-37.546667 51.2 0 92.16 37.546667 95.573333 88.746667 3.413333 58.026667 20.48 136.533333 27.306667 167.253333H785.066667c10.24 0 17.066667 6.826667 17.066666 17.066667s-6.826667 17.066667-17.066666 17.066667z" p-id="2888"/><path fill="#bfbfbf" d="M324.266667 426.666667c-3.413333 0-10.24 0-13.653334-3.413334l-51.2-51.2c-6.826667-6.826667-6.826667-17.066667 0-23.893333s17.066667-6.826667 23.893334 0l51.2 51.2c6.826667 6.826667 6.826667 17.066667 0 23.893333 0 3.413333-6.826667 3.413333-10.24 3.413334zM699.733333 426.666667c-3.413333 0-6.826667 0-10.24-3.413334-6.826667-6.826667-10.24-17.066667-3.413333-23.893333l34.133333-51.2c6.826667-6.826667 17.066667-10.24 23.893334-3.413333s10.24 17.066667 3.413333 23.893333l-34.133333 51.2c-3.413333 3.413333-6.826667 6.826667-13.653334 6.826667zM563.2 426.666667c-3.413333 0-6.826667 0-10.24-3.413334 0 0-20.48-13.653333-40.96-13.653333s-40.96 13.653333-40.96 13.653333c-6.826667 6.826667-17.066667 3.413333-23.893333-3.413333-6.826667-6.826667-3.413333-17.066667 3.413333-23.893333 0 0 27.306667-20.48 61.44-20.48s61.44 20.48 61.44 20.48c6.826667 6.826667 10.24 17.066667 3.413333 23.893333-3.413333 3.413333-6.826667 6.826667-13.653333 6.826667zM631.466667 614.4c-27.306667 0-51.2-20.48-71.68-37.546667-17.066667-17.066667-34.133333-30.72-54.613334-30.72-17.066667 0-30.72 13.653333-47.786666 30.72-17.066667 17.066667-37.546667 37.546667-68.266667 37.546667-44.373333 0-58.026667-13.653333-81.92-37.546667l-17.066667-17.066666c-6.826667-6.826667-6.826667-17.066667 0-23.893334s17.066667-6.826667 23.893334 0l17.066666 17.066667c23.893333 23.893333 27.306667 27.306667 54.613334 27.306667 13.653333 0 27.306667-13.653333 44.373333-27.306667 20.48-20.48 40.96-40.96 71.68-40.96 30.72 0 54.613333 20.48 75.093333 40.96 17.066667 13.653333 34.133333 27.306667 47.786667 27.306667 30.72 0 34.133333-3.413333 54.613333-27.306667 3.413333-6.826667 10.24-10.24 17.066667-17.066667s17.066667-6.826667 23.893333 0 6.826667 17.066667 0 23.893334c-6.826667 6.826667-10.24 13.653333-17.066666 17.066666-13.653333 23.893333-27.306667 37.546667-71.68 37.546667zM529.066667 648.533333h-34.133334c-10.24 0-17.066667-6.826667-17.066666-17.066666s6.826667-17.066667 17.066666-17.066667h34.133334c10.24 0 17.066667 6.826667 17.066666 17.066667s-6.826667 17.066667-17.066666 17.066666z" p-id="2889"/><path fill="#bfbfbf" d="M631.466667 512c-47.786667 0-85.333333-37.546667-85.333334-85.333333s37.546667-85.333333 85.333334-85.333334 85.333333 37.546667 85.333333 85.333334-37.546667 85.333333-85.333333 85.333333z m0-136.533333c-27.306667 0-51.2 23.893333-51.2 51.2s23.893333 51.2 51.2 51.2 51.2-23.893333 51.2-51.2-23.893333-51.2-51.2-51.2zM392.533333 512C344.746667 512 307.2 474.453333 307.2 426.666667s37.546667-85.333333 85.333333-85.333334 85.333333 37.546667 85.333334 85.333334-37.546667 85.333333-85.333334 85.333333z m0-136.533333c-27.306667 0-51.2 23.893333-51.2 51.2s23.893333 51.2 51.2 51.2 51.2-23.893333 51.2-51.2-23.893333-51.2-51.2-51.2z" p-id="2890"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="1468" t="1546239206365" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M907 378.05l-12.4-14.33c-61-70.41-166.93-177.81-236.2-239.4l-14.12-12.58C609.07 80.37 562.07 63.09 512 63.09s-97.08 17.28-132.32 48.65l-14.12 12.57c-69.28 61.61-175.24 169-236.2 239.41l-12.41 14.33c-63.92 73.87-63.92 194 0 267.87l12.41 14.33C190.24 730.6 296.2 838 365.54 899.69l14.14 12.57c35.24 31.37 82.23 48.65 132.32 48.65s97.06-17.28 132.32-48.65l14.13-12.57 8.15-7.25c21.93-19.46 31.93-28.35 62.69-58.93l7.27-7.36-1.16-1.22a28.35 28.35 0 0 0-45.87-32.14c-2.92 2.78-43.63 41.53-68.73 63.91l-14.1 12.56c-24.89 22.1-58.53 34.28-94.7 34.28s-69.82-12.19-94.69-34.31l-14.14-12.58c-67.85-60.34-171.47-165.38-231-234.14l-12.4-14.32c-21.73-25.12-33.7-59.29-33.7-96.2s12-71.07 33.7-96.17l12.41-14.33c59.5-68.75 163.12-173.79 231-234.15l14.1-12.57c24.86-22.12 58.49-34.31 94.68-34.31s69.83 12.19 94.7 34.3l14.12 12.58c67.86 60.37 171.49 165.41 231 234.14l12.39 14.34c45.22 52.21 45.34 143.76 0.26 192.07l-7.15 7.69c-20.35 21.94-32.64 35.19-45.62 39.1-12.3 3.71-27.89-0.23-57.53-14.54-49.55-23.94-119.64-64-144-78 9.87-19.61 32.46-67.6 43.11-115.62l2.86-12.87H534.5v-15.06h154.78v-57.37H534.5v-72.41h-56.89v72.41H322.83v57.37h154.78v15.05H358.54V491H573c-4.63 14.52-13.16 32.57-19.19 44.37-22.13-8.73-80.75-29.33-141-29.33-37.94 0-69.92 10.28-92.49 29.71-22.37 19.27-34.19 46-34.19 77.42s11.32 58.29 32.75 77.74c21.9 19.89 53 30.41 90 30.41 42.76 0 87.09-19 128.18-54.78a326.76 326.76 0 0 0 43.61-46.35c22.9 12.75 90 50 152.61 83.47 40.83 21.85 69.5 26.18 95.87 14.47 25.09-11.14 47.07-36.53 77.49-71.68l0.47-0.54C971 572.07 971 451.9 907 378.05zM407.83 662c-60.15 0-64.83-37.38-64.83-48.82a48.21 48.21 0 0 1 12.15-31.36c11.06-12.2 28.45-18.39 51.69-18.39 50 0 95 17.21 115.39 26.35C503.71 611.69 456 662 407.83 662z" p-id="1469"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="6244" t="1553935360914" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#8a8a8a" d="M957.217391 86.372174C957.217391 86.372174 957.217391 608.211478 957.217391 608.211478 957.217391 639.510261 949.782261 670.630957 934.956522 701.573565 920.086261 732.605217 900.674783 762.568348 876.633043 791.685565 852.591304 820.758261 825.121391 848.317217 794.267826 874.273391 763.369739 900.274087 732.070957 923.425391 700.326957 943.727304 668.538435 964.073739 637.68487 980.992 607.721739 994.437565 577.758609 1007.88313 551.490783 1017.09913 528.918261 1022.130087 528.918261 1022.130087 518.233043 1024 518.233043 1024 518.233043 1024 508.438261 1022.130087 508.438261 1022.130087 485.286957 1017.09913 458.440348 1007.88313 427.853913 994.437565 397.267478 980.992 365.523478 964.073739 332.577391 943.727304 299.631304 923.425391 267.308522 900.274087 235.52 874.273391 203.776 848.317217 175.415652 820.758261 150.483478 791.685565 125.551304 762.568348 105.382957 732.605217 89.978435 701.573565 74.48487 670.630957 66.782609 639.510261 66.782609 608.211478 66.782609 608.211478 66.782609 86.372174 66.782609 86.372174 66.782609 86.372174 103.290435 80.717913 103.290435 80.717913 103.290435 80.717913 512.890435 0 512.890435 0 512.890435 0 930.504348 80.717913 930.504348 80.717913 930.504348 80.717913 957.217391 86.372174 957.217391 86.372174 957.217391 86.372174 957.217391 86.372174 957.217391 86.372174ZM513.024 75.553391C513.024 75.553391 508.082087 74.529391 508.082087 74.529391 508.082087 74.529391 156.538435 137.527652 156.538435 137.527652 156.538435 137.527652 156.538435 466.765913 156.538435 466.765913 156.538435 466.765913 513.024 466.765913 513.024 466.765913 513.024 466.765913 513.024 75.553391 513.024 75.553391 513.024 75.553391 513.024 75.553391 513.024 75.553391ZM867.461565 466.765913C867.461565 466.765913 513.024 466.765913 513.024 466.765913 513.024 466.765913 513.024 935.401739 513.024 935.401739 535.81913 929.881043 560.617739 921.466435 587.419826 910.113391 614.177391 898.760348 640.623304 885.359304 666.713043 869.865739 692.847304 854.372174 717.957565 837.186783 742.13287 818.265043 766.308174 799.343304 787.634087 778.99687 806.288696 757.314783 824.898783 735.677217 839.724522 713.149217 850.810435 689.730783 861.94087 666.35687 867.461565 642.582261 867.461565 618.496 867.461565 618.496 867.461565 466.765913 867.461565 466.765913 867.461565 466.765913 867.461565 466.765913 867.461565 466.765913Z" p-id="6245"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574649142168" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1910" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M468.693333 16.725333a85.333333 85.333333 0 0 1 82.56 0l381.952 211.072a85.333333 85.333333 0 0 1 44.074667 74.666667v419.029333a85.333333 85.333333 0 0 1-44.074667 74.666667l-381.952 211.114667a85.333333 85.333333 0 0 1-82.56 0l-381.952-211.072A85.333333 85.333333 0 0 1 42.666667 721.493333V302.506667a85.333333 85.333333 0 0 1 44.074666-74.666667L468.693333 16.682667z m423.253334 285.781334l-381.994667-211.072L128 302.506667v418.986666l381.952 211.072 381.994667-211.072V302.506667z m-684.714667 42.197333a42.666667 42.666667 0 0 1 57.984-16.725333l244.736 135.253333 244.778667-135.253333a42.666667 42.666667 0 0 1 41.258666 74.666666l-243.370666 134.528v268.16a42.666667 42.666667 0 0 1-85.333334 0V537.173333L223.914667 402.688a42.666667 42.666667 0 0 1-16.682667-58.026667z" fill="#bfbfbf" p-id="1911"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574649191790" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2774" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M646 1024H100A100 100 0 0 1 0 924V258a100 100 0 0 1 100-100h546a100 100 0 0 1 100 100v31a40 40 0 1 1-80 0v-31a20 20 0 0 0-20-20H100a20 20 0 0 0-20 20v666a20 20 0 0 0 20 20h546a20 20 0 0 0 20-20V713a40 40 0 0 1 80 0v211a100 100 0 0 1-100 100z" fill="#cdcdcd" p-id="2775"></path><path d="M924 866H806a40 40 0 0 1 0-80h118a20 20 0 0 0 20-20V100a20 20 0 0 0-20-20H378a20 20 0 0 0-20 20v8a40 40 0 0 1-80 0v-8A100 100 0 0 1 378 0h546a100 100 0 0 1 100 100v666a100 100 0 0 1-100 100z" fill="#cdcdcd" p-id="2776"></path><path d="M469 887a40 40 0 0 1-27-10L152 618a40 40 0 0 1 1-60l290-248a40 40 0 0 1 66 30v128a367 367 0 0 0 241-128l94-111a40 40 0 0 1 70 35l-26 109a430 430 0 0 1-379 332v142a40 40 0 0 1-40 40zM240 589l189 169v-91a40 40 0 0 1 40-40c144 0 269-85 323-214a447 447 0 0 1-323 137 40 40 0 0 1-40-40v-83z" fill="#cdcdcd" p-id="2777"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="654" t="1545959978831" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M877.297288 553.796942L553.79643 877.298823c-54.370305 54.369282-126.656655 84.311221-203.547883 84.312245-76.890204-0.001023-149.177578-29.942963-203.546859-84.312245S62.389444 750.641145 62.389444 673.750941c0-76.890204 29.942963-149.177578 84.312244-203.547883l135.442762-135.441738c75.829036-75.829036 199.213157-75.829036 275.043217 0s75.830059 199.214181 0 275.043217L399.320173 767.674077c-17.620309 17.620309-46.188972 17.620309-63.809281 0-17.620309-17.621333-17.620309-46.188972 0-63.809281l157.867493-157.867494c40.645722-40.645722 40.645722-106.779955 0-147.424654-40.644699-40.645722-106.778932-40.645722-147.424654 0L210.51097 534.01234c-77.051887 77.05291-77.051887 202.423269 0 279.476179 77.051887 77.051887 202.423269 77.051887 279.475155 0l323.501882-323.501882c77.051887-77.050864 77.051887-202.423269 0-279.475156-77.05291-77.051887-202.424292-77.050864-279.476179 0-17.619286 17.620309-46.188972 17.620309-63.809281 0s-17.619286-46.189995 0-63.809281c54.369282-54.369282 126.657678-84.313268 203.546859-84.312244 76.892251 0 149.178601 29.942963 203.548906 84.312244 54.369282 54.369282 84.311221 126.656655 84.311221 203.547882 0 76.889181-29.942963 149.176554-84.312245 203.54686z" p-id="655"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h36.571V128H0V54.857zM91.429 27.43H128V128H91.429V27.429zM45.714 0h36.572v128H45.714V0z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="6717" t="1547360688278" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M890 120H134a70 70 0 0 0-70 70v500a70 70 0 0 0 70 70h756a70 70 0 0 0 70-70V190a70 70 0 0 0-70-70z m-10 520a40 40 0 0 1-40 40H712V448a40 40 0 0 0-80 0v232h-80V368a40 40 0 0 0-80 0v312h-80V512a40 40 0 0 0-80 0v168H184a40 40 0 0 1-40-40V240a40 40 0 0 1 40-40h656a40 40 0 0 1 40 40zM696 824H328a40 40 0 0 0 0 80h368a40 40 0 0 0 0-80z" p-id="6718"/></svg>
\ No newline at end of file
<svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574649229600" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3752" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M942 191.9C939.8 128.9 748.1 78 512 78S84.2 128.9 82 191.9V831c0 63.5 192.5 115 430 115s430-51.5 430-115V191.9z m-56.7 393.8c-4.6 3.3-11.6 7.4-21.9 12.2-21.3 9.8-50.5 19.1-84.4 26.8-74 16.8-168.8 26-267 26s-193-9.2-267-26c-33.9-7.7-63.1-16.9-84.4-26.8-10.3-4.8-17.3-8.9-21.9-12.2 0.1-0.1 0.2-0.1 0.3-0.2h-7v-123c72.2 36.4 215.3 61.1 380 61.1s307.8-24.8 380-61.1v122.9h-7l0.3 0.3z m0-177c-4.6 3.3-11.6 7.4-21.9 12.2-21.3 9.8-50.5 19.1-84.4 26.8-74 16.8-168.8 26-267 26s-193-9.2-267-26c-33.9-7.7-63.1-16.9-84.4-26.8-10.3-4.8-17.3-8.9-21.9-12.2 0.1-0.1 0.2-0.1 0.3-0.2h-7V246.9c72.2 36.4 215.3 61.1 380 61.1s307.8-24.8 380-61.1v161.6h-7c0.1 0 0.2 0.1 0.3 0.2zM160.7 180.8C182 171 211.2 161.7 245 154c74-16.8 168.8-26 267-26s193 9.2 267 26c33.9 7.7 63.1 16.9 84.4 26.8 10.3 4.8 17.3 8.9 21.9 12.2-4.6 3.3-11.6 7.4-21.9 12.2C842 215 812.8 224.3 779 232c-74 16.8-168.8 26-267 26s-193-9.2-267-26c-33.9-7.7-63.1-16.9-84.4-26.8-10.3-4.8-17.3-8.9-21.9-12.2 4.7-3.3 11.7-7.4 22-12.2zM885.3 831c-4.6 3.3-11.6 7.4-21.9 12.2C842 853 812.8 862.3 779 870c-74 16.8-168.8 26-267 26s-193-9.2-267-26c-33.9-7.7-63.1-16.9-84.4-26.8-10.3-4.8-17.3-8.9-21.9-12.2 0.1-0.1 0.2-0.1 0.3-0.2h-7V639.5c72.2 36.4 215.3 61.1 380 61.1s307.8-24.8 380-61.1v191.3h-7c0.1 0.1 0.2 0.1 0.3 0.2z" fill="#cdcdcd" p-id="3753"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="5330" t="1553935012815" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#8a8a8a" d="M453.22752 781.67168 170.31936 781.67168 170.31936 409.18016l650.45632 0c11.6864 0 21.15968-9.47328 21.15968-21.15968L841.93536 218.68032l0-12.3904c0-11.6864-9.47328-21.15968-21.15968-21.15968l-11.8784 0L660.94464 185.13024l0-35.97184c0-11.6864-9.47328-21.15968-21.15968-21.15968-11.68768 0-21.15968 9.47328-21.15968 21.15968l0 35.97184L356.24704 185.13024l0-35.97184c0-11.6864-9.47328-21.15968-21.15968-21.15968s-21.15968 9.47328-21.15968 21.15968l0 35.97184L161.04064 185.13024l-11.88096 0c-11.6864 0-21.15968 9.47328-21.15968 21.15968l0 12.3904 0 169.34144 0 402.4192c0 18.49984 14.8224 33.55008 33.04064 33.55008l292.18816 0c11.6864 0 21.15968-9.472 21.15968-21.15968C474.38848 791.14496 464.91392 781.67168 453.22752 781.67168zM170.31936 227.4496l143.60832 0 0 35.97184c0 11.6864 9.47328 21.15968 21.15968 21.15968s21.15968-9.472 21.15968-21.15968l0-35.97184 262.37696 0 0 35.97184c0 11.6864 9.472 21.15968 21.15968 21.15968 11.6864 0 21.15968-9.472 21.15968-21.15968l0-35.97184L799.616 227.4496l0 139.41248L170.31936 366.86208 170.31936 227.4496zM690.49984 483.10016c-113.83808 0-206.44992 92.61312-206.44992 206.45248 0 113.83552 92.61184 206.44736 206.44992 206.44736s206.44992-92.61312 206.44992-206.44736C896.94976 575.71328 804.33792 483.10016 690.49984 483.10016zM690.49984 853.68064c-90.50112 0-164.13056-73.62816-164.13056-164.13184s73.62816-164.13184 164.13056-164.13184c90.5024 0 164.13184 73.62816 164.13184 164.13184S781.00224 853.68064 690.49984 853.68064zM390.10304 640.81536l-143.8848 0c-11.68768 0-21.15968 9.472-21.15968 21.15968 0 11.68512 9.472 21.1584 21.15968 21.1584l143.8848 0c11.6864 0 21.15968-9.47328 21.15968-21.1584C411.26144 650.28736 401.78816 640.81536 390.10304 640.81536zM390.10304 521.32608l-143.8848 0c-11.68768 0-21.15968 9.47328-21.15968 21.1584 0 11.68768 9.472 21.15968 21.15968 21.15968l143.8848 0c11.6864 0 21.15968-9.472 21.15968-21.15968C411.26144 530.80064 401.78816 521.32608 390.10304 521.32608zM803.1744 668.39296l-91.51488 0 0-50.78272c0-11.68768-9.472-21.15968-21.1584-21.15968s-21.15968 9.472-21.15968 21.15968l0 71.9424c0 11.68512 9.47328 21.1584 21.15968 21.1584l112.67328 0c11.6864 0 21.15968-9.47328 21.15968-21.1584C824.33536 677.86496 814.8608 668.39296 803.1744 668.39296z" p-id="5331"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574649300337" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4312" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M877.952 447.616v-0.256a272 272 0 0 0-479.68-175.68 166.144 166.144 0 0 0-226.016 155.296c0 4.768 0.32 9.6 0.704 14.144A196.896 196.896 0 0 0 206.592 832H448v-256H304l208-208 208 208H576v256h241.408a196.96 196.96 0 0 0 60.544-384.384z" fill="#cdcdcd" p-id="4313"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="1799" t="1553478255619" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M329.285097 317.714062l-8.422833 4.428869c-8.78099 4.584412-13.528108 14.84715-11.923564 24.415063 1.644453 4.909823 3.491521 9.864672 5.492084 14.747889 2.030239 4.854565 4.230348 9.652847 6.53688 14.293541 5.621021 7.891737 16.246009 11.824303 25.699312 8.858762l9.041934-2.868327c14.741749-3.860934 31.115672-0.056282 42.62582 11.512195 11.549034 11.526521 15.374152 27.863604 11.549034 42.570561l-2.882654 9.126868c-2.958378 9.438976 0.938372 20.042475 8.830109 25.706475 4.634554 2.328022 9.403161 4.52813 14.323217 6.529717 4.876054 2.043542 9.80839 3.846608 14.739702 5.478781 9.538237 1.603521 19.87363-3.123131 24.414039-11.910261l4.402263-8.388041c7.67889-13.144368 21.915126-22.002107 38.267559-22.002107 16.338107 0 30.547737 8.829086 38.255279 21.931498l4.41352 8.459672c4.584412 8.78713 14.84715 13.513782 24.414039 11.910261 4.91187-1.632173 9.851369-3.462868 14.734586-5.478781 4.882194-2.030239 9.66615-4.201695 14.322194-6.529717 7.891737-5.622044 11.809977-16.253172 8.843412-25.706475l-2.852978-9.041934c-3.859911-14.733563-0.069585-31.085996 11.484565-42.655496 11.55415-11.525498 27.878954-15.372106 42.599214-11.512195l9.097192 2.88163c9.426697 2.952238 20.044522-0.937348 25.693172-8.829086 2.313695-4.656043 4.527107-9.411347 6.54302-14.322194 2.029216-4.883217 3.847631-9.80839 5.495154-14.748912 1.616824-9.581216-3.108804-19.843954-11.911284-24.429389l-8.402367-4.400217c-13.132088-7.665587-21.98778-21.901823-21.98778-38.255279 0-16.32378 8.830109-30.589692 21.974477-38.268582l8.416693-4.443196c8.80248-4.571109 13.528108-14.832823 11.924587-24.400736-1.6465-4.910846-3.479241-9.850345-5.493108-14.733563-2.031263-4.868891-4.202719-9.680477-6.529717-14.308891-5.622044-7.890714-16.253172-11.82328-25.708522-8.842389l-9.05626 2.852978c-14.747889 3.861958-31.071669 0.057305-42.654472-11.512195-11.55415-11.55415-15.344476-27.877931-11.484565-42.612517l2.852978-9.05626c2.966565-9.44-0.951675-20.043499-8.856715-25.692149-4.641717-2.328022-9.397021-4.542456-14.307867-6.544043-4.883217-2.029216-9.82374-3.846608-14.734586-5.465478-9.567913-1.632173-19.872606 3.123131-24.414039 11.895935l-4.400217 8.389064c-7.67889 13.174044-21.931498 22.002107-38.268582 22.002107-16.309454 0-30.576389-8.828063-38.267559-22.002107l-4.387937-8.389064c-4.554736-8.771781-14.8318-13.528108-24.405853-11.895935-4.954849 1.604544-9.873882 3.435239-14.763239 5.4225-4.883217 2.044566-9.688663 4.217045-14.323217 6.545066-7.891737 5.649674-11.808954 16.266475-8.830109 25.735128l2.826372 9.05626c3.882424 14.762215 0.057305 31.085996-11.491729 42.612517-11.510148 11.5695-27.849278 15.373129-42.611493 11.526521l-9.070586-2.867304c-9.44-2.980891-20.063965 0.951675-25.686009 8.842389-2.342348 4.628414-4.52813 9.44-6.53688 14.308891-2.036379 4.882194-3.847631 9.822716-5.492084 14.733563-1.603521 9.581216 3.142573 19.85828 11.923564 24.443715l8.402367 4.400217c13.156648 7.67889 21.986757 21.944801 21.986757 38.268582C351.251388 295.79689 342.421278 310.019823 329.285097 317.714062zM511.977999 171.706687c59.532885 0 107.795075 48.275493 107.795075 107.779725 0 59.490929-48.26219 107.752096-107.795075 107.752096-59.533908 0-107.752096-48.26219-107.752096-107.752096C404.226926 219.98218 452.445114 171.706687 511.977999 171.706687z" p-id="1800"/><path fill="#bfbfbf" d="M924.647713 689.174212 798.570249 689.174212 798.570249 581.650313c0-26.387997-21.476127-47.850821-47.864124-47.850821L276.2543 533.799492c-26.386974 0-47.851844 21.462824-47.851844 47.850821l0 107.523899L99.345124 689.174212c-20.419052 0-36.95568 16.550954-36.95568 36.948517l0 184.771237c0 20.399609 16.536628 36.962843 36.95568 36.962843l273.965675 0c20.397562 0 36.947494-16.564257 36.947494-36.962843L410.258293 726.122729c0-20.398586-16.550954-36.948517-36.947494-36.948517l-123.103736 0L250.207064 581.650313c0-14.366196 11.68104-26.047236 26.047236-26.047236l474.451826 0c14.364149 0 26.062586 11.68104 26.062586 26.047236l0 107.523899L650.689201 689.174212c-20.412912 0-36.962843 16.550954-36.962843 36.948517l0 184.771237c0 20.399609 16.549931 36.962843 36.962843 36.962843l273.958512 0c20.397562 0 36.96182-16.564257 36.96182-36.962843L961.609533 726.122729C961.609533 705.725166 945.044252 689.174212 924.647713 689.174212z" p-id="1801"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1546567861908" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2422" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M318.577778 819.2L17.066667 512l301.511111-307.2 45.511111 45.511111L96.711111 512l267.377778 261.688889zM705.422222 819.2l-45.511111-45.511111L927.288889 512l-267.377778-261.688889 45.511111-45.511111L1006.933333 512zM540.785778 221.866667l55.751111 11.150222L483.157333 802.133333l-55.751111-11.093333z" fill="#bfbfbf" p-id="2423"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="2807" t="1547195013953" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#cdcdcd" d="M529.0496 527.616l-30.7712-30.7456 85.0688-85.0944 30.7712 30.7712z" p-id="2808"/><path fill="#cdcdcd" d="M0 340.48l427.52 256 248.32 427.52L1024 0l-1024 340.48zM665.6 921.6l-207.36-355.84-355.84-212.48L911.36 81.92l-243.2 243.2 30.72 30.72 243.2-243.2L665.6 921.6z" p-id="2809"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="1497" t="1554868028575" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M558.409143 658.285714h-92.818286l-28.379428 62.427429a18.285714 18.285714 0 1 1-33.28-15.140572l91.428571-201.142857a18.285714 18.285714 0 0 1 33.28 0l91.428571 201.142857a18.285714 18.285714 0 1 1-33.28 15.140572L558.409143 658.285714z m-16.64-36.571428L512 556.178286 482.230857 621.714286h59.538286zM329.142857 128h475.428572a18.285714 18.285714 0 1 1 0 36.571429H329.142857a91.428571 91.428571 0 0 0 0 182.857142h475.428572a18.285714 18.285714 0 0 1 18.285714 18.285715v512a18.285714 18.285714 0 0 1-18.285714 18.285714H329.142857A128 128 0 0 1 201.142857 768V256A128 128 0 0 1 329.142857 128zM237.714286 345.6V768A91.428571 91.428571 0 0 0 329.142857 859.428571h457.142857v-475.428571H329.142857a127.634286 127.634286 0 0 1-91.428571-38.4zM329.142857 274.285714a18.285714 18.285714 0 0 1 0-36.571428h438.857143a18.285714 18.285714 0 1 1 0 36.571428H329.142857z" p-id="1498"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1583752001956" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9290" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M891.8 320H608V39.2L891.8 320zM704 384v260c0 133.6-73 200.2-226.6 200.2H288V169.6h189.4c24 0 46.2 1.6 66.2 5v-168C521.8 2.2 498.8 0 474.4 0H96v1024h378.4C755.4 1024 896 894.8 896 636.2V384h-192z" fill="#707070" p-id="9291"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1583752303941" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16654" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1024 896v128H0v-320h128v192h768v-192h128v192zM576 554.688L810.688 320 896 405.312l-384 384-384-384L213.312 320 448 554.688V0h128v554.688z" fill="#707070" p-id="16655"></path></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M106.133 67.2a4.797 4.797 0 0 0-4.8 4.8c0 .187.014.36.027.533h-.027V118.4H9.6V26.667h50.133c2.654 0 4.8-2.147 4.8-4.8 0-2.654-2.146-4.8-4.8-4.8H9.6a9.594 9.594 0 0 0-9.6 9.6V118.4c0 5.307 4.293 9.6 9.6 9.6h91.733c5.307 0 9.6-4.293 9.6-9.6V72.533h-.026c.013-.173.026-.346.026-.533 0-2.653-2.146-4.8-4.8-4.8z"/><path d="M125.16 13.373L114.587 2.8c-3.747-3.747-9.854-3.72-13.6.027l-52.96 52.96a4.264 4.264 0 0 0-.907 1.36L33.813 88.533c-.746 1.76-.226 3.534.907 4.68 1.133 1.147 2.92 1.667 4.693.92l31.4-13.293c.507-.213.96-.52 1.36-.907l52.96-52.96c3.747-3.746 3.774-9.853.027-13.6zM66.107 72.4l-18.32 7.76 7.76-18.32L92.72 24.667l10.56 10.56L66.107 72.4zm52.226-52.227l-8.266 8.267-10.56-10.56 8.266-8.267.027-.026 10.56 10.56-.027.026z"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M88.883 119.565c-7.284 0-19.434 2.495-21.333 8.25v.127c-4.232.13-5.222 0-7.108 0-1.895-5.76-14.045-8.256-21.333-8.256H0V0h42.523c9.179 0 17.109 5.47 21.47 13.551C68.352 5.475 76.295 0 85.478 0H128v119.57l-39.113-.005h-.004zM60.442 24.763c0-9.651-8.978-16.507-17.777-16.507H7.108V111.43H39.11c7.054-.14 18.177.082 21.333 6.12v-4.628c-.134-5.722-.004-13.522 0-13.832V27.413l.004-2.655-.004.005zm60.442-16.517h-35.55c-8.802 0-17.78 6.856-17.78 16.493v74.259c.004.32.138 8.115 0 13.813v4.627c3.155-6.022 14.279-6.26 21.333-6.114h32V8.25l-.003-.005z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="2851" t="1554009929581" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#8a8a8a" d="M511.471952 957.559056c-51.013955 0-93.475781-37.318473-101.502932-86.07185l-199.795618 0c-32.961053 0-59.794291-26.834261-59.794291-59.827038 0-12.417319 3.735224-24.277935 10.811684-34.336434l83.646513-111.561431 533.235518 0 83.515524 111.364948c7.306713 10.484212 11.008167 22.246587 11.008167 34.532917 0 32.9938-26.833238 59.827038-59.794291 59.827038l-199.861112 0C604.914986 920.241606 562.485907 957.559056 511.471952 957.559056zM261.61307 699.312805l-73.293289 97.734961c-2.751786 3.964455-4.390168 9.174325-4.390168 14.612403 0 14.481414 11.762375 26.276536 26.243789 26.276536l231.969715 0 0 16.774739c0 38.202647 31.093441 69.296088 69.328835 69.296088 38.202647 0 69.296088-31.093441 69.296088-69.296088l0-16.774739 232.03521 0c14.481414 0 26.243789-11.795122 26.243789-26.276536 0-5.373606-1.605635-10.516959-4.652145-14.875403l-73.096806-97.472983L261.61307 699.311782zM786.461219 613.240955l-550.011281 0 0-188.951187c0-112.348386 68.673891-213.392858 172.142677-255.101499l0-3.113028c0-56.715033 46.164304-102.879337 102.879337-102.879337 56.715033 0 102.84659 46.164304 102.84659 102.879337l0 3.113028c103.468786 41.708641 172.142677 142.753113 172.142677 255.101499L786.461219 613.240955zM270.00044 579.690453l482.910277 0 0-155.400685c0-102.158899-64.67669-193.668827-160.969751-227.677789l-11.172926-3.964455 0-26.571261c0-38.235394-31.093441-69.328835-69.296088-69.328835-38.235394 0-69.328835 31.093441-69.328835 69.328835l0 26.571261-11.172926 3.964455c-96.294085 34.008962-160.969751 125.51889-160.969751 227.677789L270.00044 579.690453z" p-id="2852"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="5914" t="1547360570987" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M234.27218 32h58.36780969v179.99999344h-58.36874719V32zM583.99997844 32h58.27218562v179.99999344H583.99997844V32zM175.99999437 331.99998875h524.59216688v59.99999719H175.99999437v-59.99999719z m0 179.9999925h291.40780125v59.99999812H175.99999437v-59.99999812z m352.55998594 383.999985H32V79.99999812h767.99997v381.6477975C911.16871531 492.99216969 991.9999625 597.1043525 991.9999625 721.99997281c0 149.99999437-116.59218281 269.99998969-262.27217719 269.99998969a258.38436469 258.38436469 0 0 1-201.1199925-95.99999625z m212.35217906-443.75998312V138.31999625H91.08781062v699.35997188H492.36873219A277.72780125 277.72780125 0 0 1 467.40779562 721.99997281c0-149.99999437 116.59218281-269.99998969 262.31998969-269.99998875 3.744375 0 7.4878125 0.095625 11.18437407 0.23999906zM175.99999437 691.99997469h233.13561563v59.99999719H175.99999437v-59.99999719z m553.72779094-179.99999344c-110.73562031 0-203.9999925 95.99999625-203.9999925 209.99999156s93.26437125 209.99999156 203.9999925 209.9999925 203.9999925-95.99999625 203.99999156-209.9999925-93.26343375-209.99999156-203.99999156-209.99999156zM703.99997375 559.99997938h59.75999812v203.99999249H703.99997375V559.99997938z m59.75999812 239.99999062v59.75999812H703.99997375V799.99997h59.75999812z" p-id="5915"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="2201" t="1545883026424" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M925.597853 836.903811c0.367367-2.783393 0.847298-5.528923 0.847298-8.40953L926.44515 180.091658c19.034519-11.079336 31.976272-31.470759 31.976272-55.082526 0-35.32146-28.633131-63.956637-63.953567-63.956637-23.611767 0-44.007283 12.941753-55.082526 31.980365L182.108594 93.03286c-11.076266-19.038612-31.470759-31.980365-55.082526-31.980365-35.31839 0-63.953567 28.635177-63.953567 63.956637 0 23.611767 12.9438 44.00319 31.976272 55.082526l0 648.402623c0 2.880607 0.479931 5.627161 0.851391 8.40953-19.4991 10.954493-32.827663 31.586392-32.827663 55.543014 0 35.317367 28.635177 63.953567 63.953567 63.953567 35.32146 0 63.953567-28.635177 63.953567-63.953567l639.536698 0c0 35.317367 28.631084 63.953567 63.953567 63.953567 35.319413 0 63.953567-28.635177 63.953567-63.953567C958.421422 868.490204 945.093882 847.859327 925.597853 836.903811zM862.491583 828.494281 159.00234 828.494281 159.00234 180.091658c9.596566-5.586229 17.524119-13.513782 23.110347-23.110347l657.273664 0c5.582135 9.596566 13.509688 17.524119 23.106254 23.110347L862.492606 828.494281z" p-id="2202"/><path d="M670.62781 252.915243 350.86202 252.915243 318.885747 252.915243 286.908452 252.915243 286.908452 380.818285 350.86202 380.818285 350.86202 316.864718 478.768131 316.864718 478.768131 668.610874 414.815587 668.610874 414.815587 732.564441 606.675266 732.564441 606.675266 668.610874 542.721699 668.610874 542.721699 316.864718 670.62781 316.864718 670.62781 380.818285 734.585471 380.818285 734.585471 252.915243 702.609199 252.915243Z" p-id="2203"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1583751668311" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2803" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M263.456 759.36c0 27.04 22.88 40.576 68.672 40.576 40.064 0 60.096-14.048 60.096-42.144 0-26.528-21.856-39.808-65.536-39.808C284.544 718.016 263.456 731.808 263.456 759.36zM853.344 0 170.688 0C76.8 0 0 76.8 0 170.688l0 682.624C0 947.264 76.8 1024 170.688 1024l682.656 0C947.232 1024 1024 947.264 1024 853.312L1024 170.688C1024 76.8 947.232 0 853.344 0zM475.744 408.992c-7.296 2.592-17.696 5.472-31.2 8.576 4.16 11.968 6.24 23.168 6.24 33.568 0 33.28-10.016 62.304-30.048 87.008-20.032 24.704-45.92 39.392-77.632 44.096-20.8 3.136-31.2 14.304-31.2 33.568 0 6.752 3.392 13.536 10.144 20.288 8.832 9.888 21.856 16.128 39.008 18.72 74.4 11.456 111.584 42.4 111.584 92.864 0 80.64-48.128 120.96-144.352 120.96-39.552 0-72.064-7.04-97.536-21.056-32.256-17.696-48.384-45.536-48.384-83.488 0-43.712 24.192-73.6 72.576-89.728l0-1.568c-17.696-10.912-26.528-27.584-26.528-49.952 0-29.12 8.32-47.36 24.96-54.624l0-1.568c-16.64-5.728-31.488-18.72-44.48-39.04-14.56-21.856-21.856-45.248-21.856-70.24 0-37.472 13.28-68.672 39.808-93.632 25.504-23.424 55.936-35.104 91.296-35.104 25.504 0 49.152 6.24 71.008 18.72 24.96 0 53.856-6.24 86.624-18.72L475.744 408.992 475.744 408.992zM602.176 679.008l-88.192 0c1.056-10.4 1.568-28.096 1.568-53.056L515.552 383.232c0-24.448-0.512-41.376-1.568-50.72l88.192 0c-1.056 9.888-1.568 26.272-1.568 49.152l0 239.552C600.608 647.776 601.152 667.04 602.176 679.008zM596.32 254.496c-10.656 11.456-23.296 17.152-37.856 17.152-15.072 0-27.968-5.728-38.624-17.152-10.656-11.456-16-24.96-16-40.576 0-16.128 5.344-29.92 16-41.376 10.656-11.456 23.552-17.152 38.624-17.152 14.56 0 27.2 5.728 37.856 17.152 10.656 11.456 16 25.216 16 41.376C612.32 229.504 606.976 243.04 596.32 254.496zM841.696 668.832c-19.264 10.4-42.4 15.616-69.472 15.616-37.984 0-64.256-13.504-78.816-40.576-10.944-20.288-16.384-52.288-16.384-95.968l0-139.68 0.768 0 0-1.568-11.712-0.768c-6.752 0-15.616 0.768-26.528 2.336L639.584 332.512l38.24 0 0-30.432c0-14.56-0.768-26.272-2.336-35.104l90.528 0c-1.536 9.888-2.336 21.056-2.336 33.536l0 32 67.872 0 0 75.68c-2.592 0-7.424-0.256-14.432-0.768-7.04-0.512-13.664-0.8-19.904-0.8l-33.568 0 0 145.152c0 34.848 11.456 52.288 34.336 52.288 16.128 0 30.688-4.416 43.712-13.248L841.696 668.832 841.696 668.832zM321.216 400.416c-32.768 0-49.152 19.264-49.152 57.76 0 35.904 16.384 53.856 49.152 53.856 31.744 0 47.616-18.208 47.616-54.624 0-15.104-3.648-28.096-10.912-39.008C349.056 406.4 336.832 400.416 321.216 400.416z" p-id="2804"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="1258" t="1554279845314" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M921.9 468.6H749.6c-9.4 0-18.4 3.8-25 10.5-6.6 6.7-10.3 15.7-10.3 25.1v11.1c0 19.6 15.9 35.5 35.4 35.5h172.2c19.5 0 35.3-15.9 35.3-35.5v-11.1c0-9.4-3.7-18.4-10.3-25.1-6.6-6.7-15.6-10.5-25-10.5zM522.4 163.9c-53.6 42.6-165.7 102.3-246.3 159.8h-0.1c-0.9 0.6-1.8 3.8-2.8 4.3-9.5 5.4-13.8 20.1-65.6 20.1h-101c-26 0-42 12.2-42 39.6V631c0 27.4 14.7 40.9 42 40.9H208c51.5 0.1 55.7 14.8 65.2 20.1 0.9 0.5 1.8 3.7 2.7 4.3h0.1c78.2 57.5 191 121.8 246.4 162.7 16.7 12.3 72.1 33.9 72.1-42.1v-614c0-76.1-55.9-51.8-72.1-39z m159 167.8c9.2 16.1 27.3 20.2 40.5 9l141.5-119.3c13.3-11.1 16.5-33.2 7.4-49.4l-5.2-9.1c-9.1-16.1-27.3-20.1-40.5-9L683.6 273.2c-13.2 11.2-16.5 33.2-7.4 49.4l5.2 9.1z m40.4 347.4c-13.2-11.1-31.3-7-40.4 9l-5.2 9.1c-9.1 16.1-5.8 38.2 7.4 49.4L825.1 866c13.2 11.1 31.3 7.1 40.4-9l5.2-9.1c9.1-16.1 5.8-38.2-7.4-49.4L721.8 679.1z m0 0" p-id="1259"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="3572" t="1545136555590" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M403.2 780.8V619.2h-160c-89.6 0-161.6 72-161.6 161.6s72 161.6 161.6 161.6 160-72 160-161.6z m81.6 0c0 134.4-108.8 243.2-243.2 243.2S0 915.2 0 780.8s108.8-243.2 243.2-243.2h243.2c-1.6 0-1.6 243.2-1.6 243.2z m134.4 0V619.2h161.6c89.6 0 161.6 72 161.6 161.6s-72 161.6-161.6 161.6-161.6-72-161.6-161.6z m-81.6 0c0 134.4 108.8 243.2 243.2 243.2S1024 915.2 1024 780.8s-108.8-243.2-243.2-243.2H537.6v243.2z m-134.4-537.6v161.6h-160c-89.6 0-161.6-72-161.6-161.6S153.6 81.6 243.2 81.6s160 72 160 161.6z m81.6 0C484.8 108.8 376 0 243.2 0 108.8 1.6 0 108.8 0 243.2s108.8 243.2 243.2 243.2h243.2c-1.6 0-1.6-243.2-1.6-243.2z m134.4 0v161.6h161.6c89.6 0 161.6-72 161.6-161.6S870.4 81.6 780.8 81.6 619.2 153.6 619.2 243.2z m-81.6 0C537.6 108.8 646.4 0 780.8 0c134.4 1.6 241.6 108.8 241.6 243.2s-108.8 243.2-243.2 243.2H537.6v-81.6-161.6z" p-id="3573"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="1303" t="1545960873089" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#4A576A" d="M784 112H240C152 112 80 184 80 272v480c0 88 72 160 160 160h544c88 0 160-72 160-160V272c0-88-72-160-160-160z m96 640c0 52.8-43.2 96-96 96H240c-52.8 0-96-43.2-96-96V272c0-52.8 43.2-96 96-96h544c52.8 0 96 43.2 96 96v480z" p-id="1304"/><path fill="#4A576A" d="M352 480c52.8 0 96-43.2 96-96s-43.2-96-96-96-96 43.2-96 96 43.2 96 96 96z m0-128c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM814.4 731.2l-3.2-3.2-177.6-177.6c-25.6-25.6-65.6-25.6-91.2 0l-80 80-36.8-36.8c-25.6-25.6-65.6-25.6-91.2 0l-134.4 134.4c-4.8 6.4-8 14.4-8 24 0 17.6 14.4 32 32 32 9.6 0 16-3.2 22.4-9.6l134.4-134.4 134.4 134.4c6.4 6.4 14.4 9.6 24 9.6 17.6 0 32-14.4 32-32 0-9.6-4.8-17.6-9.6-24l-52.8-52.8 80-80 180.8 180.8c6.4 4.8 12.8 8 20.8 8 17.6 0 32-14.4 32-32 0-8-3.2-16-8-20.8z" p-id="1305"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1572170050760" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5149" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400"><defs><style type="text/css"></style></defs><path d="M219.428571 658.285714q0-30.285714-21.428571-51.714285T146.285714 585.142857t-51.714285 21.428572T73.142857 658.285714t21.428572 51.714286T146.285714 731.428571t51.714286-21.428571T219.428571 658.285714z m109.714286-256q0-30.285714-21.428571-51.714285T256 329.142857t-51.714286 21.428572T182.857143 402.285714t21.428571 51.714286T256 475.428571t51.714286-21.428571T329.142857 402.285714z m244.571429 274.857143l57.714285-218.285714q3.428571-14.857143-4.285714-27.714286T605.142857 414.285714t-27.428571 3.714286-17.142857 22.571429l-57.714286 218.285714q-34.285714 2.857143-61.142857 24.857143t-36 56.285714q-11.428571 44 11.428571 83.428571t66.857143 50.857143 83.428571-11.428571 50.857143-66.857143q9.142857-34.285714-3.428571-66.857143t-41.142857-52z m377.142857-18.857143q0-30.285714-21.428572-51.714285T877.714286 585.142857t-51.714286 21.428572-21.428571 51.714285 21.428571 51.714286 51.714286 21.428571 51.714285-21.428571 21.428572-51.714286z m-365.714286-365.714285q0-30.285714-21.428571-51.714286T512 219.428571t-51.714286 21.428572T438.857143 292.571429t21.428571 51.714285T512 365.714286t51.714286-21.428572T585.142857 292.571429z m256 109.714285q0-30.285714-21.428571-51.714285T768 329.142857t-51.714286 21.428572T694.857143 402.285714t21.428571 51.714286T768 475.428571t51.714286-21.428571T841.142857 402.285714z m182.857143 256q0 149.142857-80.571429 276-10.857143 16.571429-30.857142 16.571429H111.428571q-20 0-30.857142-16.571429Q0 808 0 658.285714q0-104 40.571429-198.857143t109.142857-163.428571 163.428571-109.142857 198.857143-40.571429 198.857143 40.571429 163.428571 109.142857 109.142857 163.428571 40.571429 198.857143z" p-id="5150" fill="#bfbfbf"></path></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M83.287 103.01c-1.57-3.84-6.778-10.414-15.447-19.548-2.327-2.444-2.182-4.306-1.338-9.862v-.64c.553-3.81 1.513-6.05 14.313-8.087 6.516-1.018 8.203 1.57 10.589 5.178l.785 1.193a12.625 12.625 0 0 0 6.43 5.207c1.134.524 2.53 1.164 4.421 2.24 4.596 2.53 4.596 5.41 4.596 11.753v.727a26.91 26.91 0 0 1-5.178 17.454 59.055 59.055 0 0 1-19.025 11.026c3.49-6.546.814-14.313 0-16.553l-.146-.087zM64 5.12a58.502 58.502 0 0 1 25.484 5.818 54.313 54.313 0 0 0-12.859 10.327c-.93 1.28-1.716 2.473-2.472 3.579-2.444 3.694-3.637 5.352-5.818 5.614a25.105 25.105 0 0 1-4.219 0c-4.276-.29-10.094-.64-11.956 4.422-1.193 3.23-1.396 11.956 2.444 16.495.66 1.077.778 2.4.32 3.578a7.01 7.01 0 0 1-2.066 3.229 18.938 18.938 0 0 1-2.909-2.91 18.91 18.91 0 0 0-8.32-6.603c-1.25-.349-2.647-.64-3.985-.93-3.782-.786-8.03-1.688-9.019-3.812a14.895 14.895 0 0 1-.727-5.818 21.935 21.935 0 0 0-1.396-9.25 8.873 8.873 0 0 0-5.557-4.946A58.705 58.705 0 0 1 64 5.12zM0 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="5670" t="1544682877339" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M449.98144 243.90144c-57.7536-10.624-121.00096-7.98208-167.65952 6.8352C195.92192 278.19008 146.95936 329.984 119.76192 406.528c-32.22528 90.69568-2.93376 190.62784 15.81056 248.63744 18.74432 58.0096 76.0576 144.97792 135.94112 155.8528 63.7696 11.58144 121.30816-9.89696 155.37664-50.7392 16.05632-19.24608 30.27456-46.75072 31.70816-74.46016 0.93184-18.0224-1.22368-31.64672-6.1696-45.14816-5.64224-15.40096-15.06816-29.6448-32.95232-46.57664-19.18976-18.17088-62.53056-34.09408-104.28416-28.29312-30.90432 4.29056-56.55552 15.67744-78.4384 32.47616-33.5872 25.78944-65.41312 82.65728-65.41312 82.65728s-1.152-33.25952 13.27104-66.69824c7.22944-16.75264 24.3968-44.8512 41.26208-58.99776 17.12128-14.36672 37.85728-31.5392 72.1664-40.32 38.8864-9.95328 78.27456-6.97856 93.62944-3.5584 46.39744 10.32192 82.24256 34.64704 111.616 65.32096 59.52512 62.16704 82.46784 161.536 51.75296 246.03648-10.28096 28.28288-38.85056 61.06112-69.30944 85.10976-18.32448 14.464-57.00096 35.4048-103.18848 45.14304-30.592 6.4512-64.48128 6.2976-97.93536 2.2272-83.95776-10.22464-159.50336-86.53312-195.11296-147.77856-35.61472-61.24544-89.0368-186.05568-75.80672-320.60928 6.30272-64.12288 28.08832-132.46976 62.88384-182.4768C114.77504 249.3952 167.1168 215.15264 194.80576 199.13216c52.89984-30.60736 132.29056-43.6224 185.19552-40.832 33.62816 1.77664 86.85568 12.66688 137.27232 38.08768 39.66464 20.00384 75.78112 55.2448 92.17536 95.37536 9.81504 24.02304 6.71232 47.49312 6.67136 47.49312-0.04608 0.11776 1.13664-2.54464-31.44192-34.05312C557.16352 278.59456 507.72992 254.53056 449.98144 243.90144L449.98144 243.90144z" p-id="5671"/><path d="M559.07328 155.18208c0 0 37.8624-68.5056 72.36096-88.50944 34.49856-20.00384 61.65504-7.67488 79.4624 5.92896 17.81248 13.60384 26.82368 30.91456 22.912 55.552-3.91168 24.63744-43.14624 71.76192-66.3296 106.22976C631.34208 207.98464 595.21024 181.58592 559.07328 155.18208L559.07328 155.18208z" p-id="5672"/><path d="M408.26368 117.03296c0 0 6.8096-62.65344 26.31168-88.04864 19.50208-25.3952 43.65824-24.41216 61.23008-19.64544 17.57184 4.76672 29.73184 14.97088 34.53952 34.56 4.80256 19.59424-9.73312 66.688-16.24576 99.46112C478.81728 134.58944 443.54048 125.80864 408.26368 117.03296L408.26368 117.03296z" p-id="5673"/><path d="M294.76352 125.06112c0 0-11.65824-45.60896-4.6592-68.34176 7.00416-22.72768 24.17664-28.16 37.7344-29.27104 13.55776-1.11104 24.7552 2.94912 33.2544 15.45728 8.4992 12.50304 10.66496 49.17248 14.69952 73.78432C348.78464 119.48032 321.77152 122.27072 294.76352 125.06112L294.76352 125.06112z" p-id="5674"/><path d="M185.1648 163.1232c0 0-20.89984-34.67264-20.79232-55.01952 0.10752-20.352 12.86656-28.93312 23.7312-33.1008 10.85952-4.16768 21.06368-3.51744 31.1552 4.72064 10.09152 8.23296 20.97152 37.8368 30.39744 57.08288C228.15744 145.57696 206.66368 154.35264 185.1648 163.1232L185.1648 163.1232z" p-id="5675"/><path d="M97.408 227.1488c0 0-26.7776-25.18528-31.72352-42.9312-4.9408-17.74592 4.0448-28.26752 12.47232-34.49344 8.4224-6.22592 17.46944-8.09472 28.29312-3.34336 10.81856 4.75648 27.6224 27.9296 40.59136 42.42944C130.49856 201.58976 113.95584 214.36928 97.408 227.1488L97.408 227.1488z" p-id="5676"/><path d="M762.08128 537.68704c38.15424 4.096 77.2864 17.52064 103.7568 35.49696 49.01376 33.28 70.04672 74.84416 72.832 127.85664 3.3024 62.81216-33.65376 119.96672-56.192 152.81664-22.53824 32.84992-74.63424 76.66176-114.17088 72.33024-42.10176-4.61824-74.15296-28.78464-87.88992-60.71296-6.4768-15.04768-10.2656-34.92864-6.00576-52.55168 2.76992-11.46368 6.656-19.59936 12.27264-27.136 6.40512-8.59648 14.96064-15.76448 29.312-23.04512 15.40608-7.81312 45.52192-9.71776 70.59456 1.6896 18.56 8.44288 32.512 20.352 43.08992 34.94912 16.24064 22.41024 25.59488 63.95904 25.59488 63.95904s6.91712-20.61824 4.10112-44.25216c-1.408-11.83744-6.93248-32.64-14.86336-44.64128-8.05376-12.1856-17.8432-26.80832-37.70368-38.69696-22.50752-13.47072-47.73376-18.944-57.98912-19.6608-30.98624-2.17088-57.97376 6.39488-82.07872 20.14208-48.86016 27.86304-81.73056 85.84192-78.22336 144.49664 1.17248 19.63008 12.96896 45.48608 27.57632 66.21696 8.78592 12.47232 29.11744 32.78848 56.23808 47.49312 17.96608 9.73824 39.22432 15.9488 60.93824 19.62496 54.49728 9.22624 116.02944-24.51456 149.74464-56.25344 33.71008-31.73888 90.41408-99.98336 107.17696-186.73664 7.9872-41.33888 7.06048-88.2176-5.42208-126.02368-13.71136-41.5232-40.12544-72.71424-54.49216-87.90528-27.4432-29.02016-74.752-51.95776-108.416-60.0576-21.39136-5.1456-56.77056-8.23296-93.08672-1.69472-28.57472 5.14048-57.75872 20.50048-75.49952 42.58816-10.61888 13.22496-13.04576 28.50304-13.04576 28.50304s-0.21504-1.79712 26.06592-15.47264C688.47616 539.46368 723.92192 533.59104 762.08128 537.68704L762.08128 537.68704z" p-id="5677"/><path d="M710.25664 461.7984c0 0-10.96704-49.96608-28.85632-68.92032-17.88416-18.94912-37.19168-16.2816-50.88256-11.07968-13.69088 5.20704-22.55872 14.37184-24.69376 30.53568-2.13504 16.16384 13.66528 52.98688 21.77536 78.8992C655.15008 481.42336 682.70592 471.60832 710.25664 461.7984L710.25664 461.7984z" p-id="5678"/><path d="M811.83232 465.97632c0 0 7.3984-40.51456-0.09216-60.0576-7.49056-19.54304-22.80448-23.424-34.70336-23.71072-11.89888-0.28672-21.41696 3.84512-28.07296 15.22176-6.656 11.37664-6.31808 43.58656-8.34048 65.3312C764.3648 463.83616 788.10112 464.90624 811.83232 465.97632L811.83232 465.97632z" p-id="5679"/><path d="M881.43872 492.1344c0 0 15.7952-26.40384 15.6416-41.94304-0.1536-15.54432-9.9072-22.144-18.19136-25.36448-8.28928-3.22048-16.05632-2.75968-23.71072 3.49184-7.64928 6.25152-15.83616 28.82048-22.94272 43.48416C848.64 478.58176 865.03936 485.35552 881.43872 492.1344L881.43872 492.1344z" p-id="5680"/><path d="M943.01184 536.38144c0 0 19.54816-17.82784 23.2704-30.59712 3.72224-12.76928-2.67264-20.52096-8.704-25.15456-6.03136-4.6336-12.53888-6.12352-20.39296-2.8416-7.85408 3.2768-20.18304 19.79904-29.6704 30.10048C919.3472 517.38624 931.17952 526.88384 943.01184 536.38144L943.01184 536.38144z" p-id="5681"/><path d="M986.07104 592.82432c0 0 21.46304-10.79296 27.86304-20.992 6.4-10.19392 2.72896-18.46272-1.39264-23.93088-4.11648-5.46816-9.43616-8.32512-17.1008-7.36256-7.66464 0.96256-22.50752 12.35456-33.3312 19.0208C970.09664 570.65472 978.08384 581.73952 986.07104 592.82432L986.07104 592.82432z" p-id="5682"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="749" t="1547192680027" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M377.596784 791.989528s-39.199482 22.799699 27.799633 30.399598c81.198926 9.199878 122.598379 7.999894 211.997197-8.999881 0 0 23.599688 14.799804 56.399254 27.599635C473.395518 926.787745 220.198866 835.988946 377.596784 791.989528m-24.399677-112.198517s-43.799421 32.399572 23.199693 39.399479c86.598855 8.999881 155.197948 9.599873 273.596382-13.199825 0 0 16.399783 16.599781 42.199442 25.599661-242.596792 70.999061-512.593222 5.799923-338.995517-51.799315m206.397271-190.197485c49.399347 56.799249-12.999828 107.998572-12.999828 107.998572s125.398342-64.799143 67.799103-145.798072c-53.799289-75.599-94.998744-113.198503 128.198305-242.596792 0.199997 0-350.395367 87.598842-182.99758 280.396292m265.196493 385.194907s28.999617 23.799685-31.799579 42.399439c-115.798469 34.999537-481.593632 45.599397-583.192289 1.399982-36.599516-15.799791 31.999577-37.999498 53.599291-42.599437 22.399704-4.799937 35.399532-3.999947 35.399532-3.999947-40.599463-28.599622-262.596528 56.199257-112.798508 80.398937 408.3946 66.399122 744.790152-29.799606 638.791553-77.598974M396.396536 563.592548s-186.197538 44.199416-65.999128 60.199204c50.799328 6.79991 151.99799 5.199931 246.196745-2.599966 76.998982-6.399915 154.397958-20.39973 154.397958-20.39973s-27.19964 11.599847-46.799381 24.999669c-188.997501 49.799342-553.992675 26.599648-448.994063-24.19968 88.998823-42.799434 161.197869-37.999498 161.197869-37.999497m333.995583 186.597532c192.197459-99.79868 103.198635-195.797411 41.199456-182.797582-15.199799 3.199958-21.999709 5.999921-21.999709 5.99992s5.599926-8.799884 16.399783-12.599833c122.598379-43.199429 216.997131 127.198318-39.599477 194.597427 0-0.199997 2.99996-2.799963 3.999947-5.199932M614.393653 0s106.398593 106.398593-100.998664 269.99643c-166.197802 131.198265-37.999498 206.197274 0 291.596144-96.998717-87.598842-168.197776-164.597824-120.398408-236.396874C463.195652 220.197088 657.393085 168.997765 614.393653 0m-198.997369 1020.786502c184.397562 11.799844 467.593817-6.599913 474.19373-93.798759 0 0-12.799831 32.999564-152.397985 59.399214-157.397919 29.599609-351.595351 26.199654-466.59383 7.199905 0-0.199997 23.599688 19.399743 144.798085 27.19964" p-id="750"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.585 12.087c0 6.616 3.974 11.98 8.877 11.98 4.902 0 8.877-5.364 8.877-11.98 0-6.616-3.975-11.98-8.877-11.98-4.903 0-8.877 5.364-8.877 11.98zM125.86.107H35.613c-1.268 0-2.114 1.426-2.114 2.852v18.255c0 1.712 1.057 2.853 2.114 2.853h90.247c1.268 0 2.114-1.426 2.114-2.853V2.96c0-1.711-1.057-2.852-2.114-2.852zM.106 62.86c0 6.615 3.974 11.979 8.876 11.979 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zM124.17 50.88H33.921c-1.268 0-2.114 1.425-2.114 2.851v18.256c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852V53.73c0-1.426-.846-2.852-2.114-2.852zM.106 115.913c0 6.616 3.974 11.98 8.876 11.98 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zm124.064-11.98H33.921c-1.268 0-2.114 1.426-2.114 2.853v18.255c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852v-18.255c0-1.427-.846-2.853-2.114-2.853z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="3654" t="1545700954682" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M868.935 1008.63l-713.868 0c-40.657 0-72.291-31.631-72.291-67.773l0-496.994c0-36.144 31.631-67.773 72.291-67.773l713.868 0c40.657 0 72.291 31.631 72.291 67.773l0 496.994c0 36.144-31.631 67.773-72.291 67.773l0 0 0 0 0 0zM512 543.259c-58.732 0-108.432 45.187-108.432 99.402 0 36.144 22.586 67.773 54.218 85.849l0 94.887c0 27.108 22.586 49.696 54.218 49.696s54.218-22.586 54.218-49.696l0-94.887c31.631-18.071 54.218-49.696 54.218-85.849 0-54.218-49.696-99.402-108.432-99.402l0 0 0 0zM512 114.031c-117.471 0-216.867 90.356-216.867 198.797l-108.432 0c0-162.655 144.582-298.202 320.79-298.202s320.79 135.546 320.79 298.202l-108.432 0c9.041-112.951-90.356-198.797-207.836-198.797l0 0 0 0zM512 114.031z" p-id="3655"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="4026" t="1547360510388" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M787.692308 275.692308V78.769231c0-43.323077-35.446154-78.769231-78.769231-78.769231H78.769231C35.446154 0 0 35.446154 0 78.769231v866.461538c0 43.323077 35.446154 78.769231 78.769231 78.769231h354.461538v-39.384615H78.769231c-19.692308 0-39.384615-15.753846-39.384616-39.384616V78.769231c0-23.630769 15.753846-39.384615 39.384616-39.384616h630.153846c19.692308 0 39.384615 15.753846 39.384615 39.384616v196.923077h39.384616z" p-id="4027"/><path fill="#bfbfbf" d="M137.846154 472.615385h196.923077c11.815385 0 19.692308 7.876923 19.692307 19.692307s-7.876923 19.692308-19.692307 19.692308h-196.923077c-11.815385 0-19.692308-7.876923-19.692308-19.692308s7.876923-19.692308 19.692308-19.692307zM137.846154 669.538462h118.153846c11.815385 0 19.692308 7.876923 19.692308 19.692307s-7.876923 19.692308-19.692308 19.692308h-118.153846c-11.815385 0-19.692308-7.876923-19.692308-19.692308s7.876923-19.692308 19.692308-19.692307zM137.846154 275.692308h354.461538c11.815385 0 19.692308 7.876923 19.692308 19.692307s-7.876923 19.692308-19.692308 19.692308h-354.461538c-11.815385 0-19.692308-7.876923-19.692308-19.692308s7.876923-19.692308 19.692308-19.692307zM716.8 433.230769c7.876923 0 19.692308 0 31.507692 3.938462 0 3.938462 3.938462 11.815385 3.938462 19.692307 3.938462 23.630769 11.815385 63.015385 55.138461 78.769231 7.876923 3.938462 15.753846 3.938462 19.692308 3.938462 31.507692 0 51.2-19.692308 66.953846-35.446154l11.815385-11.815385c43.323077 19.692308 66.953846 51.2 70.892308 98.461539-3.938462 3.938462-11.815385 7.876923-19.692308 7.876923-15.753846 7.876923-51.2 27.569231-51.2 70.892308s39.384615 63.015385 63.015384 74.830769c3.938462 3.938462 11.815385 7.876923 19.692308 7.876923-3.938462 47.261538-27.569231 74.830769-74.830769 98.461538l-11.815385-11.815384c-15.753846-15.753846-35.446154-31.507692-66.953846-31.507693-7.876923 0-15.753846 0-23.630769 3.938462-43.323077 11.815385-51.2 51.2-55.138462 74.830769 0 3.938462-3.938462 11.815385-3.938461 15.753846-11.815385 0-19.692308 3.938462-31.507692 3.938462-35.446154 0-63.015385-11.815385-86.646154-39.384616 0-3.938462 3.938462-11.815385 7.876923-15.753846 11.815385-23.630769 31.507692-59.076923 3.938461-94.523077-7.876923-11.815385-27.569231-27.569231-63.015384-27.56923-11.815385 0-19.692308 0-31.507693 3.938461-7.876923 0-15.753846 3.938462-19.692307 3.938462-23.630769-43.323077-23.630769-78.769231 0-122.092308 3.938462 0 11.815385 0 19.692307 3.938462 7.876923 0 19.692308 3.938462 31.507693 3.938461 31.507692 0 51.2-15.753846 63.015384-27.569231 27.569231-35.446154 7.876923-74.830769-3.938461-94.523077-3.938462-3.938462-7.876923-11.815385-7.876923-15.753846 23.630769-39.384615 51.2-51.2 82.707692-51.2m0-39.384615c-47.261538 0-82.707692 19.692308-118.153846 55.138461-27.569231 31.507692 35.446154 78.769231 11.815384 110.276923-7.876923 11.815385-19.692308 11.815385-31.507692 11.815385-15.753846 0-35.446154-3.938462-51.2-3.938461-11.815385 0-23.630769 3.938462-31.507692 15.753846-31.507692 55.138462-31.507692 110.276923 0 169.353846 7.876923 11.815385 19.692308 15.753846 31.507692 15.753846 15.753846 0 35.446154-3.938462 51.2-3.938462 11.815385 0 23.630769 3.938462 31.507692 11.815385 23.630769 35.446154-43.323077 78.769231-11.815384 110.276923 35.446154 39.384615 74.830769 55.138462 122.092308 55.138462 11.815385 0 27.569231 0 43.323076-3.938462 43.323077-7.876923 19.692308-78.769231 59.076924-94.523077h7.876923c31.507692 0 51.2 47.261538 78.76923 47.261539 3.938462 0 7.876923 0 11.815385-3.938462 63.015385-27.569231 94.523077-70.892308 102.4-133.907692 3.938462-43.323077-78.769231-43.323077-78.769231-82.707692 0-43.323077 82.707692-39.384615 78.769231-82.707693-7.876923-63.015385-39.384615-110.276923-102.4-133.907692-3.938462 0-7.876923-3.938462-11.815385-3.938462-31.507692 0-51.2 51.2-82.707692 51.2h-7.876923c-39.384615-11.815385-15.753846-86.646154-59.076923-98.461538-15.753846-7.876923-27.569231-7.876923-43.323077-7.876923z" p-id="4028"/><path fill="#bfbfbf" d="M748.307692 590.769231c43.323077 0 78.769231 35.446154 78.769231 78.769231s-35.446154 78.769231-78.769231 78.76923-78.769231-35.446154-78.76923-78.76923 35.446154-78.769231 78.76923-78.769231m0-39.384616c-66.953846 0-118.153846 51.2-118.153846 118.153847s51.2 118.153846 118.153846 118.153846 118.153846-51.2 118.153846-118.153846-51.2-118.153846-118.153846-118.153847z" p-id="4029"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575115830633" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2251" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M409.002667 469.333333L300.8 361.130667 361.130667 300.8l211.2 211.2-211.2 211.2-60.330667-60.330667L409.002667 554.666667H128v-85.333334h281.002667zM469.333333 128h341.333334c46.933333 0 85.333333 38.4 85.333333 85.333333v597.333334c0 46.933333-38.4 85.333333-85.333333 85.333333h-341.333334v-85.333333h341.333334V213.333333h-341.333334V128z" fill="#cdcdcd" p-id="2252"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="983" t="1552025141027" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M895.318 192H128.682C93.008 192 64 220.968 64 256.616v510.698C64 802.986 93.008 832 128.682 832h766.636C930.992 832 960 802.986 960 767.312V256.616C960 220.968 930.992 192 895.318 192zM568.046 704h-112.096v-192l-84.08 107.756L287.826 512v192H175.738V320h112.088l84.044 135.96 84.08-135.96h112.096v384z m167.314 0l-139.27-192h84v-192h112.086v192h84.054l-140.906 192h0.036z" p-id="984"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="2559" t="1545037285158" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M96 128h832v192H96zM96 416h832v192H96zM96 704h832v192H96z" p-id="2560"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 20.967v59.59c0 11.59 8.537 20.966 19.075 20.966h28.613l1 26.477L76.8 101.523h32.125c10.538 0 19.075-9.377 19.075-20.966v-59.59C128 9.377 119.463 0 108.925 0h-89.85C8.538 0 0 9.377 0 20.967zm82.325 33.1c0-5.524 4.013-9.935 9.037-9.935 5.026 0 9.038 4.41 9.038 9.934 0 5.524-4.025 9.934-9.038 9.934-5.024 0-9.037-4.41-9.037-9.934zm-27.613 0c0-5.524 4.013-9.935 9.038-9.935s9.037 4.41 9.037 9.934c0 5.524-4.025 9.934-9.037 9.934-5.025 0-9.038-4.41-9.038-9.934zm-27.1 0c0-5.524 4.013-9.935 9.038-9.935s9.038 4.41 9.038 9.934c0 5.524-4.026 9.934-9.05 9.934-5.013 0-9.025-4.41-9.025-9.934z"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574572606408" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1870" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M870.4 793.6H153.6C68.9024 793.6 0 724.6976 0 640V153.6C0 68.9024 68.9024 0 153.6 0h716.8c84.6976 0 153.6 68.9024 153.6 153.6v486.4c0 84.6976-68.9024 153.6-153.6 153.6zM153.6 51.2c-56.4608 0-102.4 45.9392-102.4 102.4v486.4c0 56.4608 45.9392 102.4 102.4 102.4h716.8c56.4608 0 102.4-45.9392 102.4-102.4V153.6c0-56.4608-45.9392-102.4-102.4-102.4H153.6zM793.6 1024H230.4a25.6 25.6 0 0 1 0-51.2h563.2a25.6 25.6 0 0 1 0 51.2zM633.6 908.8h-243.2a25.6 25.6 0 0 1 0-51.2h243.2a25.6 25.6 0 0 1 0 51.2z" fill="#bfbfbf" p-id="1871"></path><path d="M349.0688 404.3008A25.664 25.664 0 0 1 330.9568 396.8l-54.2976-54.3104a25.6 25.6 0 0 1 36.2112-36.2112l44.2624 44.2752 88.2688-20.3648 20.3648-88.256-44.2752-44.2752a25.6 25.6 0 1 1 36.1984-36.1984L512 215.7824c6.2464 6.2336 8.8192 15.2576 6.848 23.8592l-27.1616 117.6704a25.6 25.6 0 0 1-19.1872 19.1872l-117.6832 27.1488a25.7792 25.7792 0 0 1-5.7472 0.6528zM584.4096 639.6288a25.4976 25.4976 0 0 1-18.0992-7.5008L512 577.8304a25.5616 25.5616 0 0 1-6.848-23.8464l27.1488-117.6832a25.6256 25.6256 0 0 1 19.2-19.1872l117.6704-27.1488a25.536 25.536 0 0 1 23.8464 6.848l54.2976 54.3104a25.6 25.6 0 0 1-36.1984 36.2112l-44.2752-44.2752-88.256 20.3648-20.3648 88.256 44.2752 44.2752a25.6 25.6 0 0 1-18.0864 43.6736z" fill="#bfbfbf" p-id="1872"></path><path d="M557.248 467.648a25.4976 25.4976 0 0 1-18.0992-7.5008l-90.496-90.496a25.6 25.6 0 1 1 36.1984-36.1984l90.496 90.496a25.6 25.6 0 0 1-18.0992 43.6992z" fill="#bfbfbf" p-id="1873"></path></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.122 127.892v-28.68H7.513V87.274h46.609v-12.4H7.513v-12.86h38.003L.099 0h22.6l32.556 45.07c3.617 5.144 6.44 9.611 8.487 13.385 1.788-3.05 4.89-7.779 9.301-14.186L103.93 0h24.01L82.385 62.013h38.34v12.862h-46.41v12.4h46.41v11.937h-46.41v28.68H54.123z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="4695" t="1543827393750" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css">@font-face{font-family:rbicon;src:url(chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2) format(&quot;woff2&quot;);font-weight:400;font-style:normal}</style></defs><path d="M64 64V640H896V64H64zM0 0h960v704H0V0z" p-id="4696"/><path d="M192 896H768v64H192zM448 640H512v256h-64z" p-id="4697"/><path d="M479.232 561.604267l309.9904-348.330667-47.803733-42.5472-259.566934 291.669333L303.957333 240.008533 163.208533 438.6048l52.224 37.009067 91.6224-129.28z" p-id="4698"/></svg>
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="3833" t="1561614515233" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#8a8a8a" d="M807.049 391.258c0.946-9.62 1.45-19.37 1.45-29.239 0-163.7-132.706-296.406-296.406-296.406S215.687 198.318 215.687 362.02c0 9.802 0.498 19.486 1.432 29.043-43.925 18.95-74.675 62.638-74.675 113.516v330.363c0 68.25 55.328 123.58 123.58 123.58h491.672c68.25 0 123.578-55.328 123.578-123.58V504.578c0-50.704-30.54-94.267-74.225-113.32zM510.917 165.905c109.134 0 197.604 88.47 197.604 197.603 0 5.895-0.275 11.726-0.782 17.49H314.094a200.097 200.097 0 0 1-0.782-17.49c0.002-109.132 88.472-197.603 197.605-197.603z" p-id="3834"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M104.185 95.254c8.161 7.574 13.145 17.441 13.145 28.28 0 1.508-.098 2.998-.285 4.466h-10.784c.238-1.465.403-2.948.403-4.465 0-8.983-4.36-17.115-11.419-23.216C86 104.66 75.355 107.162 64 107.162c-11.344 0-21.98-2.495-31.22-6.83-7.064 6.099-11.444 14.218-11.444 23.203 0 1.517.165 3 .403 4.465H10.955a35.444 35.444 0 0 1-.285-4.465c0-10.838 4.974-20.713 13.127-28.291C9.294 85.42.003 70.417.003 53.58.003 23.99 28.656.001 64 .001s63.997 23.988 63.997 53.58c0 16.842-9.299 31.85-23.812 41.673zM64 36.867c-29.454 0-53.33-10.077-53.33 15.342 0 25.418 23.876 46.023 53.33 46.023 29.454 0 53.33-20.605 53.33-46.023 0-25.419-23.876-15.342-53.33-15.342zm24.888 25.644c-3.927 0-7.111-2.665-7.111-5.953 0-3.288 3.184-5.954 7.11-5.954 3.928 0 7.111 2.666 7.111 5.954s-3.183 5.953-7.11 5.953zm-3.556 16.372c0 4.11-9.55 7.442-21.332 7.442-11.781 0-21.332-3.332-21.332-7.442 0-1.06.656-2.064 1.8-2.976 3.295 2.626 10.79 4.465 19.532 4.465 8.743 0 16.237-1.84 19.531-4.465 1.145.912 1.801 1.916 1.801 2.976zm-46.22-16.372c-3.927 0-7.11-2.665-7.11-5.953 0-3.288 3.183-5.954 7.11-5.954 3.927 0 7.111 2.666 7.111 5.954s-3.184 5.953-7.11 5.953z"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><g><path d="M95.648 118.762c0 5.035-3.563 9.121-7.979 9.121H7.98c-4.416 0-7.979-4.086-7.979-9.121C0 100.519 15.408 83.47 31.152 76.75c-9.099-6.43-15.216-17.863-15.216-30.987v-9.128c0-20.16 14.293-36.518 31.893-36.518s31.894 16.358 31.894 36.518v9.122c0 13.137-6.123 24.556-15.216 30.993 15.738 6.726 31.141 23.769 31.141 42.012z"/><path d="M106.032 118.252h15.867c3.376 0 6.101-3.125 6.101-6.972 0-13.957-11.787-26.984-23.819-32.123 6.955-4.919 11.638-13.66 11.638-23.704v-6.985c0-15.416-10.928-27.926-24.39-27.926-1.674 0-3.306.193-4.89.561 1.936 4.713 3.018 9.974 3.018 15.526v9.121c0 13.137-3.056 23.111-11.066 30.993 14.842 4.41 27.312 23.42 27.541 41.509z"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="3778" t="1543477660371" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css">@font-face{font-family:rbicon;src:url(chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2) format(&quot;woff2&quot;);font-weight:400;font-style:normal}</style></defs><path d="M418.496 705.6 383.296 705.6l0-53.248 0 0C384 484.48 257.28 503.808 255.872 503.808L255.488 503.744c-133.504 0-125.632 146.112-125.632 148.608l0 53.248L91.84 705.6C76.032 705.6 64 716.864 64 731.52l0 201.152c0 14.72 12.032 25.856 27.84 25.856l326.656 0c15.808 0 28.096-11.136 28.096-25.856L446.592 731.52C446.592 716.864 434.24 705.6 418.496 705.6zM175.936 652.352c0-0.448-4.928-100.8 77.376-100.8 7.296 0.256 78.144-4.032 78.144 100.8l0 53.248-155.52 0L175.936 652.352zM960 889.024c0 61.12-77.824 69.504-77.824 69.504L635.776 958.528l-80.64 0c0 0-41.088 0.96-41.088-39.168l-1.344-196.928C514.304 533.376 464 464.768 348.8 427.264c-33.344-24.96-47.168-31.296-47.168-78.528 0-47.232 38.848-47.232 38.848-47.232s0 1.344 13.824-76.416c13.44-75.456 87.232-155.968 208.32-160.64L562.624 64c1.792 0 3.456 0.192 5.248 0.192C569.856 64.192 571.776 64 573.824 64l0 0.512c105.28 5.312 181.056 85.44 194.432 160.576 13.888 77.76 13.888 76.416 13.888 76.416s38.848 0 38.848 47.232c0 47.232-13.824 63.936-47.168 88.896C740.48 462.656 750.4 516.48 698.88 563.968c-27.52 25.344-47.232 44.48-47.232 80.64 0 36.032 19.456 44.352 38.848 55.488s150.016 47.232 211.136 88.96S960 852.928 960 889.024z" p-id="3779"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="1989" t="1554009861477" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#8a8a8a" d="M756.081 1012.218 291.154 1012.218c-68.473 0-123.982-55.975-123.982-125.054L167.172 136.836c0-69.078 55.512-125.054 123.982-125.054l464.928 0c68.474 0 123.984 55.975 123.984 125.054l0 750.328C880.066 956.242 824.555 1012.218 756.081 1012.218L756.081 1012.218zM818.062 136.836c0-34.516-27.751-62.526-61.98-62.526L291.154 74.31c-34.228 0-61.991 28.01-61.991 62.526l0 31.268 588.899 0L818.062 136.836 818.062 136.836zM818.062 230.63 229.163 230.63l0 499.242 588.899 0L818.062 230.63 818.062 230.63zM818.062 792.398 229.163 792.398l0 94.766c0 34.54 27.765 62.526 61.991 62.526l464.928 0c34.229 0 61.98-27.986 61.98-62.526L818.062 792.398 818.062 792.398zM523.623 918.429c-25.668 0-46.482-20.993-46.482-46.896 0-25.903 20.816-46.895 46.482-46.895 25.664 0 46.477 20.993 46.477 46.895S549.287 918.429 523.623 918.429L523.623 918.429z" p-id="1990"/><path fill="#8a8a8a" d="M756.081 1017.218 291.154 1017.218c-71.121 0-128.982-58.342-128.982-130.054L162.172 136.836c0-71.712 57.861-130.054 128.982-130.054l464.928 0c71.122 0 128.984 58.342 128.984 130.054l0 750.328C885.066 958.876 827.204 1017.218 756.081 1017.218zM291.154 16.783c-65.607 0-118.982 53.856-118.982 120.054l0 750.328c0 66.198 53.375 120.054 118.982 120.054l464.927 0c65.608 0 118.985-53.855 118.985-120.054L875.066 136.836c0-66.198-53.376-120.054-118.984-120.054L291.154 16.782zM756.082 954.69 291.154 954.69c-36.939 0-66.991-30.292-66.991-67.526l0-99.766 598.899 0 0.001 99.766C823.063 924.398 793.016 954.69 756.082 954.69zM234.163 797.398l0 89.766c0 31.72 25.566 57.526 56.991 57.526l464.928 0c31.419 0 56.98-25.807 56.98-57.526l0-89.766L234.163 797.398zM523.623 923.429c-28.387 0-51.482-23.28-51.482-51.896s23.096-51.895 51.482-51.895c28.385 0 51.477 23.279 51.477 51.895S552.008 923.429 523.623 923.429zM523.623 829.639c-22.873 0-41.482 18.794-41.482 41.895 0 23.102 18.609 41.896 41.482 41.896 22.871 0 41.477-18.794 41.477-41.896C565.1 848.433 546.494 829.639 523.623 829.639zM823.062 734.872 224.163 734.872 224.163 225.63l598.899 0L823.062 734.872zM234.163 724.872l578.899 0L813.062 235.63 234.163 235.63 234.163 724.872zM823.062 173.104 224.163 173.104l0-36.268c0-37.234 30.052-67.526 66.991-67.526l464.927 0c36.934 0 66.98 30.292 66.98 67.526L823.061 173.104zM234.163 163.104l578.899 0 0-26.268c0-31.72-25.562-57.526-56.98-57.526L291.154 79.31c-31.425 0-56.991 25.806-56.991 57.526L234.163 163.104z" p-id="1991"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="1276" t="1546225865881" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M892.928 499.712c-45.056-45.056-116.736-45.056-161.792 0-36.864 36.864-43.008 92.16-20.48 135.168L602.112 743.424c-51.2 51.2-137.216 45.056-194.56-10.24s-61.44-143.36-10.24-194.56L522.24 413.696l-45.056-45.056-124.928 124.928c-75.776 75.776-71.68 204.8 10.24 286.72 43.008 43.008 98.304 65.536 153.6 65.536 49.152 0 96.256-18.432 133.12-53.248L757.76 684.032c16.384 8.192 34.816 14.336 55.296 14.336 28.672 0 59.392-10.24 79.872-32.768 45.056-49.152 45.056-122.88 0-165.888zM847.872 614.4c-18.432 18.432-51.2 18.432-69.632 0-18.432-18.432-18.432-51.2 0-69.632 10.24-10.24 22.528-14.336 34.816-14.336s24.576 4.096 34.816 14.336c18.432 18.432 18.432 51.2 0 69.632z" p-id="1277"/><path fill="#bfbfbf" d="M296.96 372.736l108.544-108.544c51.2-51.2 137.216-45.056 194.56 10.24 26.624 26.624 43.008 63.488 45.056 100.352 2.048 36.864-10.24 69.632-34.816 94.208L485.376 593.92l45.056 45.056L655.36 514.048c36.864-36.864 55.296-88.064 53.248-141.312-2.048-53.248-24.576-104.448-63.488-143.36-81.92-81.92-208.896-86.016-286.72-10.24L249.856 327.68c-43.008-22.528-98.304-16.384-135.168 20.48-45.056 45.056-45.056 116.736 0 161.792 22.528 22.528 51.2 32.768 79.872 32.768s59.392-10.24 79.872-32.768c38.912-38.912 45.056-94.208 22.528-137.216z m-65.536 90.112c-18.432 18.432-51.2 18.432-69.632 0-18.432-18.432-18.432-51.2 0-69.632 10.24-10.24 22.528-14.336 34.816-14.336 12.288 0 24.576 4.096 34.816 14.336 18.432 18.432 18.432 49.152 0 69.632z" p-id="1278"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547360607827" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6287" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M900.512 388.751V287.87L512.708 63.967 124.904 287.87v240.093c-23.42 6.798-40.924 27.562-40.924 53.144s17.504 46.346 40.924 53.144v101.424l387.804 223.862 387.804-223.862V494.761c23.13-6.979 40.345-27.642 40.345-52.984 0-25.376-17.215-46.047-40.345-53.026zM114.87 581.107c0-13.999 11.356-25.355 25.355-25.355 13.958 0 25.314 11.356 25.314 25.355s-11.356 25.355-25.314 25.355c-13.999 0-25.355-11.356-25.355-25.355z m754.753 136.729L512.708 923.858 155.793 717.836v-83.638c23.265-6.883 40.635-27.603 40.635-53.09 0-25.487-17.37-46.207-40.635-53.09V305.709L512.708 99.646l356.915 206.063v82.856c-23.585 6.692-41.254 27.513-41.254 53.212 0 25.665 17.669 46.48 41.254 53.17v222.889z m14.99-250.745c-13.999 0-25.355-11.356-25.355-25.314 0-13.999 11.356-25.355 25.355-25.355s25.355 11.356 25.355 25.355c0 13.958-11.356 25.314-25.355 25.314z m-184.631-117.32c-5.947-2.271-12.678-0.661-17.014 4.047L511.841 542.29 338.029 357.576c-4.295-4.666-10.985-6.153-16.931-3.758a15.428 15.428 0 0 0-9.746 14.329v315.867h30.889V407.089l158.574 168.526a15.404 15.404 0 0 0 11.232 4.873c3.469-0.289 8.507-1.9 11.439-5.079l155.477-171.251v279.817h30.889v-319.79a15.492 15.492 0 0 0-9.87-14.414z" fill="#bfbfbf" p-id="6288"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="2866" t="1543477186503" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css">@font-face{font-family:rbicon;src:url(chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2) format(&quot;woff2&quot;);font-weight:400;font-style:normal}</style></defs><path d="M609.093716 908.277839c0-106.125689 85.803749-191.929438 191.929438-191.929438 38.950386 0 75.07828 11.854465 105.561191 31.611907l0-3.38699c0-60.965821-71.69129-136.044101-128.705623-145.076075l76.771775-127.012128-178.945976 0c32.176406-46.288864 53.627343-107.254686 53.627343-174.994487 0-5.080485 0-10.725469 0-15.805954 69.433297-12.418964 114.593164-32.176406 114.593164-51.933848 0-21.450937-50.240353-41.208379-127.012128-53.627343C712.961411 158.059537 661.592062 11.289967 600.62624 11.289967c-27.095921 0-48.546858 14.112459-62.659316 35.563396 0 10.725469-10.725469 21.450937-24.837927 21.450937-12.418964 0-23.144432-9.031974-24.837927-19.757442C475.307607 27.660419 452.163175 11.289967 425.631753 11.289967 366.359427 11.289967 311.038589 145.640573 298.619625 179.510474 232.573319 191.929438 189.671444 209.993385 189.671444 231.444322c0 21.450937 44.595369 39.514884 114.593164 51.933848 0 5.080485 0 10.725469 0 15.805954 0 67.739802 19.757442 128.705623 53.627343 174.994487L178.945976 474.178611l76.771775 125.318633c-57.014333 0-132.092613 78.46527-132.092613 146.76957l1.693495 205.477398c0 33.869901 26.531422 60.965821 60.965821 60.965821l453.85667 0C620.383682 982.227122 609.093716 946.663727 609.093716 908.277839zM468.533627 962.46968l-28.789416 0-53.627343-395.148842 112.335171 98.222712L468.533627 962.46968zM498.45204 351.117971c-7.338479 62.659316-39.514884 76.771775-57.014333 76.771775-42.901874 0-55.320838-57.014333-57.014333-76.771775l-14.112459 0L370.310915 338.699008l0-12.418964 107.254686 0L477.565601 338.699008l71.69129 0 0-12.418964 107.254686 0L656.511577 338.699008l3.38699 0 0 12.418964-14.112459 0c0 0-9.031974 76.771775-57.014333 76.771775C539.660419 427.889746 530.628445 351.117971 530.628445 351.117971L498.45204 351.117971zM562.804851 962.46968l-30.482911-296.92613 112.335171-99.916207-53.627343 396.842337L562.804851 962.46968z" p-id="2867"/><path d="M918.438809 907.148842c0 1.693495-1.128997 2.822492-2.822492 2.822492l-97.658214 0 0 97.658214c0 1.693495-1.128997 2.822492-2.822492 2.822492l-43.466373 0c-1.693495 0-2.822492-1.128997-2.822492-2.822492l0-97.658214-97.658214 0c-1.693495 0-2.822492-1.128997-2.822492-2.822492L668.366042 863.68247c0-1.693495 1.128997-2.822492 2.822492-2.822492l97.658214 0 0-97.658214c0-1.693495 1.128997-2.822492 2.822492-2.822492l43.466373 0c1.693495 0 2.822492 1.128997 2.822492 2.822492l0 97.658214 97.658214 0c1.693495 0 2.822492 1.128997 2.822492 2.822492L918.438809 907.148842z" p-id="2868"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M124.884 109.812L94.256 79.166c-.357-.357-.757-.629-1.129-.914a50.366 50.366 0 0 0 8.186-27.59C101.327 22.689 78.656 0 50.67 0 22.685 0 0 22.688 0 50.663c0 27.989 22.685 50.663 50.656 50.663 10.186 0 19.643-3.03 27.6-8.201.286.385.557.771.9 1.114l30.628 30.632a10.633 10.633 0 0 0 7.543 3.129c2.728 0 5.457-1.043 7.543-3.115 4.171-4.157 4.171-10.915.014-15.073M50.671 85.338C31.557 85.338 16 69.78 16 50.663c0-19.102 15.557-34.661 34.67-34.661 19.115 0 34.657 15.559 34.657 34.675 0 19.102-15.557 34.661-34.656 34.661"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574576420335" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9530" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M915.94 827.89h-91.42a12.5 12.5 0 0 1 0-25h78.92v-535h-78.92a12.5 12.5 0 1 1 0-25h91.42a12.5 12.5 0 0 1 12.5 12.5v560a12.5 12.5 0 0 1-12.5 12.5z" fill="#cdcdcd" p-id="9531"></path><path d="M915.94 547.91h-91.42a12.5 12.5 0 0 1 0-25h91.42a12.5 12.5 0 0 1 0 25z" fill="#cdcdcd" p-id="9532"></path><path d="M774.6 231.51a90.63 90.63 0 0 1-90.37 90.37H215.94a90.62 90.62 0 0 1-81.18-50.81 88.92 88.92 0 0 0 15.4 1.33h468.29a90.26 90.26 0 0 0 81.18-129.92c42.44 7.35 74.97 44.57 74.97 89.03z" fill="#cdcdcd" p-id="9533"></path><path d="M684.23 334.38H215.94a102.23 102.23 0 0 1-55.12-16.11 103.66 103.66 0 0 1-37.28-41.69 12.5 12.5 0 0 1 13.38-17.82 76.71 76.71 0 0 0 13.24 1.14h468.29a77.76 77.76 0 0 0 70-111.91 12.5 12.5 0 0 1 13.35-17.83 103.18 103.18 0 0 1 85.3 101.35 103.13 103.13 0 0 1-102.87 102.87zM159.46 284.9a78.31 78.31 0 0 0 56.48 24.48h468.29a77.75 77.75 0 0 0 59.28-128.2 78.73 78.73 0 0 0-24.14-19.08 103.06 103.06 0 0 1-100.92 122.8z" fill="#cdcdcd" p-id="9534"></path><path d="M618.45 284.91H150.16a102.86 102.86 0 1 1 0-205.73h468.29a102.86 102.86 0 0 1 0 205.73zM150.16 104.18a77.86 77.86 0 1 0 0 155.73h468.29a77.86 77.86 0 0 0 0-155.73z" fill="#cdcdcd" p-id="9535"></path><path d="M176.2 235.43A53.39 53.39 0 1 1 229.59 182a53.45 53.45 0 0 1-53.39 53.43z m0-81.78A28.39 28.39 0 1 0 204.59 182a28.43 28.43 0 0 0-28.39-28.35zM551.12 194.54H423a12.5 12.5 0 0 1 0-25h128.12a12.5 12.5 0 0 1 0 25z" fill="#cdcdcd" p-id="9536"></path><path d="M774.6 534.74a90.63 90.63 0 0 1-90.37 90.37H215.94a90.62 90.62 0 0 1-81.18-50.81 88.92 88.92 0 0 0 15.4 1.33h468.29a90.26 90.26 0 0 0 81.18-129.92c42.44 7.35 74.97 44.57 74.97 89.03z" fill="#cdcdcd" p-id="9537"></path><path d="M684.23 637.61H215.94a102.23 102.23 0 0 1-55.12-16.11 103.66 103.66 0 0 1-37.28-41.69A12.5 12.5 0 0 1 136.92 562a76.71 76.71 0 0 0 13.24 1.14h468.29a77.76 77.76 0 0 0 70-111.91 12.5 12.5 0 0 1 13.35-17.83 103.18 103.18 0 0 1 85.3 101.34 103.13 103.13 0 0 1-102.87 102.87z m-524.77-49.48a78.31 78.31 0 0 0 56.48 24.48h468.29a77.75 77.75 0 0 0 59.28-128.2 78.73 78.73 0 0 0-24.14-19.08 103.06 103.06 0 0 1-100.92 122.8z" fill="#cdcdcd" p-id="9538"></path><path d="M618.45 588.13H150.16a102.86 102.86 0 1 1 0-205.73h468.29a102.86 102.86 0 0 1 0 205.73zM150.16 407.4a77.86 77.86 0 1 0 0 155.73h468.29a77.86 77.86 0 0 0 0-155.73z" fill="#cdcdcd" p-id="9539"></path><path d="M176.2 538.66a53.39 53.39 0 1 1 53.39-53.39 53.45 53.45 0 0 1-53.39 53.39z m0-81.78a28.39 28.39 0 1 0 28.39 28.39 28.43 28.43 0 0 0-28.39-28.39zM551.12 497.77H423a12.5 12.5 0 0 1 0-25h128.12a12.5 12.5 0 0 1 0 25z" fill="#cdcdcd" p-id="9540"></path><path d="M774.6 869.33a90.63 90.63 0 0 1-90.37 90.37H215.94a90.62 90.62 0 0 1-81.18-50.81 88.92 88.92 0 0 0 15.4 1.33h468.29a90.26 90.26 0 0 0 81.18-129.92c42.44 7.35 74.97 44.57 74.97 89.03z" fill="#cdcdcd" p-id="9541"></path><path d="M684.23 972.2H215.94a102.23 102.23 0 0 1-55.12-16.11 103.66 103.66 0 0 1-37.28-41.69 12.5 12.5 0 0 1 13.38-17.82 76.71 76.71 0 0 0 13.24 1.14h468.29a77.76 77.76 0 0 0 70-111.91A12.5 12.5 0 0 1 701.76 768a102.73 102.73 0 0 1 55.14 174 102.16 102.16 0 0 1-72.67 30.2z m-524.77-49.48a78.31 78.31 0 0 0 56.48 24.48h468.29A77.75 77.75 0 0 0 743.51 819a78.71 78.71 0 0 0-24.14-19.08 103.06 103.06 0 0 1-100.92 122.8z" fill="#cdcdcd" p-id="9542"></path><path d="M618.45 922.72H150.16a102.86 102.86 0 1 1 0-205.73h468.29a102.86 102.86 0 0 1 0 205.73zM150.16 742a77.86 77.86 0 1 0 0 155.73h468.29a77.86 77.86 0 1 0 0-155.73z" fill="#cdcdcd" p-id="9543"></path><path d="M176.2 873.25a53.39 53.39 0 1 1 53.39-53.39 53.45 53.45 0 0 1-53.39 53.39z m0-81.78a28.39 28.39 0 1 0 28.39 28.39 28.42 28.42 0 0 0-28.39-28.4zM551.12 832.35H423a12.5 12.5 0 0 1 0-25h128.12a12.5 12.5 0 0 1 0 25z" fill="#cdcdcd" p-id="9544"></path></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M42.913 101.36c1.642 0 3.198.332 4.667.996a12.28 12.28 0 0 1 3.89 2.772c1.123 1.184 1.987 2.582 2.592 4.193.605 1.612.908 3.318.908 5.118 0 1.8-.303 3.507-.908 5.118-.605 1.611-1.469 3.01-2.593 4.194a13.3 13.3 0 0 1-3.889 2.843 10.582 10.582 0 0 1-4.667 1.066c-1.729 0-3.306-.355-4.732-1.066a13.604 13.604 0 0 1-3.825-2.843c-1.123-1.185-1.988-2.583-2.593-4.194a14.437 14.437 0 0 1-.907-5.118c0-1.8.302-3.506.907-5.118.605-1.61 1.47-3.009 2.593-4.193a12.515 12.515 0 0 1 3.825-2.772c1.426-.664 3.003-.996 4.732-.996zm53.932.285c1.643 0 3.22.331 4.733.995a11.386 11.386 0 0 1 3.889 2.772c1.08 1.185 1.945 2.583 2.593 4.194.648 1.61.972 3.317.972 5.118 0 1.8-.324 3.506-.972 5.117-.648 1.611-1.513 3.01-2.593 4.194a12.253 12.253 0 0 1-3.89 2.843 11 11 0 0 1-4.732 1.066 10.58 10.58 0 0 1-4.667-1.066 12.478 12.478 0 0 1-3.824-2.843c-1.08-1.185-1.945-2.583-2.593-4.194a13.581 13.581 0 0 1-.973-5.117c0-1.801.325-3.507.973-5.118.648-1.611 1.512-3.01 2.593-4.194a11.559 11.559 0 0 1 3.824-2.772 11.212 11.212 0 0 1 4.667-.995zm21.781-80.747c2.42 0 4.3.355 5.64 1.066 1.34.71 2.29 1.587 2.852 2.63a6.427 6.427 0 0 1 .778 3.34c-.044 1.185-.195 2.204-.454 3.057-.26.853-.8 2.606-1.62 5.26a589.268 589.268 0 0 1-2.788 8.743 1236.373 1236.373 0 0 0-3.047 9.453c-.994 3.128-1.75 5.592-2.269 7.393-1.123 3.79-2.55 6.42-4.278 7.89-1.728 1.469-3.846 2.203-6.352 2.203H39.023l1.945 12.795h65.342c4.148 0 6.223 1.943 6.223 5.828 0 1.896-.41 3.53-1.232 4.905-.821 1.374-2.442 2.061-4.862 2.061H38.505c-1.729 0-3.176-.426-4.343-1.28-1.167-.852-2.14-1.966-2.917-3.34a21.277 21.277 0 0 1-1.88-4.478 44.128 44.128 0 0 1-1.102-4.55c-.087-.568-.324-1.942-.713-4.122-.39-2.18-.865-4.904-1.426-8.174l-1.88-10.947c-.692-4.027-1.383-8.079-2.075-12.154-1.642-9.572-3.5-20.234-5.574-31.986H6.87c-1.296 0-2.377-.356-3.24-1.067a9.024 9.024 0 0 1-2.14-2.558 10.416 10.416 0 0 1-1.167-3.2C.108 8.53 0 7.488 0 6.54c0-1.896.583-3.46 1.75-4.69C2.917.615 4.494 0 6.482 0h13.095c1.728 0 3.111.284 4.148.853 1.037.569 1.858 1.28 2.463 2.132a8.548 8.548 0 0 1 1.297 2.701c.26.948.475 1.754.648 2.417.173.758.346 1.825.519 3.199.173 1.374.345 2.772.518 4.193.26 1.706.519 3.507.778 5.403h88.678z"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h54.796v18.286H36.531V128H18.265V73.143H0V54.857zm127.857-36.571H91.935V128H72.456V18.286H36.534V0h91.326l-.003 18.286z"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M31.652 93.206h33.401c1.44 2.418 3.077 4.663 4.93 6.692h-38.33v-6.692zm0-10.586h28.914a44.8 44.8 0 0 1-1.264-6.688h-27.65v6.688zm0-17.27H59.39c.288-2.286.714-4.532 1.34-6.687H31.65v6.687h.003zm53.913 44.84v5.85c0 2.798-2.095 5.075-4.667 5.075h-70.07c-2.576 0-4.663-2.277-4.663-5.075V31.26l23.22-20.96v22.25H17.16v6.688h18.39V6.688h45.348c2.576 0 4.667 2.277 4.667 5.066v20.009c1.987-.675 4.053-1.128 6.17-1.445v-18.56C91.738 5.28 86.874 0 80.902 0H31.15L0 28.118v87.917c0 6.48 4.859 11.759 10.832 11.759h70.07c5.974 0 10.837-5.27 10.837-11.759v-4.41c-2.117-.312-4.183-.765-6.17-1.435h-.004zM23.279 58.667h-7.96v6.688h7.96v-6.688zm-7.956 41.23h7.96v-6.691h-7.96v6.692zm7.956-23.96h-7.96v6.687h7.96v-6.688zm89.718-15.042l-4.896-4.07-12.447 17.613-11.19-9.305-3.762 5.311 16.091 13.38 16.204-22.929zM128 70.978c0-18.632-13.97-33.782-31.147-33.782-17.168 0-31.135 15.155-31.135 33.782 0 18.628 13.97 33.783 31.135 33.783 17.172 0 31.143-15.15 31.143-33.783H128zm-6.17 0c0 14.933-11.203 27.1-24.981 27.1-13.77 0-24.987-12.158-24.987-27.1 0-14.941 11.195-27.099 24.987-27.099 13.778 0 24.982 12.158 24.982 27.1z"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574679314986" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2155" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M546.26 538.81v257.63c0 18.38-14.9 33.29-33.29 33.29-18.01 0.37-32.91-13.93-33.29-31.94-0.01-0.45-0.01-0.9 0-1.35V538.81l-233-134.47c-15.73-9.25-21.07-29.45-11.98-45.27 8.82-15.71 28.7-21.3 44.41-12.48 0.29 0.16 0.57 0.33 0.86 0.5l233 133.14 231-133.14c15.43-9.29 35.48-4.31 44.77 11.13 0.17 0.28 0.34 0.57 0.5 0.86 9.09 15.82 3.74 36.01-11.98 45.27l-231 133.14v1.32z" fill="#515151" p-id="2156"></path><path d="M512 1006.74c-18.08 0-36.14-4.65-52.27-13.96L121.77 797.65c-32.24-18.61-52.27-53.3-52.27-90.53V316.87c0-37.23 20.03-71.92 52.27-90.53L459.73 31.22c32.24-18.61 72.29-18.61 104.53 0l337.97 195.13c32.24 18.61 52.27 53.3 52.27 90.53v390.25c0 37.23-20.03 71.92-52.27 90.53L564.27 992.78c-16.12 9.3-34.2 13.96-52.27 13.96z m0-940.77c-9.65 0-19.29 2.48-27.9 7.45L146.13 268.55c-17.21 9.94-27.9 28.45-27.9 48.32v390.25c0 19.87 10.69 38.39 27.9 48.32L484.1 950.57c17.21 9.94 38.59 9.93 55.8 0l337.97-195.13c17.21-9.94 27.9-28.45 27.9-48.32V316.87c0-19.87-10.69-38.39-27.9-48.32L539.9 73.43a55.757 55.757 0 0 0-27.9-7.46z" fill="#515151" p-id="2157"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="6696" t="1544607518503" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M896 716.8c-44.8 0-76.8 25.6-96 57.6L460.8 614.4l147.2-243.2c25.6 12.8 51.2 25.6 83.2 25.6 83.2 0 153.6-70.4 153.6-153.6s-70.4-153.6-153.6-153.6-153.6 64-153.6 147.2c0 19.2 6.4 38.4 12.8 57.6L300.8 403.2c-25.6-44.8-76.8-76.8-134.4-76.8C83.2 326.4 12.8 396.8 12.8 480c0 83.2 70.4 153.6 153.6 153.6 12.8 0 19.2 0 32-6.4l57.6 128c-12.8 12.8-19.2 25.6-19.2 44.8 0 38.4 32 64 64 64 38.4 0 64-32 64-64 0-12.8-6.4-19.2-6.4-32l70.4-121.6 352 166.4v6.4c0 64 51.2 115.2 115.2 115.2s115.2-51.2 115.2-115.2-51.2-102.4-115.2-102.4z m-204.8-582.4c57.6 0 108.8 44.8 108.8 108.8s-44.8 108.8-108.8 108.8-108.8-57.6-108.8-115.2 51.2-102.4 108.8-102.4zM569.6 332.8l-153.6 256-108.8-44.8c6.4-19.2 12.8-44.8 12.8-64V448l249.6-115.2zM64 480c0-57.6 44.8-108.8 108.8-108.8s108.8 44.8 108.8 108.8c0 57.6-44.8 108.8-108.8 108.8S64 537.6 64 480z m262.4 262.4c-6.4 0-12.8-6.4-19.2-6.4h-6.4l-57.6-128c12.8-6.4 25.6-12.8 38.4-25.6l108.8 51.2-64 108.8z m569.6 147.2c-38.4 0-64-32-64-64 0-38.4 32-64 64-64s64 32 64 64c0 38.4-25.6 64-64 64z" p-id="6697"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="3388" t="1553861152984" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M306.689473 349.006765l408.370805-0.3776c22.463618 0 40.678468-18.213827 40.678468-40.678468 0-22.463618-18.21485-40.677445-40.678468-40.677445l-408.370805 0.3776c-22.465664 0-40.679491 18.203594-40.679491 40.678468C266.009981 330.792938 284.223808 349.006765 306.689473 349.006765z" p-id="3389"/><path fill="#bfbfbf" d="M306.689473 511.719614l408.370805-0.3776c22.463618 0 40.678468-18.213827 40.678468-40.677445 0-22.463618-18.21485-40.677445-40.678468-40.677445l-408.370805 0.3776c-22.465664 0-40.679491 18.202571-40.679491 40.677445C266.009981 493.505787 284.223808 511.719614 306.689473 511.719614z" p-id="3390"/><path fill="#bfbfbf" d="M877.157095 624.190175l-0.337691-482.536968c-1.905396-43.141566-37.141922-77.602426-80.721463-77.751828l-573.366649 0.327458c-43.220361 1.917676-77.763085 37.302581-77.763085 80.999802l0 43.220361-0.335644 0 0.277316 645.76761 0.058328 0 0 43.220361c0 44.928259 36.428677 81.354889 81.357959 81.354889l40.677445 0 0 0.229221 120.088052-0.217964c22.465664 0 40.679491-18.213827 40.679491-40.677445 0-22.465664-18.213827-40.679491-40.679491-40.679491l-104.773252 0.189312c-39.148625-3.783163-53.509704-17.011442-56.051597-58.137095l-0.278339-623.272269 0.23843 32.224935c-0.972141-69.328995 14.937201-81.882915 80.204693-82.804914l-9.414417-0.099261 419.393859-0.23843c60.562331 1.429559 78.277808 12.652158 79.114872 70.174246l0 3.744277c0 2.99931 0 5.998621-0.081864 9.245572l0.081864-4.080945 0.25685 367.961466-160.131047 0.217964 0 0.11768-43.220361 0c-44.928259 0-81.354889 36.418444-81.354889 81.357959l0 40.677445-0.278339 0 0.257873 195.506742c-2.62171 12.93152 1.033539 26.874067 11.062963 36.903491 4.031826 4.030803 8.721639 7.021927 13.68672 9.006118 4.90573 2.087545 10.287297 3.25002 15.927761 3.25002 14.20349 0 26.656103-7.290033 33.924647-18.304901l271.679609-272.363178c3.01773-1.826602 5.838985-3.932566 8.303106-6.463202 7.704472-7.398504 12.532431-17.749246 12.532431-29.278837C878.171192 629.950366 877.793592 627.031896 877.157095 624.190175zM592.290139 819.2395l-0.078795-67.76129c0.556679-61.910025 14.896268-77.462233 82.549088-77.462233l-82.071204 0.545422-0.497327 73.223698-0.099261-73.79982 145.274688-0.197498L592.290139 819.2395z" p-id="3391"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574576079728" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6611" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M981.917808 277.742466H813.589041V122.038356c0-19.638356-15.430137-35.068493-35.068493-35.068493H252.493151c-19.638356 0-35.068493 15.430137-35.068493 35.068493v155.70411H42.082192c-19.638356 0-35.068493 15.430137-35.068493 35.068493V911.780822c0 19.638356 15.430137 35.068493 35.068493 35.068493h939.835616c19.638356 0 35.068493-15.430137 35.068493-35.068493V312.810959c0-19.638356-15.430137-35.068493-35.068493-35.068493z m-694.356164-120.635617H743.452055v120.635617H287.561644v-120.635617zM252.493151 347.879452h694.356164v133.260274h-74.345205v-50.49863c0-19.638356-15.430137-35.068493-35.068494-35.068493h-117.830137c-19.638356 0-35.068493 15.430137-35.068493 35.068493v50.49863h-336.657534v-50.49863c0-19.638356-15.430137-35.068493-35.068493-35.068493h-117.830137c-19.638356 0-35.068493 15.430137-35.068493 35.068493v50.49863H77.150685v-133.260274H252.493151z m549.873972 119.232877v140.273972h-47.69315v-140.273972h47.69315z m-526.027397 0v140.273972h-47.693151v-140.273972h47.693151zM77.150685 876.712329V551.276712h81.358904v89.775343c0 19.638356 15.430137 35.068493 35.068493 35.068493h117.830137c19.638356 0 35.068493-15.430137 35.068493-35.068493v-89.775343h336.657535v89.775343c0 19.638356 15.430137 35.068493 35.068493 35.068493h117.830137c19.638356 0 35.068493-15.430137 35.068493-35.068493v-89.775343h74.345205v324.032877H77.150685z" p-id="6612" fill="#bfbfbf"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="211.719" height="200" class="icon" p-id="10233" t="1543827724451" version="1.1" viewBox="0 0 1084 1024"><defs><style type="text/css">@font-face{font-family:rbicon;src:url(chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2) format(&quot;woff2&quot;);font-weight:400;font-style:normal}</style></defs><path fill="#bfbfbf" d="M1080.09609 434.500756c-4.216302-23.731757-26.9241-47.945376-50.595623-53.185637l-17.648235-4.095836a175.940257 175.940257 0 0 1-101.612877-80.832531 177.807476 177.807476 0 0 1-18.732427-129.801867l5.541425-16.684509c7.10748-23.129428-2.108151-54.992624-20.599646-70.833873 0 0-16.624276-14.094495-63.244529-41.199293-46.800951-26.984332-66.858502-34.513443-66.858502-34.513443-22.76803-8.372371-54.631227-0.361397-71.255503 17.407304l-12.287509 13.251234a173.470708 173.470708 0 0 1-120.465769 48.065842A174.13327 174.13327 0 0 1 421.329029 33.590675L409.583617 20.761071C393.140039 2.99237 361.096144-4.898138 338.267881 3.353767c0 0-20.358715 7.529111-67.099434 34.513443-46.800951 27.34573-63.244529 41.440225-63.244529 41.440225-18.431263 15.66055-27.646894 47.222582-20.539413 70.592941l5.059562 16.865207a178.048407 178.048407 0 0 1-18.672194 129.621169 174.916297 174.916297 0 0 1-102.275439 81.073463l-17.045906 3.854904c-23.310126 5.42096-46.258856 29.333415-50.595623 53.185637 0 0-3.854905 21.382674-3.854905 75.712737 0 54.330062 3.854905 75.712736 3.854905 75.712736 4.216302 23.972688 26.9241 47.945376 50.595623 53.185637l16.624276 3.854905a174.253736 174.253736 0 0 1 102.395904 81.314394c23.310126 40.837896 28.911785 87.337683 18.732427 129.801867l-4.81863 16.443578c-7.10748 23.129428 2.108151 54.992624 20.599646 70.833872 0 0 16.624276 14.094495 63.244529 41.199293 46.800951 27.104798 66.918735 34.513443 66.918735 34.513443 22.707798 8.372371 54.631227 0.361397 71.255503-17.407303l11.624947-12.588673a175.096996 175.096996 0 0 1 242.256662 0.120465l11.624947 12.648906c16.383345 17.708468 48.427239 25.598976 71.255503 17.347071 0 0 20.358715-7.529111 67.159666-34.513443 46.740719-27.104798 63.124063-41.199293 63.124064-41.199293 18.491496-15.600317 27.707127-47.463513 20.599646-70.833873l-5.059562-17.106139a176.723284 176.723284 0 0 1 18.672194-129.139305 176.060722 176.060722 0 0 1 102.395904-81.314394l16.68451-3.854905c23.310126-5.42096 46.258856-29.333415 50.595623-53.185637 0 0 3.854905-21.382674 3.854904-75.712737-0.240932-54.330062-4.095836-75.833202-4.095836-75.833202z m-537.819428 293.334149c-119.261112 0-216.175824-97.336342-216.175824-217.621412a216.657687 216.657687 0 0 1 216.236057-217.320249c119.200879 0 216.115591 97.276109 216.11559 217.56118-0.240932 120.044139-96.974945 217.320248-216.175823 217.320249z" p-id="10234"/></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1588584086939" class="icon" viewBox="0 0 1084 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1156" xmlns:xlink="http://www.w3.org/1999/xlink" width="211.71875" height="200"><defs><style type="text/css"></style></defs><path d="M1080.096 434.5c-4.216-23.731-26.924-47.945-50.596-53.185l-17.648-4.096a175.94 175.94 0 0 1-101.613-80.832 177.807 177.807 0 0 1-18.732-129.802l5.541-16.685c7.108-23.13-2.108-54.992-20.6-70.833 0 0-16.624-14.095-63.244-41.2-46.8-26.984-66.858-34.513-66.858-34.513-22.768-8.373-54.632-0.362-71.256 17.407l-12.287 13.251a173.47 173.47 0 0 1-120.466 48.066 174.133 174.133 0 0 1-121.008-48.487l-11.745-12.83C393.14 2.992 361.096-4.899 338.268 3.354c0 0-20.359 7.529-67.1 34.513-46.8 27.346-63.244 41.44-63.244 41.44-18.431 15.661-27.647 47.223-20.54 70.593l5.06 16.866a178.048 178.048 0 0 1-18.672 129.62A174.916 174.916 0 0 1 71.496 377.46l-17.045 3.855c-23.31 5.421-46.26 29.334-50.596 53.186 0 0-3.855 21.382-3.855 75.712s3.855 75.713 3.855 75.713C8.07 609.9 30.779 633.872 54.45 639.112l16.624 3.855A174.254 174.254 0 0 1 173.47 724.28c23.31 40.838 28.911 87.338 18.732 129.802l-4.818 16.444c-7.108 23.129 2.108 54.992 20.6 70.833 0 0 16.623 14.095 63.244 41.2 46.8 27.105 66.918 34.513 66.918 34.513 22.708 8.373 54.632 0.362 71.256-17.407l11.625-12.589a175.097 175.097 0 0 1 242.257 0.12l11.624 12.65c16.384 17.708 48.428 25.599 71.256 17.347 0 0 20.359-7.53 67.16-34.514 46.74-27.105 63.124-41.2 63.124-41.2 18.491-15.6 27.707-47.463 20.6-70.833l-5.06-17.106A176.723 176.723 0 0 1 910.66 724.4a176.06 176.06 0 0 1 102.396-81.314l16.684-3.855c23.31-5.42 46.26-29.333 50.596-53.185 0 0 3.855-21.383 3.855-75.713-0.241-54.33-4.096-75.833-4.096-75.833z m-537.82 293.335c-119.26 0-216.175-97.336-216.175-217.622a216.658 216.658 0 0 1 216.236-217.32c119.2 0 216.115 97.276 216.115 217.561-0.24 120.045-96.974 217.32-216.175 217.32z" p-id="1157"></path></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.921.052H49.08c-1.865 0-3.198 1.599-3.198 3.464v6.661c0 1.865 1.6 3.464 3.198 3.464h29.84c1.865 0 3.198-1.599 3.198-3.464V3.516C82.385 1.65 80.786.052 78.92.052zm45.563 0H94.642c-1.865 0-3.464 1.599-3.464 3.464v6.661c0 1.865 1.599 3.464 3.464 3.464h29.842c1.865-.266 3.464-1.599 3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464zm0 22.382H40.02c-1.866 0-3.464-1.599-3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464H3.516C1.65.052.052 1.651.052 3.516V124.75c0 1.598 1.599 3.197 3.464 3.197h120.968c1.865 0 3.464-1.599 3.464-3.464V25.898c0-1.865-1.599-3.464-3.464-3.464z"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M125.5 36.984L95.336 2.83C93.735 1.018 91.565 0 89.3 0c-2.263 0-4.433 1.018-6.033 2.83l-3.786 4.286c-1.6 1.812-3.77 2.83-6.032 2.831H54.553c-2.263 0-4.434-1.018-6.033-2.83L44.734 2.83C43.134 1.018 40.964 0 38.701 0c-2.263 0-4.434 1.018-6.034 2.83L2.5 36.984C.9 38.796 0 41.254 0 43.815c0 2.562.899 5.02 2.5 6.831L14.565 64.31c2.178 2.468 5.367 3.403 8.33 2.444 1.35-.435 2.709.592 2.709 2.18v49.407c0 5.313 3.84 9.66 8.532 9.66h59.726c4.693 0 8.532-4.347 8.532-9.66V68.934c0-1.59 1.36-2.616 2.71-2.181 2.962.96 6.15.024 8.329-2.444L125.5 50.646c1.6-1.811 2.499-4.269 2.499-6.83 0-2.563-.899-5.02-2.5-6.832z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="2986" t="1546864403462" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M814.502 270.913l30.18-30.18 30.58 30.58 37.825-37.825-86.377-86.378-37.825 37.825 30.58 30.58-30.18 30.18c-66.856-61.301-154.087-100.642-250.374-106.858V66.548h-53.499v72.289c-214.046 13.792-383.407 191.652-383.407 409.199 0 226.533 183.624 410.157 410.157 410.157s410.157-183.624 410.157-410.157c-0.001-106.858-40.892-204.139-107.817-277.123zM529.994 598.26v74.606h-35.666V598.26c-20.724-7.385-35.666-26.958-35.666-50.225 0-23.267 14.942-42.842 35.666-50.225v-235.1h35.666v235.102c20.724 7.383 35.666 26.958 35.666 50.225 0 23.265-14.942 42.839-35.666 50.223z" p-id="2987"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.781" height="200" class="icon" p-id="1270" t="1545876582522" version="1.1" viewBox="0 0 1028 1024"><defs><style type="text/css"/></defs><path d="M20.746854 180.67456c-27.09504 27.136-21.31968 65.35168 0.26624 86.87616 0.86016 0.83968 87.49056 83.57888 209.3056 205.4144 3.13344 3.13344 7.22944 4.66944 11.32544 4.66944s8.192-1.57696 11.32544-4.66944c6.2464-6.2464 6.2464-16.384 0-22.6304-18.37056-18.37056-35.84-35.7376-52.40832-52.18304l50.85184-50.85184c6.2464-6.2464 6.2464-16.384 0-22.6304s-16.384-6.2464-22.6304 0l-50.97472 50.97472c-28.50816-28.16-53.63712-52.736-74.07616-72.66304l115.67104-115.67104c6.2464-6.2464 6.2464-16.384 0-22.6304s-16.384-6.2464-22.6304 0l-116.03968 116.03968c-23.552-22.81472-37.13024-35.77856-37.33504-36.00384-6.7584-6.7584-15.62624-25.76384 0-41.3696l160.01024-160.01024c6.18496-6.26688 22.6304-18.71872 40.67328-0.77824 0.79872 0.90112 81.59232 92.672 204.92288 216.00256 6.2464 6.2464 16.384 6.2464 22.6304 0s6.2464-16.384 0-22.6304c-122.55232-122.53184-202.752-213.6064-204.22656-215.26528-29.81888-29.75744-65.80224-20.82816-86.6304 0l-160.03072 160.01024zM699.392614 772.66944c-6.2464-6.2464-16.384-6.2464-22.6304 0l-50.91328 50.87232c-15.52384-15.70816-31.80544-32.1536-48.96768-49.31584-6.2464-6.2464-16.384-6.2464-22.6304 0s-6.2464 16.384 0 22.6304c118.53824 118.49728 201.3184 207.01184 202.50624 208.2816 10.97728 11.01824 26.0096 17.05984 42.33216 17.05984l0 0c16.7936 0 33.792-6.5536 44.31872-17.12128l159.92832-161.83296c20.13184-20.13184 21.27872-54.272 2.49856-73.1136l-214.58944-214.56896c-6.2464-6.2464-16.384-6.2464-22.6304 0s-6.2464 16.384 0 22.6304l214.58944 214.56896c6.41024 6.41024 5.18144 20.23424-2.51904 27.93472l-159.96928 161.83296c-3.6864 3.70688-12.04224 7.68-21.62688 7.68 0 0 0 0 0 0-5.50912 0-13.37344-1.35168-19.33312-7.33184-0.32768-0.34816-13.7216-14.66368-36.98688-39.0144l116.61312-116.61312c6.2464-6.2464 6.2464-16.384 0-22.6304s-16.384-6.2464-22.6304 0l-116.1216 116.1216c-19.968-20.76672-44.4416-46.01856-72.31488-74.42432l51.07712-51.07712c6.2464-6.20544 6.2464-16.32256 0-22.58944zM4.608614 1018.53184c3.072 3.13344 7.20896 4.79232 11.44832 4.79232 1.536 0 3.072-0.22528 4.56704-0.67584l320-95.3344c2.60096-0.77824 4.89472-2.1504 6.77888-4.05504l546.87744-550.56384c0.77824-0.77824 1.14688-1.76128 1.72032-2.62144l116.98176-117.00224c9.40032-9.44128 14.62272-21.95456 14.62272-35.28704 0-13.312-5.2224-25.82528-14.62272-35.20512l-167.5264-167.48544c-18.82112-18.82112-51.67104-18.82112-70.49216 0l-119.64416 119.64416c-0.77824 0.75776-1.18784 1.76128-1.76128 2.6624l-547.71712 547.7376c-1.80224 1.78176-3.13344 3.97312-3.91168 6.36928l-101.13024 310.8864c-1.86368 5.67296-0.4096 11.83744 3.74784 16.13824zM667.587174 168.67328l33.23904 33.23904-496.7424 498.0736-55.25504-12.53376 518.7584-518.77888zM224.072294 725.31968l499.42528-500.736 77.94688 77.94688-503.93088 497.47968-73.44128 0 0-74.69056zM860.365414 361.472l-519.80288 523.32544-18.47296-64.06144 501.98528-495.57504 36.29056 36.31104zM127.836774 715.48928l64.22528 14.58176 0 85.9136c0 8.82688 7.168 15.99488 15.99488 15.99488l83.968 0 20.29568 70.41024-271.60576 80.93696 87.1424-267.83744zM797.676134 37.72416c6.7584-6.7584 18.49344-6.7584 25.25184 0l167.5264 167.5264c3.35872 3.35872 5.2224 7.84384 5.2224 12.61568 0 4.73088-1.86368 9.25696-5.24288 12.63616l-107.86816 107.90912-192.73728-192.73728 107.86816-107.9296z" p-id="1271"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M44.8 0h79.543C126.78 0 128 1.422 128 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H44.8c-2.438 0-3.657-1.422-3.657-4.267V4.267C41.143 1.422 42.362 0 44.8 0zm22.857 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 80 64 78.578 64 75.733V52.267C64 49.422 65.219 48 67.657 48zm0 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 128 64 126.578 64 123.733v-23.466C64 97.422 65.219 96 67.657 96zM50.286 68.267c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V32h6.4c2.02 0 3.658-1.91 3.658-4.267V4.267C27.429 1.91 25.79 0 23.77 0H3.657C1.637 0 0 1.91 0 4.267v23.466C0 30.09 1.637 32 3.657 32h6.4v80c0 2.356 1.638 4.267 3.657 4.267h36.572c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V68.267h32.915z"/></svg>
\ No newline at end of file
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="1381" t="1545700997954" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M880 512H320V288c0-106.032 85.968-192 192-192s192 85.968 192 192a48 48 0 1 0 96 0c0-159.056-128.944-288-288-288S224 128.944 224 288v224H144a48 48 0 0 0-48 48v416a48 48 0 0 0 48 48h736a48 48 0 0 0 48-48V560a48 48 0 0 0-48-48zM560 786.688V880a48 48 0 1 1-96 0v-93.312c-28.576-16.624-48-47.248-48-82.688a96 96 0 1 1 192 0c0 35.44-19.424 66.064-48 82.688z" p-id="1382"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="2702" t="1561614445035" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#8a8a8a" d="M914.285769 802.889143q0 68.534857-41.691429 108.251429t-110.884571 39.716571l-499.419429 0q-69.12 0-110.884571-39.716571t-41.691429-108.251429q0-30.281143 1.974857-59.172571t7.972571-62.317714 15.140571-62.025143 24.576-55.734857 35.401143-46.299429 48.859429-30.573714 63.707429-11.410286q5.12 0 23.990857 12.288t42.569143 27.428571 61.732571 27.428571 76.288 12.288 76.288-12.288 61.732571-27.428571 42.569143-27.428571 23.990857-12.288q34.889143 0 63.707429 11.410286t48.859429 30.573714 35.401143 46.299429 24.576 55.734857 15.140571 62.025143 7.972571 62.317714 1.974857 59.172571zM731.428626 292.571429q0 90.843429-64.292571 155.136t-155.136 64.292571-155.136-64.292571-64.292571-155.136 64.292571-155.136 155.136-64.292571 155.136 64.292571 64.292571 155.136z" p-id="2703"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="4263" t="1553934943780" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#8a8a8a" d="M512 256s-97.2-4.8-144-96c16.8 113.6 108 192 144 192s127.2-78.8 144-192c-46.8 91.2-144 96-144 96z" p-id="4264"/><path fill="#8a8a8a" d="M928 448C928 218.4 741.6 32 512 32S96 218.4 96 448c0 186.8 122.8 344.4 292.4 397.2-42 35.2-68.4 88-68.4 146.8h64c0-70.8 57.2-128 128-128s128 57.2 128 128h64c0-58.8-26.4-111.6-68.4-146.8 169.6-52.8 292.4-210.4 292.4-397.2z m-416 352c-194.4 0-352-157.6-352-352s157.6-352 352-352 352 157.6 352 352-157.6 352-352 352z" p-id="4265"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="1777" t="1561614261684" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#8a8a8a" d="M963.801169 218.170758a72.850542 72.850542 0 0 0-57.513586-63.903984 1357.959666 1357.959666 0 0 1-185.960594-42.815669A690.80207 690.80207 0 0 1 554.17663 14.317049a76.045741 76.045741 0 0 0-88.826539 0 435.825173 435.825173 0 0 1-167.428438 96.495016 624.341926 624.341926 0 0 1-180.848276 44.732789 67.738223 67.738223 0 0 0-56.874546 63.903984S58.281712 379.847839 58.281712 521.075644c0 255.615937 301.626806 502.924356 452.440208 502.924356s406.42934-174.457877 447.32789-499.090117c10.224637-191.711953 3.195199-306.100085 3.195199-306.100085zM799.567929 415.63407l-315.046642 297.153527a42.815669 42.815669 0 0 1-52.401267 5.112318l-8.307518-7.029438L249.993665 530.022202a42.815669 42.815669 0 0 1 63.903984-58.791666L457.042574 621.404899l283.73369-268.396734a42.815669 42.815669 0 1 1 58.791665 63.903984" p-id="1778"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="4347" t="1544682770180" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path d="M320 128c0-70.656-57.344-128-128-128S64 57.344 64 128s57.344 128 128 128S320 198.656 320 128zM544 192C596.992 192 640 148.992 640 96S596.992 0 544 0 448 43.008 448 96 491.008 192 544 192zM864 64C811.008 64 768 107.008 768 160S811.008 256 864 256 960 212.992 960 160 916.992 64 864 64zM537.088 257.216C460.032 256 372.352 267.904 302.144 330.112 231.872 392.32 240.64 547.712 339.968 589.504c99.392 41.728 121.28 113.92 94.656 203.776C408 883.136 453.44 960 567.04 960 762.88 960 832 776.512 832 570.944 832 347.392 744.128 260.352 537.088 257.216z" p-id="4348"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1572860137475" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1681" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M698.026667 597.333333C701.44 569.173333 704 541.013333 704 512 704 482.986667 701.44 454.826667 698.026667 426.666667L842.24 426.666667C849.066667 453.973333 853.333333 482.56 853.333333 512 853.333333 541.44 849.066667 570.026667 842.24 597.333333M622.506667 834.56C648.106667 787.2 667.733333 736 681.386667 682.666667L807.253333 682.666667C766.293333 753.066667 701.013333 807.68 622.506667 834.56M611.84 597.333333 412.16 597.333333C407.893333 569.173333 405.333333 541.013333 405.333333 512 405.333333 482.986667 407.893333 454.4 412.16 426.666667L611.84 426.666667C615.68 454.4 618.666667 482.986667 618.666667 512 618.666667 541.013333 615.68 569.173333 611.84 597.333333M512 851.626667C476.586667 800.426667 448 743.68 430.506667 682.666667L593.493333 682.666667C576 743.68 547.413333 800.426667 512 851.626667M341.333333 341.333333 216.746667 341.333333C257.28 270.506667 322.986667 215.893333 401.066667 189.44 375.466667 236.8 356.266667 288 341.333333 341.333333M216.746667 682.666667 341.333333 682.666667C356.266667 736 375.466667 787.2 401.066667 834.56 322.986667 807.68 257.28 753.066667 216.746667 682.666667M181.76 597.333333C174.933333 570.026667 170.666667 541.44 170.666667 512 170.666667 482.56 174.933333 453.973333 181.76 426.666667L325.973333 426.666667C322.56 454.826667 320 482.986667 320 512 320 541.013333 322.56 569.173333 325.973333 597.333333M512 171.946667C547.413333 223.146667 576 280.32 593.493333 341.333333L430.506667 341.333333C448 280.32 476.586667 223.146667 512 171.946667M807.253333 341.333333 681.386667 341.333333C667.733333 288 648.106667 236.8 622.506667 189.44 701.013333 216.32 766.293333 270.506667 807.253333 341.333333M512 85.333333C276.053333 85.333333 85.333333 277.333333 85.333333 512 85.333333 747.52 276.48 938.666667 512 938.666667 747.52 938.666667 938.666667 747.52 938.666667 512 938.666667 276.48 747.52 85.333333 512 85.333333Z" p-id="1682" fill="#515151"></path></svg>
\ No newline at end of file
<svg width="128" height="110" xmlns="http://www.w3.org/2000/svg"><path d="M86.635 33.334c1.467 0 2.917.113 4.358.283C87.078 14.392 67.58.111 45.321.111 20.44.111.055 17.987.055 40.687c0 13.104 6.781 23.863 18.115 32.209l-4.527 14.352 15.82-8.364c5.666 1.182 10.207 2.395 15.858 2.395 1.42 0 2.829-.073 4.227-.189-.886-3.19-1.398-6.53-1.398-9.996 0-20.845 16.98-37.76 38.485-37.76zm-24.34-12.936c3.407 0 5.665 2.363 5.665 5.954 0 3.576-2.258 5.97-5.666 5.97-3.392 0-6.795-2.395-6.795-5.97 0-3.591 3.403-5.954 6.795-5.954zM30.616 32.323c-3.393 0-6.818-2.395-6.818-5.971 0-3.591 3.425-5.954 6.818-5.954 3.392 0 5.65 2.363 5.65 5.954 0 3.576-2.258 5.97-5.65 5.97z"/><path d="M127.945 70.52c0-19.075-18.108-34.623-38.448-34.623-21.537 0-38.5 15.548-38.5 34.623 0 19.108 16.963 34.622 38.5 34.622 4.508 0 9.058-1.2 13.584-2.395l12.414 7.167-3.404-11.923c9.087-7.184 15.854-16.712 15.854-27.471zm-50.928-5.97c-2.254 0-4.53-2.362-4.53-4.773 0-2.378 2.276-4.771 4.53-4.771 3.422 0 5.665 2.393 5.665 4.771 0 2.41-2.243 4.773-5.665 4.773zm24.897 0c-2.24 0-4.498-2.362-4.498-4.773 0-2.378 2.258-4.771 4.498-4.771 3.392 0 5.665 2.393 5.665 4.771 0 2.41-2.273 4.773-5.665 4.773z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" class="icon" p-id="2023" t="1564885435527" version="1.1" viewBox="0 0 1024 1024"><defs><style type="text/css"/></defs><path fill="#bfbfbf" d="M1024 659.2c0-147.2-147.2-262.4-307.2-262.4-172.8 0-307.2 115.2-307.2 262.4 0 147.2 134.4 262.4 307.2 262.4 38.4 0 70.4-6.4 108.8-19.2l102.4 51.2L896 870.4C972.8 812.8 1024 742.4 1024 659.2zM614.4 614.4c-19.2 0-38.4-19.2-38.4-38.4 0-19.2 19.2-38.4 38.4-38.4 25.6 0 44.8 19.2 44.8 38.4C659.2 595.2 646.4 614.4 614.4 614.4zM812.8 614.4c-19.2 0-38.4-19.2-38.4-38.4 0-19.2 19.2-38.4 38.4-38.4 25.6 0 44.8 19.2 44.8 38.4C864 595.2 844.8 614.4 812.8 614.4z" p-id="2024"/><path fill="#bfbfbf" d="M364.8 128C166.4 128 0 262.4 0 435.2c0 102.4 51.2 179.2 147.2 243.2l-38.4 108.8 128-64c44.8 6.4 83.2 19.2 128 19.2 12.8 0 25.6 0 32 0C390.4 716.8 384 691.2 384 665.6c0-160 134.4-288 307.2-288 12.8 0 25.6 0 32 0C697.6 236.8 537.6 128 364.8 128zM243.2 371.2C217.6 371.2 192 352 192 326.4c0-25.6 25.6-44.8 57.6-44.8s44.8 19.2 44.8 44.8C288 352 268.8 371.2 243.2 371.2zM499.2 371.2c-25.6 0-57.6-19.2-57.6-44.8 0-25.6 25.6-44.8 57.6-44.8 25.6 0 44.8 19.2 44.8 44.8C544 352 524.8 371.2 499.2 371.2z" p-id="2025"/></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574576020792" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5498" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M64 64h384v384H64V64z m0 512h384v384H64V576z m512 0h384v384H576V576z m192-128c106.039 0 192-85.961 192-192S874.039 64 768 64s-192 85.961-192 192 85.961 192 192 192z" p-id="5499" fill="#bfbfbf"></path></svg>
\ No newline at end of file
# replace default config
# multipass: true
# full: true
plugins:
# - name
#
# or:
# - name: false
# - name: true
#
# or:
# - name:
# param1: 1
# param2: 2
- removeAttrs:
attrs:
- 'fill'
- 'fill-rule'
import Highcharts from 'highcharts';
import HTreemap from 'highcharts/modules/treemap.js';
import Highcharts3D from 'highcharts/highcharts-3d.js';
//import oldie from 'highcharts/oldie.js';
//import cylinder from 'highcharts/cylinder.js';
HTreemap(Highcharts); // treemap 类型
Highcharts3D(Highcharts); // 3D 类型
var Highchart = function(){
/**
* 图表数据格式化
* @param: {Array} list
* @param: {Object} opts [standOut(突出最大值)]
* @example1: qf.UI.showFloatMenu({top:y,left:x, eventOutClose:}, html);
* @return:
* @author: Kimber
* @updatetime: 2021/12/25
* @createtime: 2021/12/25
*/
var formatChartData = function(list, opts){
var sdata = [], sum = 0, maxVal = 0, mark = 0;
var len = list.length;
for(var i=0; i<len; i++){
var item = list[i];
var value = item[opts.value] * 1;
value > maxVal && (maxVal = value, mark = i);
sdata.push({name:item[opts.name], y:value, 'color':item.color || void 0});
sum += value;
};
if(opts.standOut){
sdata[mark].sliced = true;
sdata[mark].selected = true;
};
return {seriesData:sdata, sum:sum};
};
/**
* series数据格式化
* @param: {Array} list
* @param: {Object} opts [standOut(突出最大值)]
* @example1: qf.UI.showFloatMenu({top:y,left:x, eventOutClose:}, html);
* @return:
* @author: Kimber
* @updatetime: 2022/12/28
* @createtime: 2022/12/28
*/
var seriesDataFormat = function(data, opts){
var names = data.names || [], list = data.list || data.lists, series = [], categories = [],
maxVal = 0;
if(names[0] && list){
var colors = ['#8085E9', '#90ED7D', '#F7A35C', '#F15C80', '#E4D354', '#2B908F', '#F45B5B', '#91E8E1', '#0769CB', '#00ABBD', '#ffd886', "#9F2E61", "#4D670C"];
var len = names.length;
for(var i=0; i<len; i++){
var item = names[i];
var serie = {name:item.name, data:[], key:item.key, type:data.chartType, color:colors[i]};
opts && serie.type && (serie.type = opts.type);
series.push(serie);
};
for(var item of list){
var values = item.values;
//var datetime = item[opts.datekey || 'dateUnit'];
//var time = datetime.indexOf(' ') > 0 ? datetime.split(' ')[1] : datetime;
var timestamp = item['date'];
//categories.push(timestamp);
for(var serie of series){
var value = values[serie.key] * 1;
Math.abs(value) > maxVal && (maxVal = Math.abs(value));
serie.data.push([timestamp, value]);
};
};
};
return {series:series, categories:categories, maxVal:maxVal}
};
/**
* 递归继承, 新对象在先, 原对象在后, 节省运行效率
* @param: {Object} inherit // 继承者
* @param: {Object} give // 传承者
* @param: {Function} call // 方法回调, 于在在特殊情况自定义
* @example1: var options = reversExtends(option, opts);
* @return:
* @author: Kimber
* @updatetime: 2022/1/12
* @createtime: 2022/1/12
*/
var reversExtends = function(inherit, give, fn){
return (function run(main, assist){
var keys = Object.keys(assist), i = 0;
return (function loop(){
var key = keys[i]; i++;
if(key){
fn && fn(key, main, assist);
return typeof main[key] === 'object' ? run(main[key], assist[key]) : (main[key] = assist[key]), loop();
}else{
return inherit;
};
})();
})(inherit, give);
};
/**
* 根据报警级别识别近两条报警线
* @param: {Number} level
* @param: {Object} value
* @example1: series = discernValidAlarmValue(data.alarm, data.lists, series);
* @return:
* @author: Kimber
* @updatetime: 2022/4/18(周一)
* @createtime: 2022/4/18(周一)
*/
var discernValidAlarmValue = function(alarms, list, series, direction, opts){
var xLength = (list || []).length, maxAlarm = 0, opts = opts || {};
if(alarms && xLength){
var value = alarms.value;
// discern
var levelDist = [
{color:'red', name:'红色报警线'},
{color:'orange', name:'橙色报警线'},
{color:'yellow', name:'黄色报警线'},
{color:'blue', name:'蓝色报警线'}],
alarmLine = {}, setAlarmSerie = function(value, name, color){
// 修改蓝色色值
(color === 'blue') && (color = '#3BAFFB');
var sx = list[0].date, ex = list[xLength-1].date;
var serie = {name:name, type:'spline', data:[{x:sx, y:value}, {x:ex, y:value}],
color:color,
enableMouseTracking:false,
legend:false,
showInLegend:false,
dashStyle:'ShortDot',
lineWidth:opts.lineWidth || 1,
states:{
inactive:{
opacity:opts.opacity
},
},
dataLabels:{
enabled:opts.valEnabled || false, // 数据值, 2022/11/11(周五) 因多条报警线暂时关闭
//backgroundColor:'red',
verticalAlign:'middle',
padding:0,
defer:false,
allowOverlap:true,
color:color,
style:{
fontSize:'17',
textOutline:'none',
},
},
tooltip:{
//footerFormat:'',
//pointFormat:'',
headerFormat:'',
//nullFormat:'',
},
marker:{
enabled:false
},
zIndex:-10,
};
series.push(serie);
};
/* 智能报警线
var level = (~~alarms.alarmLevel || levelDist.length+1) - 1;
var nearLevel = level ? level - 1 : level;
var alarm = levelDist[level];
var nearAlarm = levelDist[nearLevel];
nearAlarm.value = value[nearAlarm.color];
alarmLine[nearAlarm.color] = nearAlarm;
if(alarm){
alarm.value = value[alarm.color];
alarmLine[alarm.color] = alarm;
}; */
// 多条报警线
for(var item of levelDist){
item.value = value[item.color];
alarmLine[item.color] = item;
};
// add
for(var key in alarmLine){
var line = alarmLine[key];
line.value > maxAlarm && (maxAlarm = line.value);
setAlarmSerie(line.value, line.name, line.color);
direction && setAlarmSerie(0-line.value, line.name, line.color);
};
};
return {series, maxAlarm};
};
var addAlarmLine = function(alarms, list, series, direction){
var xLength = (list || []).length;
if(alarms && xLength){
var value = alarms.value;
// discern
var levelDist = [
{color:'red', name:'红色报警线'},
{color:'orange', name:'橙色报警线'},
{color:'yellow', name:'黄色报警线'},
{color:'blue', name:'蓝色报警线'}],
alarmLine = {}, setAlarmSerie = function(value, name, color){
var serie = {name:name, type:'spline', data:[{x:0, y:value}, {x:xLength, y:value}], color:color,
//enableMouseTracking:false,
legend:false,
showInLegend:false,
dashStyle:'ShortDot',
states:{
inactive:{
opacity:1
},
},
};
series.push(serie);
};
for(var item of levelDist){
var value = alarms[item.color] * 1;
if(value){
setAlarmSerie(value, item.name, item.color);
direction && setAlarmSerie(0-value, item.name, item.color);
};
};
};
return series;
};
var template = {
pie: function(el, data, opts){
var chartData = formatChartData(data, opts);
var seriesData = chartData.seriesData;
return new Highcharts.chart(el, {
chart: {
backgroundColor:'transparent',
//spacing:[0, 0 , 0, 0]
},
title: {
floating:true,
text: '总数<br/>'+chartData.sum,
verticalAlign: 'middle',
y:22,
floating: true,
style:{
color:'#00f6ff',
}
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
borderWidth: 0,
minSize:130,
//size:200,
cursor: 'pointer',
dataLabels: {
enabled: true,
distance:10,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
},
}
},
credits: {
enabled: false
},
series: [{
type: 'pie',
innerSize: '70%',
name: '设备数量',
data: seriesData
}]
}, function(c) { // 图表初始化完毕后的会掉函数
/* // 环形图圆心
var centerY = c.series[0].center[1],
titleHeight = parseInt(c.title.styles.fontSize);
// 动态设置标题位置
c.setTitle({
y:centerY
}); */
});
},
/**
* 浮动菜单容器
* @param: {Dom} el
* @param: {Object} data
* @param: {Object} opts {chartConfig:{}, callback:Function}
* @example1:
* @return:
* @author: Kimber
* @updatetime: 2022/1/11
* @createtime: 2022/1/11
*/
high: function(el, data, opts){
var list = data.list;
data.chartType = data.range === 'month' ? 'line' : 'column';
var chartConfig = opts.chartConfig || {};
var chartData, categories = [], series = [], maxVal = null;
if(opts.isSeriesData){
}else{
chartData = seriesDataFormat(data, {});
categories = chartData.categories;
series = chartData.series;
};
// add alarm line
var alarmData = discernValidAlarmValue(data.alarm, data.lists, series, opts.warningLine);
//series = addAlarmLine(data.alarm, data.lists, series, opts.warningLine);
// 识别最大值
var maxVal = chartData && chartData.maxVal > alarmData.maxAlarm ? chartData.maxVal : alarmData.maxAlarm;
var option = {
chart: {
type: data.chartType,
backgroundColor:'transparent',
//marginTop:30,
marginBottom:22,
marginLeft:30,
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
type: 'datetime' || 'category',
labels: {
rotation:0, // 设置轴标签旋转角度
style:{
color:'#fff'
},
y:15,
},
categories: categories[0] && categories,
lineWidth:0,
//lineColor:'#ff0000',
gridLineColor:'#aaa',
tickLength:0, // 刻度线
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%m-%d',
week: '%m-%d',
month: '%Y-%m',
year: '%Y'
}
},
yAxis: {
title: {
text: ''
},
labels:{
style:{
color:'#fff'
},
x:-6,
},
gridLineColor:'#0F5680',
//minorGridLineWidth: 5,
//gridLineWidth: 5,
max:opts.maxValDev ? maxVal + maxVal * opts.maxValDev : null,
},
plotOptions: {
column: {
borderWidth: 0,
//y:50,
//itemMarginTop:50,
},
bar:{
borderWidth: 0,
},
},
legend: {
enabled: series.length > 1 ? true : false,
// 图例定位
layout: 'horizontal', // 水平布局:“horizontal”, 垂直布局:“vertical”
floating: false, // 图列是否浮动
align: 'right',
// 图例容器
//width:'100%', // number || String
padding:2, // 内边距
margin:2,
borderRadius:5,
//borderWidth:1,
verticalAlign: 'top',
// 图例项
//itemWidth:120, // 宽度
itemDistance:10, // 间距 20
y:-10,
itemMarginTop:2,
itemStyle:{color:'#fff',},
itemHoverStyle:{color:'#fff',},
},
credits: {
enabled: false
},
tooltip: {
/* formatter: function (e) {
return this.series.name + ":"+ this.key +'<br/>'+ this.y.toFixed(3)+' ' + data.unit;
}, */
pointFormat: '{series.name}:{point.y} ' + data.unit,
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%m-%d %H:%M',
hour: '%m-%d %H:%M',
day: '%m-%d %H:%M',
week: '%m-%d %H:%M',
month: '%Y-%m',
year: '%Y'
}
},
series: series
};
Highcharts.setOptions({
global: {
useUTC: false
},
});
var options;
if(opts.isSeriesData){
options = reversExtends(option, chartConfig, opts.callback);
if(opts.type === "t_10"){
delete options.legend;
delete options.xAxis;
delete options.yAxis;
};
}else{
options = reversExtends(option, chartConfig, opts.callback);
};
return new Highcharts.chart(el, options);
},
rich: function(el, data, opts){
var list = data.list;
var chartConfig = opts.chartConfig || {};
var chartData, categories = [], series = [], maxVal = null, unit = data.danwei;
if(opts.isSeriesData){
}else{
chartData = seriesDataFormat(data, {datekey:'date'});
categories = chartData.categories;
series = chartData.series;
};
var warningLine = this.form.config.warningLine;
// add alarm line
var option = {
valEnabled: true,
opacity:1,
lineWidth:3,
};
var alarmData = discernValidAlarmValue(data.alarm, data.lists, series, warningLine, option);
var option = {
chart: {
//type: '',
backgroundColor:'transparent',
//marginTop:30,
//marginBottom:30,
//marginLeft:30,
zoomType: 'x', // xy
},
title: {
text: ''
},
subtitle: {
text: ''
},
tooltip:{
enabled:false,
borderWidth:10,
},
xAxis: {
type: 'datetime',
categories: categories[0] && categories,
lineWidth:0,
//lineColor:'#ff0000',
gridLineColor:'#aaa',
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%m-%d',
week: '%m-%d',
month: '%Y-%m',
year: '%Y'
}
},
yAxis: {
title: {
text: ''
},
labels:{
x:-6,
},
gridLineColor:'#aaa',
max:null,
},
plotOptions: {
column: {
borderWidth: 0,
//y:50,
//itemMarginTop:50,
},
bar:{
borderWidth: 0,
},
},
tooltip: {
// {point.y:.4f} // 保留4位小数
//headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}:</td>' +
'<td style="padding:0"><b>{point.y}'+unit+'</b> </td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true,
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%m-%d %H时',
week: '%m-%d',
month: '%Y-%m',
year: '%Y'
}
},
legend: {
enabled: series.length > 1 ? true : false,
// 图例定位
layout: 'horizontal', // 水平布局:“horizontal”, 垂直布局:“vertical”
floating: false, // 图列是否浮动
align: 'right',
// 图例容器
//width:'100%', // number || String
padding:2, // 内边距
margin:2,
borderRadius:5,
//borderWidth:1,
verticalAlign: 'top',
// 图例项
//itemWidth:120, // 宽度
itemDistance:10, // 间距 20
y:-10,
itemMarginTop:2,
itemStyle:{},
itemHoverStyle:{},
},
credits: {
enabled: false
},
series: series
};
Highcharts.setOptions({
global: {
useUTC: false
},
lang:{
resetZoom:'重置缩放比例',
},
});
var options;
if(opts.isSeriesData){
options = reversExtends(option, chartConfig, opts.callback);
if(opts.type === "t_10"){
delete options.legend;
delete options.xAxis;
delete options.yAxis;
};
}else{
options = reversExtends(option, chartConfig, opts.callback);
};
return new Highcharts.chart(el, options);
},
};
var getRandomColor = function(random){
if(random === true){
return 'rgb(' + [Math.round(Math.random() * 160), Math.round(Math.random() * 160), Math.round(Math.random() * 160)].join(',') + ')';
}else{
var colors = ['#7CB5EC', '#434348', '#90ED7D', '#F7A35C', '#8085E9', '#F15C80', '#E4D354', '#2B908F', '#F45B5B', '#91E8E1', '#0769CB', '#00ABBD', '#ffd886', "#9F2E61", "#4D670C"];
if(typeof random === 'number'){
return colors[~~random];
}else{
return colors[~~(Math.random()*colors.length)];
};
};
};
return {
template:template, getRandomColor:getRandomColor
}
};
export var Highchart = Highchart();
import Highcharts from 'highcharts';
import HTreemap from 'highcharts/modules/treemap.js';
import Highcharts3D from 'highcharts/highcharts-3d.js';
//import oldie from 'highcharts/oldie.js';
//import cylinder from 'highcharts/cylinder.js';
HTreemap(Highcharts); // treemap 类型
Highcharts3D(Highcharts); // 3D 类型
var Highchart = function(){
/**
* 图表数据格式化
* @param: {Array} list
* @param: {Object} opts [standOut(突出最大值)]
* @example1: qf.UI.showFloatMenu({top:y,left:x, eventOutClose:}, html);
* @return:
* @author: Kimber
* @updatetime: 2021/12/25
* @createtime: 2021/12/25
*/
var formatChartData = function(list, opts){
var sdata = [], sum = 0, maxVal = 0, mark = 0;
var len = list.length;
for(var i=0; i<len; i++){
var item = list[i];
var value = item[opts.value] * 1;
value > maxVal && (maxVal = value, mark = i);
sdata.push({name:item[opts.name], y:value, 'color':item.color || void 0});
sum += value;
};
if(opts.standOut){
sdata[mark].sliced = true;
sdata[mark].selected = true;
};
return {seriesData:sdata, sum:sum};
};
/**
* series数据格式化
* @param: {Array} list
* @param: {Object} opts [standOut(突出最大值)]
* @example1: qf.UI.showFloatMenu({top:y,left:x, eventOutClose:}, html);
* @return:
* @author: Kimber
* @updatetime: 2022/12/28
* @createtime: 2022/12/28
*/
var seriesDataFormat = function(data, opts){
var names = data.names || [], list = data.list || data.lists, series = [], categories = [],
maxVal = 0;
if(names[0] && list){
var colors = ['#8085E9', '#90ED7D', '#F7A35C', '#F15C80', '#E4D354', '#2B908F', '#F45B5B', '#91E8E1', '#0769CB', '#00ABBD', '#ffd886', "#9F2E61", "#4D670C"];
var len = names.length;
for(var i=0; i<len; i++){
var item = names[i];
var serie = {name:item.name, data:[], key:item.key, type:data.chartType, color:colors[i]};
opts && serie.type && (serie.type = opts.type);
series.push(serie);
};
for(var item of list){
var values = item.values;
//var datetime = item[opts.datekey || 'dateUnit'];
//var time = datetime.indexOf(' ') > 0 ? datetime.split(' ')[1] : datetime;
var timestamp = item['date'];
//categories.push(timestamp);
for(var serie of series){
var value = values[serie.key] * 1;
Math.abs(value) > maxVal && (maxVal = Math.abs(value));
serie.data.push([timestamp, value]);
};
};
};
return {series:series, categories:categories, maxVal:maxVal}
};
/**
* 递归继承, 新对象在先, 原对象在后, 节省运行效率
* @param: {Object} inherit // 继承者
* @param: {Object} give // 传承者
* @param: {Function} call // 方法回调, 于在在特殊情况自定义
* @example1: var options = reversExtends(option, opts);
* @return:
* @author: Kimber
* @updatetime: 2022/1/12
* @createtime: 2022/1/12
*/
var reversExtends = function(inherit, give, fn){
return (function run(main, assist){
var keys = Object.keys(assist), i = 0;
return (function loop(){
var key = keys[i]; i++;
if(key){
fn && fn(key, main, assist);
return typeof main[key] === 'object' ? run(main[key], assist[key]) : (main[key] = assist[key]), loop();
}else{
return inherit;
};
})();
})(inherit, give);
};
/**
* 根据报警级别识别近两条报警线
* @param: {Number} level
* @param: {Object} value
* @example1: series = discernValidAlarmValue(data.alarm, data.lists, series);
* @return:
* @author: Kimber
* @updatetime: 2022/4/18(周一)
* @createtime: 2022/4/18(周一)
*/
var discernValidAlarmValue = function(alarms, list, series, direction, opts){
var xLength = (list || []).length, maxAlarm = 0, opts = opts || {};
if(alarms && xLength){
var value = alarms.value;
// discern
var levelDist = [
{color:'red', name:'红色报警线'},
{color:'orange', name:'橙色报警线'},
{color:'yellow', name:'黄色报警线'},
{color:'blue', name:'蓝色报警线'}],
alarmLine = {}, setAlarmSerie = function(value, name, color){
// 修改蓝色色值
(color === 'blue') && (color = '#3BAFFB');
var sx = list[0].date, ex = list[xLength-1].date;
var serie = {name:name, type:'spline', data:[{x:sx, y:value}, {x:ex, y:value}],
color:color,
enableMouseTracking:false,
legend:false,
showInLegend:false,
dashStyle:'ShortDot',
lineWidth:opts.lineWidth || 1,
states:{
inactive:{
opacity:opts.opacity
},
},
dataLabels:{
enabled:opts.valEnabled || false, // 数据值, 2022/11/11(周五) 因多条报警线暂时关闭
//backgroundColor:'red',
verticalAlign:'middle',
padding:0,
defer:false,
allowOverlap:true,
color:color,
style:{
fontSize:'17',
textOutline:'none',
},
},
tooltip:{
//footerFormat:'',
//pointFormat:'',
headerFormat:'',
//nullFormat:'',
},
marker:{
enabled:false
},
zIndex:-10,
};
series.push(serie);
};
/* 智能报警线
var level = (~~alarms.alarmLevel || levelDist.length+1) - 1;
var nearLevel = level ? level - 1 : level;
var alarm = levelDist[level];
var nearAlarm = levelDist[nearLevel];
nearAlarm.value = value[nearAlarm.color];
alarmLine[nearAlarm.color] = nearAlarm;
if(alarm){
alarm.value = value[alarm.color];
alarmLine[alarm.color] = alarm;
}; */
// 多条报警线
for(var item of levelDist){
item.value = value[item.color];
alarmLine[item.color] = item;
};
// add
for(var key in alarmLine){
var line = alarmLine[key];
line.value > maxAlarm && (maxAlarm = line.value);
setAlarmSerie(line.value, line.name, line.color);
direction && setAlarmSerie(0-line.value, line.name, line.color);
};
};
return {series, maxAlarm};
};
var addAlarmLine = function(alarms, list, series, direction){
var xLength = (list || []).length;
if(alarms && xLength){
var value = alarms.value;
// discern
var levelDist = [
{color:'red', name:'红色报警线'},
{color:'orange', name:'橙色报警线'},
{color:'yellow', name:'黄色报警线'},
{color:'blue', name:'蓝色报警线'}],
alarmLine = {}, setAlarmSerie = function(value, name, color){
var serie = {name:name, type:'spline', data:[{x:0, y:value}, {x:xLength, y:value}], color:color,
//enableMouseTracking:false,
legend:false,
showInLegend:false,
dashStyle:'ShortDot',
states:{
inactive:{
opacity:1
},
},
};
series.push(serie);
};
for(var item of levelDist){
var value = alarms[item.color] * 1;
if(value){
setAlarmSerie(value, item.name, item.color);
direction && setAlarmSerie(0-value, item.name, item.color);
};
};
};
return series;
};
var template = {
pie: function(el, data, opts){
var chartData = formatChartData(data, opts);
var seriesData = chartData.seriesData;
return new Highcharts.chart(el, {
chart: {
backgroundColor:'transparent',
//spacing:[0, 0 , 0, 0]
},
title: {
floating:true,
text: '总数<br/>'+chartData.sum,
verticalAlign: 'middle',
y:22,
floating: true,
style:{
color:'#00f6ff',
}
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
borderWidth: 0,
minSize:130,
//size:200,
cursor: 'pointer',
dataLabels: {
enabled: true,
distance:10,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
},
}
},
credits: {
enabled: false
},
series: [{
type: 'pie',
innerSize: '70%',
name: '设备数量',
data: seriesData
}]
}, function(c) { // 图表初始化完毕后的会掉函数
/* // 环形图圆心
var centerY = c.series[0].center[1],
titleHeight = parseInt(c.title.styles.fontSize);
// 动态设置标题位置
c.setTitle({
y:centerY
}); */
});
},
/**
* 浮动菜单容器
* @param: {Dom} el
* @param: {Object} data
* @param: {Object} opts {chartConfig:{}, callback:Function}
* @example1:
* @return:
* @author: Kimber
* @updatetime: 2022/1/11
* @createtime: 2022/1/11
*/
high: function(el, data, opts){
var list = data.list;
data.chartType = data.range === 'month' ? 'line' : 'column';
var chartConfig = opts.chartConfig || {};
var chartData, categories = [], series = [], maxVal = null;
if(opts.isSeriesData){
}else{
chartData = seriesDataFormat(data, {});
categories = chartData.categories;
series = chartData.series;
};
// add alarm line
var alarmData = discernValidAlarmValue(data.alarm, data.lists, series, opts.warningLine);
//series = addAlarmLine(data.alarm, data.lists, series, opts.warningLine);
// 识别最大值
var maxVal = chartData && chartData.maxVal > alarmData.maxAlarm ? chartData.maxVal : alarmData.maxAlarm;
var option = {
chart: {
type: data.chartType,
backgroundColor:'transparent',
//marginTop:30,
marginBottom:22,
marginLeft:30,
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
type: 'datetime' || 'category',
labels: {
rotation:0, // 设置轴标签旋转角度
style:{
color:'#fff'
},
y:15,
},
categories: categories[0] && categories,
lineWidth:0,
//lineColor:'#ff0000',
gridLineColor:'#aaa',
tickLength:0, // 刻度线
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%m-%d',
week: '%m-%d',
month: '%Y-%m',
year: '%Y'
}
},
yAxis: {
title: {
text: ''
},
labels:{
style:{
color:'#fff'
},
x:-6,
},
gridLineColor:'#0F5680',
//minorGridLineWidth: 5,
//gridLineWidth: 5,
max:opts.maxValDev ? maxVal + maxVal * opts.maxValDev : null,
},
plotOptions: {
column: {
borderWidth: 0,
//y:50,
//itemMarginTop:50,
},
bar:{
borderWidth: 0,
},
},
legend: {
enabled: series.length > 1 ? true : false,
// 图例定位
layout: 'horizontal', // 水平布局:“horizontal”, 垂直布局:“vertical”
floating: false, // 图列是否浮动
align: 'right',
// 图例容器
//width:'100%', // number || String
padding:2, // 内边距
margin:2,
borderRadius:5,
//borderWidth:1,
verticalAlign: 'top',
// 图例项
//itemWidth:120, // 宽度
itemDistance:10, // 间距 20
y:-10,
itemMarginTop:2,
itemStyle:{color:'#fff',},
itemHoverStyle:{color:'#fff',},
},
credits: {
enabled: false
},
tooltip: {
/* formatter: function (e) {
return this.series.name + ":"+ this.key +'<br/>'+ this.y.toFixed(3)+' ' + data.unit;
}, */
pointFormat: '{series.name}:{point.y} ' + data.unit,
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%m-%d %H:%M',
hour: '%m-%d %H:%M',
day: '%m-%d %H:%M',
week: '%m-%d %H:%M',
month: '%Y-%m',
year: '%Y'
}
},
series: series
};
Highcharts.setOptions({
global: {
useUTC: false
},
});
var options;
if(opts.isSeriesData){
options = reversExtends(option, chartConfig, opts.callback);
if(opts.type === "t_10"){
delete options.legend;
delete options.xAxis;
delete options.yAxis;
};
}else{
options = reversExtends(option, chartConfig, opts.callback);
};
return new Highcharts.chart(el, options);
},
rich: function(el, data, opts){
var list = data.list;
var chartConfig = opts.chartConfig || {};
var chartData, categories = [], series = [], maxVal = null, unit = data.danwei;
if(opts.isSeriesData){
}else{
chartData = seriesDataFormat(data, {datekey:'date'});
categories = chartData.categories;
series = chartData.series;
};
var warningLine = this.form.config.warningLine;
// add alarm line
var option = {
valEnabled: true,
opacity:1,
lineWidth:3,
};
var alarmData = discernValidAlarmValue(data.alarm, data.lists, series, warningLine, option);
var option = {
chart: {
//type: '',
backgroundColor:'transparent',
//marginTop:30,
//marginBottom:30,
//marginLeft:30,
zoomType: 'x', // xy
},
title: {
text: ''
},
subtitle: {
text: ''
},
tooltip:{
enabled:false,
borderWidth:10,
},
xAxis: {
type: 'datetime',
categories: categories[0] && categories,
lineWidth:0,
//lineColor:'#ff0000',
gridLineColor:'#aaa',
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%m-%d',
week: '%m-%d',
month: '%Y-%m',
year: '%Y'
}
},
yAxis: {
title: {
text: ''
},
labels:{
x:-6,
},
gridLineColor:'#aaa',
max:null,
},
plotOptions: {
column: {
borderWidth: 0,
//y:50,
//itemMarginTop:50,
},
bar:{
borderWidth: 0,
},
},
tooltip: {
// {point.y:.4f} // 保留4位小数
//headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}:</td>' +
'<td style="padding:0"><b>{point.y}'+unit+'</b> </td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true,
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%m-%d %H时',
week: '%m-%d',
month: '%Y-%m',
year: '%Y'
}
},
legend: {
enabled: series.length > 1 ? true : false,
// 图例定位
layout: 'horizontal', // 水平布局:“horizontal”, 垂直布局:“vertical”
floating: false, // 图列是否浮动
align: 'right',
// 图例容器
//width:'100%', // number || String
padding:2, // 内边距
margin:2,
borderRadius:5,
//borderWidth:1,
verticalAlign: 'top',
// 图例项
//itemWidth:120, // 宽度
itemDistance:10, // 间距 20
y:-10,
itemMarginTop:2,
itemStyle:{},
itemHoverStyle:{},
},
credits: {
enabled: false
},
series: series
};
Highcharts.setOptions({
global: {
useUTC: false
},
lang:{
resetZoom:'重置缩放比例',
},
});
var options;
if(opts.isSeriesData){
options = reversExtends(option, chartConfig, opts.callback);
if(opts.type === "t_10"){
delete options.legend;
delete options.xAxis;
delete options.yAxis;
};
}else{
options = reversExtends(option, chartConfig, opts.callback);
};
return new Highcharts.chart(el, options);
},
};
var getRandomColor = function(random){
if(random === true){
return 'rgb(' + [Math.round(Math.random() * 160), Math.round(Math.random() * 160), Math.round(Math.random() * 160)].join(',') + ')';
}else{
var colors = ['#7CB5EC', '#434348', '#90ED7D', '#F7A35C', '#8085E9', '#F15C80', '#E4D354', '#2B908F', '#F45B5B', '#91E8E1', '#0769CB', '#00ABBD', '#ffd886', "#9F2E61", "#4D670C"];
if(typeof random === 'number'){
return colors[~~random];
}else{
return colors[~~(Math.random()*colors.length)];
};
};
};
return {
template:template, getRandomColor:getRandomColor
}
};
export var Highchart = Highchart();
var Tools = function(){
/**
* 计时组件封装
* @param: {Object}
* @example1: var timerA = new Tools.timerLoop(3000, 'timerA');
timerA(function(){});
timerA.stop();
timerA.start();
timerA.setTime();
timerA.clear();
* @return:
* @author: Kimber
* @createtime: 2021/10/28
*/
var timerLoop = function(timer, name){
var defaultTiem = 5000;
var Cache = {timer:timer || defaultTiem, name:name};
var layer = function(timer){
Cache.timer = timer;
Cache.layer = this;
this.start = () => {
clearTimeout(Cache.timerPointer);
Cache.timerPointer = setInterval(Cache.fn.bind(this), Cache.timer);
};
var interval = function(fn, timer, name){
if(typeof fn === 'function'){
Cache.name = name;
timer && (Cache.timer = timer);
Cache.fn = fn;
Cache.layer.start()
};
};
interval.__proto__ = this.__proto__;
return interval
}; layer.prototype = {
stop: function(){
clearInterval(Cache.timerPointer);
},
start: function(){
Cache.fn && Cache.layer.start()
},
setTime: function(timer){
timer && (Cache.timer = timer);
Cache.fn && Cache.layer.start()
},
clear: function(){
clearInterval(Cache.timerPointer);
Cache = {timer:defaultTiem};
},
};
return new layer(timer)
};
// 日期时间工具
var Dates = function(){
/*
Tools.Dates.format('yyyy-MM-dd EE HH:mm:ss')
Dates.format.call(new Date(), 'yyyy-MM-dd EE HH:mm:ss')
*/
var format = function(fmt){
var Date_ = this.getDate ? this : new Date();
var o = {
"M+" : Date_.getMonth()+1, //月份
"d+" : Date_.getDate(), //日
"h+" : Date_.getHours()%12 == 0 ? 12 : Date_.getHours()%12, //小时
"H+" : Date_.getHours(), //小时
"m+" : Date_.getMinutes(), //分
"s+" : Date_.getSeconds(), //秒
"q+" : Math.floor((Date_.getMonth()+3)/3), //季度
"S" : Date_.getMilliseconds() //毫秒
};
var week = {
"0" : "\u65e5",
"1" : "\u4e00",
"2" : "\u4e8c",
"3" : "\u4e09",
"4" : "\u56db",
"5" : "\u4e94",
"6" : "\u516d"
};
if(/(y+)/.test(fmt)){
fmt=fmt.replace(RegExp.$1, (Date_.getFullYear()+"").substr(4 - RegExp.$1.length));
}
if(/(E+)/.test(fmt)){
fmt=fmt.replace(RegExp.$1, ((RegExp.$1.length>1) ? (RegExp.$1.length>2 ? "\u661f\u671f" : "\u5468") : "")+week[Date_.getDay()+""]);
}
for(var 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;
}
var getDayStamp = function(){
var start = new Date(new Date().toLocaleDateString()).getTime() / 1000;
var end = ~~(new Date().getTime() / 1000);
return {start:start, end:end};
}
return {format:format, getDayStamp:getDayStamp,}
};
/**
* 异步遍历
* @param: {Object || Array} param
* @param: {Function} fn
* @example1: var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value().then(function(res){
selectList[key] = res;
next();
})
}else{
next();
};
}, function(){});
* @example1: Tools.asyncLoop.call(this, [{name:'123'}, {name:'234'}], function(key, value, next){
var reqItem = value;
reqApi.getItem(reqItem.param).then((res) => {
if(res && res.stat){
next();
};
});
}, function(){});
* @author: Kimber
* @updatetime: 2021/12/10(周五)
* @createtime: 2021/12/10(周五)
*/
var asyncLoop = function(param, fn, end){
var list = typeof param === 'object' ? Object.keys(param) : param || [], len = list.length;
!function loop(i){
(i < len) ? (()=>{
var key = list[i];
var item = param[key];
fn && fn.call(this,key, item, ()=>{
loop.call(this, ++i);
});
})() : (()=>{end&&end.call(this)})();
}.bind(this)(0);
};
/**
* checkbox列表渲染
* @param: {Object} opts
* @example1: var result = {}; // 域外变量或常量
Tools.checkbox({
vue:self || this,
el:document.getElementById("checkctn2222") || checkctn2222,
list:[{name:'测试1', value:'a001'}, {name:'测试2', value:'a002'}],
select:['a001', 'a002'],
result:result || {}, // 用于外部记录
change: function(val){},
});
* @return:
* @author: Kimber
* @updatetime: 2022/1/22
* @createtime: 2022/1/22
*/
var checkbox = function(opts){
var that = opts.vue;
if(that && that.$root){
var Vue = that.$root.constructor, result = opts.result || {};result.items = {};
var selBox = new Vue({
el: opts.el,
name: 'checkbox',
data:opts.data,
props: ['value2'],
render: function(h){
var self = this;
return h('div', {
'class': {'checkboxctn': true,},
}, [h('ul', {}, (opts.list || []).map(function (item, index) {
var checked = opts.select && opts.select.indexOf(item.value) > -1;
checked && (result.items[item.value] = item.name);
result.values = Object.keys(result.items);
return h('li', {
}, [h('el-checkbox', {
props:['test'],data:{},
domProps:{value:item.value,index:index,},
attrs:{checked:checked,},
on:{
'change': function (val, e) {
var tag = e.target || e.srcElement;
var lable = tag.labels[0];
if(val){
result.items[lable.value] = item.name;
}else{
delete result.items[lable.value]
};
result.values = Object.keys(result.items);
opts.change && opts.change(result.values, result.items);
},
},
scopedSlots: {
default: function (a,b,c) {
return h('span', item.name)
}
},
children:[],
}, true)]);
}))]);
}
});
}else{
console.log(new Error('vue must is a vue Object'))
};
};
// 单窗口无缝滚动
var singleViewSeamlessScroll = function(el, opts){
el = typeof el === "string" ? document.getElementById(el) : el;
if(!el) return console.log('%c sliderPlate Error Element is a invalid param! ', 'color:red');
var Widget = function(unitEl){
var scroll = unitEl.firstElementChild.firstElementChild, pointer = 0;
var list = this.list = scroll.children;
var listnum = this.listnum = list.length;
var firstEl = list[pointer];
firstEl.className = 'is-animating scroll-in';
var timerA = new timerLoop(5000, 'timerA');
(listnum > 1) && timerA(function(){
var index = pointer, newi = ++pointer, pi = index ? index -1 : listnum-1;
pointer = newi % (listnum);
var target = list[index];
var previous = list[pi];
var next = list[pointer];
if(previous && previous.classList.contains('is-animating')){
previous.classList.remove('scroll-in');
previous.classList.add('scroll-out');
(function(a){
setTimeout(() => {
a.className = '';
}, 800)
})(previous);
};
target.classList.add('scroll-in');
setTimeout(() => {
next.classList.add('is-animating');
}, 1000)
});
}; Widget.prototype = {
update: function(){},
};return new Widget(el);
};
// 数组对象转对象(用于格式化Dict)
var arrayJsonToJson = function(arr, key, value){
var json = {};
if(arr[0] && arr.push){
for(var item of arr){
json[item[value || 'value']] = item[key || 'name'];
};
};return json;
};
// 利用 canvas 将 File 的 blob stream 转为 base64
var canvasTobase64 = function(img, w, h){
// canvas
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'transparent';
ctx.fillRect(0, 0, w, h);
ctx.drawImage(img, 0, 0, w, h);
// 生成结果
var results = {};
results.base64 = canvas.toDataURL('image/jpeg', 0.7);
results.base64Len = results.base64.length;
canvas = null; // 释放内存
return results;
};
var blobStreamToBase64 = function(blob, fn){
var img = new Image();
img.src = blob;
img.crossOrigin = "*";
img.onerror = function() {
var error = new Error('图片加载失败');
};
img.onload = function(){
var w = img.width, h = img.height;
return fn(canvasTobase64(img, w, h), img = null);
//var verify = fn(img); // 自定义验证
// 重设比例
//that.setCoordRatio();
}
};
/**
* 图片转 base64
* @param: {Element} el
* @param: {Function} fn
* @example1: Tools.fileElTobase64(tag, function(res){});
* @example2: Tools.fileElTobase64(tag).then(function(res){}).catch(function(err){});
* @return:
*/
var fileElTobase64 = function(el, fn, opts){
var file = el && el.files[0];
return new Promise((resolve, reject) => {
if(file.name.indexOf(".jpg") > 0 || file.name.indexOf(".png") > 0){
var blob = (typeof file === 'string') ? file : URL.createObjectURL(file);
blobStreamToBase64(blob, function(res){
return res.base64Len ? fn && fn(res) || resolve(res) : reject(res);
});
}else{
el.value = '';
return reject({type:4, msg:'图片文件类型不正确!'})
}
})
};
// 创建选择列表绑定事件
var createOnSelect = function(dom, arr, opts){
var len = arr.length, optionText = '';
for(var i=0; i<len; i++){
var item = arr[i];
optionText += '<option value="'+item[opts.value || 'value']+'" data-index="'+i+'">'+item[opts.name || 'name']+'</option>';
};
opts.fn && (dom.onchange = function(e){
var tag = e.target || e.srcElement;
var option = tag.selectedOptions[0];
opts.fn(option.value, option);
});
return dom.innerHTML = optionText, opts.onload && opts.onload(dom.options[0] && dom.options[0].value), dom;
};
var cuPrint = function(dom, options){
var Print = function () {
if (!(this instanceof Print)) return new Print(dom, options);
this.options = this.extend({
'noPrint': '.no-print'
}, options);
if ((typeof dom) === "string") {
this.dom = document.querySelector(dom);
} else {
this.isDOM(dom)
this.dom = this.isDOM(dom) ? dom : dom.$el;
}
this.init();
};
Print.prototype = {
init: function () {
var content = this.getStyle() + this.getHtml();
this.writeIframe(content);
},
extend: function (obj, obj2) {
for (var k in obj2) {
obj[k] = obj2[k];
}
return obj;
},
getStyle: function () {
var str = "",
styles = document.querySelectorAll('style,link');
for (var i = 0; i < styles.length; i++) {
str += styles[i].outerHTML;
}
str += "<style>" + (this.options.noPrint ? this.options.noPrint : '.no-print') + "{display:none;}</style>";
return str;
},
getHtml: function () {
var inputs = document.querySelectorAll('input');
var textareas = document.querySelectorAll('textarea');
var selects = document.querySelectorAll('select');
for (var k = 0; k < inputs.length; k++) {
if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {
if (inputs[k].checked == true) {
inputs[k].setAttribute('checked', "checked")
} else {
inputs[k].removeAttribute('checked')
}
} else if (inputs[k].type == "text") {
inputs[k].setAttribute('value', inputs[k].value)
} else {
inputs[k].setAttribute('value', inputs[k].value)
}
}
for (var k2 = 0; k2 < textareas.length; k2++) {
if (textareas[k2].type == 'textarea') {
textareas[k2].innerHTML = textareas[k2].value
}
}
for (var k3 = 0; k3 < selects.length; k3++) {
if (selects[k3].type == 'select-one') {
var child = selects[k3].children;
for (var i in child) {
if (child[i].tagName == 'OPTION') {
if (child[i].selected == true) {
child[i].setAttribute('selected', "selected")
} else {
child[i].removeAttribute('selected')
}
}
}
}
}
// 包裹要打印的元素
// fix: https://github.com/xyl66/vuePlugs_printjs/issues/36
let outerHTML = this.wrapperRefDom(this.dom).outerHTML
return outerHTML;
},
// 向父级元素循环,包裹当前需要打印的元素
// 防止根级别开头的 css 选择器不生效
wrapperRefDom: function (refDom) {
let prevDom = null
let currDom = refDom
// 判断当前元素是否在 body 中,不在文档中则直接返回该节点
if (!this.isInBody(currDom)) return currDom
while (currDom) {
if (prevDom) {
let element = currDom.cloneNode(false)
element.appendChild(prevDom)
prevDom = element
} else {
prevDom = currDom.cloneNode(true)
}
currDom = currDom.parentElement
}
return prevDom
},
writeIframe: function (content) {
var w, doc, iframe = document.createElement('iframe'),
f = document.body.appendChild(iframe);
iframe.id = "myIframe";
//iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";
iframe.setAttribute('style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;');
w = f.contentWindow || f.contentDocument;
doc = f.contentDocument || f.contentWindow.document;
doc.open();
doc.write(content);
doc.close();
var _this = this
iframe.onload = function(){
_this.toPrint(w);
setTimeout(function () {
document.body.removeChild(iframe)
}, 100)
}
},
toPrint: function (frameWindow) {
try {
setTimeout(function () {
frameWindow.focus();
try {
if (!frameWindow.document.execCommand('print', false, null)) {
frameWindow.print();
}
} catch (e) {
frameWindow.print();
}
frameWindow.close();
}, 10);
} catch (err) {
console.log('err', err);
}
},
// 检查一个元素是否是 body 元素的后代元素且非 body 元素本身
isInBody: function (node) {
return (node === document.body) ? false : document.body.contains(node);
},
isDOM: (typeof HTMLElement === 'object') ?
function (obj) {
return obj instanceof HTMLElement;
} :
function (obj) {
return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
}
};
Print();
};
var downloadFile = function(obj, name, suffix){
var url = window.URL.createObjectURL(new Blob([obj]));
var link = document.createElement('a');
link.style.display = 'none';
link.href = url;
var fileName = name + '.' + suffix;
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
return {
timerLoop:timerLoop, Dates:Dates(), arrayJsonToJson,
asyncLoop, checkbox, singleViewSeamlessScroll, fileElTobase64,
createOnSelect, cuPrint, downloadFile,
}
};
/**
* 文件下载
* @return: Object
* @author: Kimber
* @updatetime: 2021/7/20
* @createtime: 2021/7/20
*/
var FileStream = function(){
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
};
/**
* 字符转换 Blob 对象
* @param: {String} str
* @example1: var aaa = FileStream.toBlob(str);
* @return:
* @author: Kimber
* @updatetime: 2021/7/20
* @createtime: 2021/7/20
*/
var toBlob = function(str){
return new Blob([s2ab(str)], {
type: "application/octet-stream"
});
};
/**
* 利用 A标签 下载文件
* @param: {Blob} url
* @param: {String} saveName // 文件名
* @example1: FileStream.download(blob, 'Test.xlsx');
* @return:
* @author: Kimber
* @updatetime: 2021/7/20
* @createtime: 2021/7/20
*/
var download = function(url, saveName){
if (typeof url == 'object' && url instanceof Blob) {
url = URL.createObjectURL(url); // 创建blob地址
}
var aLink = document.createElement('a');
aLink.href = url;
aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
var event;
if (window.MouseEvent) event = new MouseEvent('click');
else {
event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
}
aLink.dispatchEvent(event);
};
return {toBlob:toBlob, download:download}
};
export var Tools = Tools();
export var FileStream = FileStream();
/* exports = {
HttpReq: HttpReq(),
Dates: Dates(),
Tools: Tools(),
}; */
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
@import 'variables';
@mixin colorBtn($color) {
background: $color;
&:hover {
color: $color;
&:before,
&:after {
background: $color;
}
}
}
.blue-btn {
@include colorBtn($blue)
}
.light-blue-btn {
@include colorBtn($light-blue)
}
.red-btn {
@include colorBtn($red)
}
.pink-btn {
@include colorBtn($pink)
}
.green-btn {
@include colorBtn($green)
}
.tiffany-btn {
@include colorBtn($tiffany)
}
.yellow-btn {
@include colorBtn($yellow)
}
.pan-btn {
font-size: 14px;
color: #fff;
padding: 14px 36px;
border-radius: 8px;
border: none;
outline: none;
transition: 600ms ease all;
position: relative;
display: inline-block;
&:hover {
background: #fff;
&:before,
&:after {
width: 100%;
transition: 600ms ease all;
}
}
&:before,
&:after {
content: '';
position: absolute;
top: 0;
right: 0;
height: 2px;
width: 0;
transition: 400ms ease all;
}
&::after {
right: inherit;
top: inherit;
left: 0;
bottom: 0;
}
}
.custom-button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
color: #fff;
-webkit-appearance: none;
text-align: center;
box-sizing: border-box;
outline: 0;
margin: 0;
padding: 10px 15px;
font-size: 14px;
border-radius: 4px;
}
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td{margin:0px;padding:0px}
li{list-style:none;}
body{overflow:hidden;}
.body1X, .body2X{display:none;}
.kmb-message-box{position:relative;display:inline-block;padding-bottom:10px;vertical-align:middle;background-color:#fff;border-radius:4px;border:1px solid #e6ebf5;font-size:18px;box-shadow:0 2px 12px 0 rgb(0 0 0 / 10%);text-align:left;overflow:hidden;backface-visibility:hidden;}
.cm-layout{height:100%;width:100%;}
.cm-layout.flex-col{display:flex;flex-direction:column;}
.cm-layout .colf{color:#fff;}
.cm-layout .font18{font-size:.18rem;}
.cm-layout .font20{font-size:.20rem;}
.cm-layout .font22{font-size:.22rem;}
.cm-layout .font24{font-size:.24rem;}
.cm-layout .font26{font-size:.26rem;}
.cm-layout .font28{font-size:.28rem;}
.cm-layout .ft16{font-size:16px;}
.cm-layout .ft18{font-size:18px;}
.cm-layout .ft20{font-size:20px;}
.cm-layout .ft24{font-size:24px;}
.cm-layout .between{display:flex;justify-content:space-between;}
.cm-layout .ctn-place, .cm-layout .ctn-fix{display:flex;}
.cm-layout .ctn-place>div, .cm-layout .ctn-fix>div{flex:1;position:relative;}
.cm-layout .fix-m1{display:flex;}
.cm-layout .flex1{flex:1;}
.cm-layout .fix-rc{justify-content:center;}
.cm-layout .fix-cc{align-items:center;}
.cm-layout .fix-rcc{align-items:center;justify-content:center;}
.cm-layout .grid2{display:grid;grid-template-columns:50% 50%;}
.cm-layout .grid3{display:grid;grid-template-columns:33.33% 33.33% 33.33%;}
.cm-layout .grid4{display:grid;grid-template-columns:25% 25% 25% 25%;}
.cm-layout .abs-flex{position:absolute;display:flex;}
.cm-layout .flex-rel{flex:1;position:relative;}
.cm-layout .flex-disf{flex:1;display:flex;}
.cm-layout .disf-col{display:flex;flex-direction:column;}
.cm-layout .flex-disf-col{flex:1;display:flex;flex-direction:column;}
.cm-layout .flex-disf-rel{flex:1;display:flex;position:relative;}
.cm-layout .ctn-rel{position:relative;}
.cm-layout .rel-flex{position:relative;display:flex;}
.cm-layout .ctn-abs{position:absolute;top:0;left:0;}
.cm-layout .abs-full, .cm-layout .ctn-absfull{position:absolute;top:0;left:0;height:100%;width:100%;}
.cm-layout .ctn-range .ctn-abs{height:100%;width:100%;}
.cm-layout .km-table{}
.cm-layout .km-table .table-box{text-align:center;}
.cm-layout .km-table dl{display:table;width:100%;}
.cm-layout .km-table dt>div, .cm-layout .km-table dd>div{display:table-cell;}
.cm-layout .km-table dt, .cm-layout .km-table dd{display:table-row;}
.cm-layout .km-table dt{font-weight:bold;}
.cm-layout .km-table dd{}
.cm-layout .km-table .border dl{border:1px solid #eef1f6;}
.cm-layout .km-table .border dt>div, .cm-layout .km-table .border dd>div{border-width:0 1px 1px 0;border-style:solid;border-color:#677290 #acb6d9;}
.cm-layout .km-table .bg44{background-color:#4476f9;}
.cm-layout .km-table .col00a{color:#00a4fe;}
.cm-layout .km-table .even-bg1 dd:nth-child(even){background-color:rgba(14,45,109,.8);}
.cm-layout .tinfo{color:#888;font-size:13px;border-width:0 0px 1px 1px;border-style:solid;border-color:#dfe6ec;}
.cm-layout .tinfo .tr{display:flex;}
.cm-layout .tinfo .td{padding:8px 5px;min-height:40px;border-width:1px 1px 0 0;border-style:solid;border-color:#dfe6ec;flex:1;display:flex;justify-content:center;align-items:center;}
.cm-layout .tinfo .td .cell{flex:1;display:flex;}
.cm-layout .tinfo .td font{white-space: nowrap;}
.cm-layout .tinfo .td span{color:#000;font-size:15px;}
.cm-layout .tinfo .td i{font-style:normal}
/* 文字定位 */
.cm-layout .text-abs{position:absolute;height:0;width:0;display:flex;justify-content:center;align-items:center;}
.cm-layout .text-abs a, .cm-layout .text-abs span{white-space:nowrap;text-align:center;}
/**/
.Screen .bg-o85{background-color:rgba(13,29,55, .85);}
.Screen .bg2-o80{background-color:rgba(4,23,63,.8);}
.Screen .bd-c1{border-color:#0394d0;}
.Screen .linef35{height:35px;line-height:35px;}
.Screen .linef40{height:40px;line-height:40px;}
.Screen .line50{height:.50rem;line-height:.50rem;}
.Screen .line42{height:.42rem;line-height:.42rem;}
.Screen .col02d{color:#02daff}
.Screen .col-green1{color:#03fd78}
.Screen .col-red1{color:#fb2b2b}
.Screen .col01f{color:#01f5ff}
.home_manage{}
.home_manage li{list-style:none;}
.page-bgc1{background-color:#f5f6fb;}
.common-page{flex:1;position:relative;display:flex;flex-direction:column;}
.common-page.page-t1{padding:.16rem;background-color:#f5f6fb;}
.common-page.dege{margin-right:1.041vw;}
.common-page h3{line-height:40px;margin:0;padding:0 0 0 10px;font-weight:normal;font-size:16px;color:#000;}
.common-page .page-row{margin-top:10px;}
.common-page .option{}
.common-page .panel-bottom{flex:1;display:flex;flex-direction:column;background-color:#fff;}
.common-page .cr-liner{height:100%;width:100%;}
.common-page .option .head-container{padding:9px;background-color:#fff;border-radius:5px;display:flex;align-items:center;border:1px solid #c9c9fe;}
.common-page .content-within{position:relative;flex:1;width:100%;}
.common-page .content-fix{width:100%;}
.common-page .content-between{display:flex;justify-content:space-between;}
.common-page .ctin-box{/* flex:1; */display:flex;padding:5px 10px 10px;border-radius:5px;}
.common-page .ctin-box .toolbar{padding:5px 0 10px;display:flex;}
.common-page .ctin-box .toolbar>div{flex:1;}
.common-page .ctin-box .toolbar>div:last-child{display:flex;justify-content:right;flex:none;}
.common-page .el-table{}
.common-page .el-table .thead{color:#666}
.common-page .el-table .red{color:#ff0000;}
.common-page .el-table .orange{color:orange;}
.common-page .el-table .yellow{color:yellow;}
.common-page .el-table .blue{color:blue;}
.common-page .el-table .green{color:#13ce66;}
.common-page .el-table .normal{color:#666;}
.common-page .el-table th, .common-page .el-table td{}
.common-page .el-table--small th{padding:10px 0;}
.common-page .el-table--small td{padding:7px 0;}
.common-page .el-table th>.cell, .common-page .el-table td>.cell{padding:0 6px;}
.common-page .el-date-editor .el-range-separator, .kmb-message-box .el-date-editor .el-range-separator{width:20px;}
/* 定义 button 默认样式 */
.kmb-message-box .el-button-group .cu-btn-null{color:#409eff;background:#ecf5ff;border-color:#b3d8ff;}
/* 自定义选择列表 */
.checkboxctn{max-height:70vh;overflow-y:auto;}
.checkboxctn li{line-height:25px;}
.checkboxctn::-webkit-scrollbar{width:5px;height:5px;cursor:pointer;}
.checkboxctn::-webkit-scrollbar-thumb{border-radius: 10px;background:#bbb;margin-right: 10px;cursor:pointer;}
.checkboxctn::-webkit-scrollbar-thumb:hover{background-color:#888;}
.checkboxctn::-webkit-scrollbar-track{border-radius: 10px;background:rgba(255, 255, 255, 0.1);margin-right: 10px;}
/* 滚动条-火狐 */
.checkboxctn{scrollbar-width:thin;scrollbar-color:#1674ee rgba(255, 255, 255, 0.1);}
/* 表单微调 */
body .el-dialog__header{border-bottom:1px solid #ddd;padding:10px;}
body .el-dialog__header .el-dialog__headerbtn{top:13px;}
body .el-dialog__body{padding:10px 20px;}
/* 滚动条 */
.scrolling{}
.scrolling::-webkit-scrollbar{width:3px;height:5px;cursor:pointer;}
.scrolling4::-webkit-scrollbar{width:4px;cursor:pointer;}
.scrolling, .scrolling4::-webkit-scrollbar-thumb{border-radius: 10px;background:#1674ee;margin-right: 10px;cursor:pointer;}
.scrolling, .scrolling4::-webkit-scrollbar-thumb:hover{background-color:#1854e8;}
.scrolling, .scrolling4::-webkit-scrollbar-track{border-radius: 10px;background:rgba(255, 255, 255, 0.1);margin-right: 10px;}
/* 滚动条-火狐 */
.scrolling, .scrolling4{scrollbar-width:thin;scrollbar-color:#1674ee rgba(255, 255, 255, 0.1);}
/* 暂无数据提示 */
/* .home_user .el-table__empty-block, .common-page .el-table__empty-block{background-color:#00344D} */
.head-container {
padding-bottom: 10px;
.filter-item {
display: inline-block;
vertical-align: middle;
margin: 0 3px 10px 0;
input {
height: 30.5px;
line-height: 30.5px;
}
}
.el-form-item-label {
display: inline-block;
text-align: right;
vertical-align: middle;
font-size: 14px;
color: #606266;
line-height: 30.5px;
padding: 0 7px 0 7px;
}
.el-button+.el-button {
//margin-left: 0 !important;
}
.el-select__caret.el-input__icon.el-icon-arrow-up{
line-height: 30.5px;
}
.date-item {
display: inline-block;
vertical-align: middle;
margin-bottom: 10px;
height: 30.5px !important;
width: 230px !important;
}
}
.el-avatar {
display: inline-block;
text-align: center;
background: #ccc;
color: #fff;
white-space: nowrap;
position: relative;
overflow: hidden;
vertical-align: middle;
width: 32px;
height: 32px;
line-height: 32px;
border-radius: 16px;
}
.logo-con{
height: 60px;
padding: 13px 0 0;
img{
height: 32px;
width: 135px;
display: block;
//margin: 0 auto;
}
}
#el-login-footer {
height: 40px;
line-height: 40px;
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
font-family: Arial, serif;
font-size: 12px;
letter-spacing: 1px;
}
#el-main-footer {
/* background: none repeat scroll 0 0 white; */
border-top: 1px solid #002B56;
overflow: hidden;
padding: 7px 6px 0 6px;
height: 26px;
font-size: 0.7rem !important;
color: #7a8b9a;
letter-spacing: 0.8px;
font-family: Arial, sans-serif !important;
position: fixed;
bottom: 0;
z-index: 99;
width: 100%;
}
.eladmin-upload {
border: 1px dashed #c0ccda;
border-radius: 5px;
height: 45px;
line-height: 45px;
width: 368px;
}
.my-blockquote{
margin: 0 0 10px;
padding: 15px;
line-height: 22px;
border-left: 5px solid #00437B;
border-radius: 0 2px 2px 0;
background-color: #f2f2f2;
}
.my-code{
position: relative;
padding: 15px;
line-height: 20px;
border-left: 5px solid #ddd;
color: #333;
font-family: Courier New, serif;
font-size: 12px
}
.el-tabs{
margin-bottom: 25px;
}
// cover some element-ui styles
.el-breadcrumb__inner,
.el-breadcrumb__inner a {
font-weight: 400 !important;
}
.el-upload {
input[type="file"] {
display: none !important;
}
}
.el-upload__input {
display: none;
}
.cell {
.el-tag {
margin-right: 0;
}
}
.small-padding {
.cell {
padding-left: 5px;
padding-right: 5px;
}
}
.fixed-width {
.el-button--mini {
padding: 7px 10px;
width: 60px;
}
}
.status-col {
.cell {
padding: 0 10px;
text-align: center;
.el-tag {
margin-right: 0;
}
}
}
// to fixed https://github.com/ElemeFE/element/issues/2461
.el-dialog {
transform: none;
left: 0;
position: relative;
margin: 0 auto;
}
// refine element ui upload
.upload-container {
.el-upload {
width: 100%;
.el-upload-dragger {
width: 100%;
height: 200px;
}
}
}
// dropdown
.el-dropdown-menu {
a {
display: block
}
}
// fix date-picker ui bug in filter-item
.el-range-editor.el-input__inner {
display: inline-flex !important;
}
/**
* I think element-ui's default theme color is too light for long-term use.
* So I modified the default color and you can modify it to your liking.
**/
/* theme color */
$--color-primary: #1890ff;
$--color-success: #13ce66;
$--color-warning: #FFBA00;
$--color-danger: #ff4949;
// $--color-info: #1E1E1E;
$--button-font-weight: 400;
// $--color-text-regular: #1f2d3d;
$--border-color-light: #dfe4ed;
$--border-color-lighter: #e6ebf5;
$--table-border:1px solid#dfe6ec;
/* icon font path, required */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "../../../node_modules/element-ui/packages/theme-chalk/src/index";
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
theme: $--color-primary;
}
@import 'variables';
@import 'mixin';
@import 'transition';
@import 'element-ui';
@import 'sidebar';
@import 'btn';
@import 'eladmin';
body {
height: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
background-color: #001b44;
}
label {
font-weight: 700;
}
html {
height: 100%;
//box-sizing: border-box;
}
#app {
height: 100%;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.no-padding {
padding: 0 !important;
}
.padding-content {
padding: 4px 0;
}
a:focus,
a:active {
outline: none;
}
a,
a:focus,
a:hover {
cursor: pointer;
color: inherit;
text-decoration: none;
}
div:focus {
outline: none;
}
.fr {
float: right;
}
.fl {
float: left;
}
.pr-5 {
padding-right: 5px;
}
.pl-5 {
padding-left: 5px;
}
.block {
display: block;
}
.pointer {
cursor: pointer;
}
.inlineBlock {
display: block;
}
.clearfix {
&:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
}
aside {
background: #eef1f6;
padding: 8px 24px;
margin-bottom: 20px;
border-radius: 2px;
display: block;
line-height: 32px;
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
color: #2c3e50;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
a {
color: #337ab7;
cursor: pointer;
&:hover {
color: rgb(32, 160, 255);
}
}
}
//main-container全局样式
.app-container {
/* padding: 20px 20px 45px 20px; */ padding: 1.851vh 1.041vw 4.166vh 1.041vw;
flex:1;position:relative;display:flex;flex-direction:column;
+ .page-footer{
background-color:transparent;
}
}
.components-container {
margin: 30px 50px;
position: relative;
}
.pagination-container {
margin-top: 30px;
}
.text-center {
text-align: center
}
.sub-navbar {
height: 50px;
line-height: 50px;
position: relative;
width: 100%;
text-align: right;
padding-right: 20px;
transition: 600ms ease position;
background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
.subtitle {
font-size: 20px;
color: #fff;
}
&.draft {
background: #d0d0d0;
}
&.deleted {
background: #d0d0d0;
}
}
.link-type,
.link-type:focus {
color: #337ab7;
cursor: pointer;
&:hover {
color: rgb(32, 160, 255);
}
}
//refine vue-multiselect plugin
.multiselect {
line-height: 16px;
}
.multiselect--active {
z-index: 1000 !important;
}
@mixin clearfix {
&:after {
content: "";
display: table;
clear: both;
}
}
@mixin scrollBar {
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
}
}
@mixin relative {
position: relative;
width: 100%;
height: 100%;
}
@mixin pct($pct) {
width: #{$pct};
position: relative;
margin: 0 auto;
}
@mixin triangle($width, $height, $color, $direction) {
$width: $width/2;
$color-border-style: $height solid $color;
$transparent-border-style: $width solid transparent;
height: 0;
width: 0;
@if $direction==up {
border-bottom: $color-border-style;
border-left: $transparent-border-style;
border-right: $transparent-border-style;
}
@else if $direction==right {
border-left: $color-border-style;
border-top: $transparent-border-style;
border-bottom: $transparent-border-style;
}
@else if $direction==down {
border-top: $color-border-style;
border-left: $transparent-border-style;
border-right: $transparent-border-style;
}
@else if $direction==left {
border-right: $color-border-style;
border-top: $transparent-border-style;
border-bottom: $transparent-border-style;
}
}
#app {
.main-container {
transition: margin-left .28s;
/* margin-right: $sideBarMargin;
padding-left: $sideBarWidth + $sideBarMargin; */
position:relative;
}
.hideSidebar {
.sidebar-container {
width:54px !important;
//min-width:54px !important;
}
.main-container {
// margin-left: 54px + $sideBarSpacingPx;
padding-left: 54px + $sideBarSpacingPx;
}
.submenu-title-noDropdown {
padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
}
}
.el-submenu {
overflow: hidden;
&>.el-submenu__title {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
}
}
.el-menu--collapse {
.el-submenu {
&>.el-submenu__title {
&>span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
}
}
}
}
.el-menu--collapse .el-menu .el-submenu {
min-width: $sideBarWidth !important;
}
// mobile responsive
.mobile {
.main-container {
// margin-left: 0;
padding-left: 0;
}
.sidebar-container {
transition: transform .28s;
//width: $sideBarWidth !important;
width:0 !important;
}
&.hideSidebar {
.sidebar-container {
pointer-events: none;
transition-duration: 0.3s;
transform: translate3d(-$sideBarWidth, 0, 0);
}
}
}
.withoutAnimation {
.main-container,
.sidebar-container {
transition: none;
}
}
}
// when menu collapsed
.el-menu--vertical {
&>.el-menu {
.svg-icon {
margin-right: 16px;
}
}
.nest-menu .el-submenu>.el-submenu__title,
.el-menu-item {
&:hover {
// you can use $subMenuHover
background: $leftMenuHover !important;
}
}
// the scroll bar appears when the subMenu is too long
>.el-menu--popup {
max-height: 100vh;
overflow-y: auto;
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
}
}
}
// global transition css
/* fade */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.28s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
/* fade-transform */
.fade-transform-leave-active,
.fade-transform-enter-active {
transition: all .5s;
}
.fade-transform-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transform-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* breadcrumb transition */
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all .5s;
}
.breadcrumb-enter,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(20px);
}
.breadcrumb-move {
transition: all .5s;
}
.breadcrumb-leave-active {
position: absolute;
}
// base color
$blue:#324157;
$light-blue:#3A71A8;
$red:#C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow:#FEC171;
$panGreen: #30B08F;
// sidebar
$menuText:#bfcbd9;
//$menuActiveText:#409EFF;
$menuActiveText:#FFF;
$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951
//$menuBg:#304156;
$menuBg:#001b44;
$leftMenuBg:transparent;
//$menuHover:#263445;
$leftMenuHover:linear-gradient(to right, rgba(0,102,228, .9), rgba(0,188,255, .9));
$subMenuBg:rgba(27,58,99, .7);
$subMenuHover:linear-gradient(to right, rgba(0,102,228, .9), rgba(0,188,255, .9));
//$sideBarWidth: 205px;
$sideBarWidth: 12.395vw;
$sideBarMargin: 0vw;
$sideBarMin:2.812vw;
$sideBarSpacingPx:10px;
$subNavbarColor:#9ae8fe;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
leftMenuBg:$leftMenuBg;
menuHover: $leftMenuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
subNavbarColor: $subNavbarColor;
}
<!--
/**
* 高德地图组件
* @example1:
1, 引入
import cuAmap from '@/components/AMap';
2, 注册
export default {
components: {
cuAmap
},
data() {
return {
amapinfo:{
zoom:6,
//longitude: 120.651884,
//latitude: 36.962533,
}
}
},
}
3, 创建
<cu-amap
ref="amap"
//:mapinfo="amapinfo"
//:onload="amapOnload"
//@click="mapClick"
:options="amapOptions()"
//:parent="_self"
/>
4, onload [Function] 回调函数, 地图的显示: {如果设置了回调函数不需要初始化地图, 否则要初始化}
export default {
methods: {
#amapOnload(cmap){
this.mapOnload && this.mapOnload()
},
amapOptions(cmap){
var self = this;
return {
zoom:6,
center:[107.260044, 36.737982],
//showLabel: true,
//pitch: 40,
onload: function(cmap){
console.log('onload ________________ ', self, cmap);
self.cmap = cmap;
},
click: function(e, cmap){
console.log('click ________________ ', cmap);
},
};
},
}
}
5, || 初始化
var opts = {
center:[107.260044, 36.737982],
showLabel: true,
pitch: 40,
zoom: 4,
mapStyle: 'amap://styles/blue',
};
var cmap = this.$refs.amap.init(opts);
// 使用
cmap.addMarker({{lnglat:[item.longitude, item.latitude], draggable:true,dragend: function(e){}});
* @author: Kimber
* @updatetime: 2022/5/13(周五)
* @createtime: 2021/7/3
*/
-->
<template>
<div id="A_Map" class="amap">amap</div>
</template>
<script>
export default {
name: 'amap',
data() {
return {
icons:{
red1:'https://webapi.amap.com/theme/v1.3/markers/n/mark_rs.png',
red2:'https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
default1:'https://webapi.amap.com/theme/v1.3/markers/n/mark_bs.png',
default2:'https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
},
Markers:{},
}
},
props:{
options: {
type: Object,
default: {},
},
parent: {
type: Object,
},
},
watch: {
},
created() {
var that = this;
/**
* 初始化地图
* @param: {Object} options {
center:[107.260044, 36.737982],
showLabel: true,
pitch: 40,
zoom: 4,
// (normal(标准), dark(幻影黑), light(月光银), whitesmoke(远山黛), fresh(草色青), grey(雅士灰), graffiti(涂鸦), macaron(马卡龙), blue(靛青蓝), darkblue(极夜蓝), wine(酱籽))
mapStyle: 'amap://styles/grey',
};
* @example1: var camap = this.$refs.amap.init(options);
* @return:
* @author: Kimber
* @updatetime: 2021/7/15(周四)
* @createtime: 2021/7/15(周四)
*/
that.init = function(options, callback){
options = options || this.options || {
resizeEnable: true, // 是否监控地图容器尺寸变化
zoom: 4, // 初始化地图层级
center: [122.081977,37.50653], // 初始化地图中心点
//viewMode:'3D',
//pitch:60,
//rotation:-35,
//features:['bg','road','point'],//隐藏默认楼块
//mapStyle:'amap://styles/light',
//layers: [new AMap.TileLayer.Satellite(), new AMap.Buildings({
//'zooms':[16,18],
//'zIndex':10,
//'heightFactor':2 //2倍于默认高度,3D下有效
//})],
};
// 卫星地图条件
if(options.satellite){
var Satellite = new AMap.TileLayer.Satellite();
options.layers && options.layers.push(Satellite) || (options.layers = [Satellite]);
/* var disCountry = new AMap.DistrictLayer.World({
zIndex: 1,
rejectMapMask: true
}); */
//options.layers.push(disCountry);
options.layers.push(new AMap.TileLayer.RoadNet({zIndex:7}));
};
var Map = new AMap.Map('A_Map', options);
Map.on('click', function(ev) {
// 触发事件的对象
var target = ev.target;
// 触发事件的地理坐标,AMap.LngLat 类型
var lnglat = ev.lnglat;
// 触发事件的像素坐标,AMap.Pixel 类型
var pixel = ev.pixel;
// 触发事件类型
var type = ev.type;
if(type === 'click'){
//that.$emit('click', ev, Map, that);
that.options.click && that.options.click.call(that.parent, ev, that);
};
});
/* Map.on('zoomstart', function(e){
});
Map.on('zoomend', function(e){
}); */
that.Map = Map;
callback && callback.call(that, Map);
return that
};
this.$nextTick(() => {
this.options.onload && this.options.onload.call(this.parent, that.init());
});
},
mounted() {
},
methods: {
/**
* 添加标记
* @param: {Object} options []
* @example1: this.$refs.amap.addMarker({});
* @example2:
camap.addMarker({
lnglat:[data.lng, data.lat],
title:'',
draggable:true,
dragend: function(e){
var lnglat = e.lnglat;
camap.deGeocode([lnglat.lng, lnglat.lat], function(addr){
that.form.item.lng = lnglat.lng;
that.form.item.lat = lnglat.lat;
that.form.item.address = addr;
});
},
});
* @method: Kimber
* @return:
* @updatetime: 2022/5/13(周五)
* @createtime: 2021/6/11
*/
addMarker(param){
/* if(this.marker){
this.removeMarker()
}; */
if(param.lnglat && param.lnglat[0]){
var icon = this.icons[param.icon];
var marker = this.marker = new AMap.Marker({
icon: icon,
map: this.Map,
position: param.lnglat, // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
title: param.title,
draggable: param.draggable,
extData:param.extData,
});
param.dragging && marker.on('dragging', param.dragging);
param.dragend && marker.on('dragend', param.dragend);
// 缓存
marker.id = marker._amap_id;
this.Markers[marker.id] = marker;
return marker
};
},
// amap.removeMarker()
removeMarker(marker){
marker = marker || this.marker;
marker && this.Map.remove(marker);
delete this.marker
},
setTargetMarker(tag){
this.tagMarker = tag;
},
getTargetMarker(){
return this.tagMarker
},
getMarkerById(id){
this.Markers[~~id]
},
createInfoWindow(opts){
var infoWindow = new AMap.InfoWindow(opts);
infoWindow.Map = this.Map;
return infoWindow
},
/**
* 地理位置解码
* @param: {Array} lnglat [longitude, latitude]
* @example1: this.$refs.amap.deGeocode([lnglat.lng, lnglat.lat], function(addr){});
* @method: Kimber
* @return:
* @create: 2021/6/11
*/
deGeocode(lnglat, fn){
//AMap.service('AMap.Geocoder', function() {
AMap.plugin('AMap.Geocoder', function() {
var geocoder = new AMap.Geocoder({});
geocoder.getAddress(lnglat, function(status, result) {
if (status === 'complete' && result.info === 'OK') {
//var address = result.regeocode.formattedAddress;
var addrObj = result.regeocode.addressComponent || {};
var address = addrObj.province + addrObj.city + addrObj.district + addrObj.township;
fn && fn(address, addrObj)
} else {
}
});
});
},
/**
* 设置中心点
* @param: {Arrar} arr
* @example1: this.$refs.amap.setCenter([lng, lat]);
* @createtime: 2021/7/2
*/
setCenter: function(arr){
this.Map.setCenter(arr)
},
/**
* 根据中心点 marker 自适应缩放
* @param: {Arrar} arr
* @example1: this.$refs.amap.setFitView(marker);
* @createtime: 2021/7/3
*/
setFitView: function(marker){
this.Map.setFitView(marker)
},
/**
* 按地址定位坐标
* @param: {String} str
* @example1: this.$refs.amap.addressSearch(addr).then((res) => {});
* @createtime: 2021/7/3
*/
addressSearch: function(str){
return new Promise(function(resolve, reject){
// 实例化Autocomplete
var autoOptions = {
city: '全国'
}
var autoComplete = new AMap.Autocomplete(autoOptions);
autoComplete.search(str, function(status, result) {
var list = result.tips || [];
for(var item of list){
if(item.location){
return resolve(item)
};
};
return resolve(list.pop())
})
})
},
/**
* 按区域画高亮遮罩层
* @param: {Object} opts
opts = {
level: "province", // province(省), country(国) 在区域内搜索(行政区级别)
city: '威海市',
color: '#00000cc',
strokeColor: 'rgba(7, 247, 247, 1)',
fillColor: 'rgba(7, 247, 247, 1)',
}
* @example1:
* @return:
* @author: Kimber
* @updatetime: 2021/7/15(周四)
* @createtime: 2021/7/15(周四)
*/
area3DLayer: function(opts){
var cMap = this.Map;
var district = new AMap.DistrictSearch({
subdistrict: 1,
extensions: 'all',
level: opts.level
});
district.search(opts.city, function (status, result) {
var bounds = result.districtList[0].boundaries;
var mask = []
for (var i = 0; i < bounds.length; i += 1) {
mask.push([bounds[i]])
};
//添加高度面
var object3Dlayer = new AMap.Object3DLayer({zIndex: 1});
cMap.add(object3Dlayer)
var height = -7000;
var wall = new AMap.Object3D.Wall({
path: bounds,
height: height,
color: opts.color
});
wall.transparent = true
object3Dlayer.add(wall);
//添加描边
for(var i=0; i<bounds.length; i+=1) {
var polygon = new AMap.Polygon({
map: cMap,
bubble: true,
strokeWeight: 1,
strokeDasharray: [10, 20],
strokeColor: opts.strokeColor || 'rgba(7, 247, 247, 1)',
fillColor: opts.fillColor || 'rgba(7, 247, 247, 1)',
fillOpacity: 0.5,
path: bounds[i],
})
}
});
},
}
}
</script>
<style lang="scss" scoped>
.amap{height:100%;width:100%;background-color:#29557A;}
</style>
<style lang="scss">
.amap-logo{display:none !important;}
</style>
<!--
/**
* 表单通用组件
* @example1:
1, 引入
import Slider from '@/components/Slider';
2, 注册
3, 创建
<Carousel
ref="Carousel"
/>
* @author: Kimber
* @createtime: 2021/12/21(周二)
*/
-->
<template>
<Carousel class="cu-slider" indicator-position="none" height="100%" :interval="config.interval">
<Carousel-item v-for="(item, i) in list">
<h3><i class="el-icon-s-data"></i>{{item.sumtitle}}</h3>
<!-- 设备信息 -->
<div v-if="item.type==='t_10'" class="sli-ctn t_10">
<div class="ctn-absfull">
<div class="chart_ctn" :data-index="i" :class="item.className" :data-item="JSON.stringify(item)" :id="item.id">
</div>
<div class="info">
<ul class="list">
<li>
<h5>设备总数</h5>
<div>
<span>{{Cache.t_10.sum}}</span>
<font></font>
</div>
</li>
<li>
<h5>设备在线数量</h5>
<div>
<span>{{Cache.t_10.online}}</span>
<font></font>
</div>
</li>
<li>
<h5>设备离线数量</h5>
<div>
<span>{{Cache.t_10.offline}}</span>
<font></font>、‘
</div>
</li>
</ul>
</div>
</div>
</div>
<!-- 实时数据(new) -->
<div v-else-if="item.type==='t_11'" class="sli-ctn t_11">
<div class="ctn-absfull scrolling4">
<div class="chart_ctn" :data-index="i" :class="item.className" :data-item="JSON.stringify(item)" :id="item.id">
<ul class="info-list">
</ul>
</div>
</div>
</div>
<!-- 报警记录(new) -->
<div v-else-if="item.type==='t_12'" class="sli-ctn t_12">
<div class="ctn-absfull scrolling4">
<div class="chart_ctn" :data-index="i" :class="item.className" :data-item="JSON.stringify(item)" :id="item.id">
<ul class="info-list">
<!-- <li><h5><i class="level2"></i>浸润线1</h5><span> 4 </span><font>报警时间(4)</font></li> -->
</ul>
</div>
</div>
</div>
<!-- 实时数据(discard)
<div v-else-if="item.type==='t_11'" class="sli-ctn t_1">
<div class="ctn-absfull">
<div class="info">
<ul class="list">
<li>
<h5>降雨量</h5>
<div>
<span>{{Cache.t_10.sum}}</span>
<font></font>
</div>
</li>
<li>
<h5>表面位移</h5>
<div>
<span>{{Cache.t_10.online}}</span>
<font></font>
</div>
</li>
</ul>
</div>
</div>
</div> -->
<!-- 水质 -->
<div v-else-if="item.type==='t_8'" class="sli-ctn t_8">
<div class="ctn-absfull">
<div class="chart_ctn" :data-index="i" :class="item.className" :data-item="JSON.stringify(item)">
<!-- <ul class="info">
<li>
<div>
<span>{{'896'}}</span>
<font>浊度</font>
</div>
<div>
<font></font>
<span>{{'14890'}}</span>
</div>
</li>
</ul> -->
</div>
</div>
</div>
<div v-else class="sli-ctn">
<div class="chart_ctn ctn-absfull" :data-index="i" :class="item.className" :data-item="JSON.stringify(item)" :id="item.id"></div>
</div>
</Carousel-item>
</Carousel>
</template>
<script>
import {Carousel, CarouselItem} from 'element-ui';
export default {
components: { Carousel, CarouselItem },
data() {
return {
list:[],
Cache:{
t_10:{
sum:0,
online:0,
offline:0,
},
},
config:{
interval:6000,
},
}
},
props:{
},
beforeCreate(){
},
created(){
},
mounted() {
},
methods: {
createViews(item){
this.list = item.children;this.config.interval = item.interval;
var carouselCtn = this.$el.firstElementChild;
return new Promise((resolve, reject) => {
this.$nextTick(() => {
var chartEls = carouselCtn.querySelectorAll('.chart_ctn');
var panelList = this.setAttribute(chartEls);
resolve(panelList);
});
})
},
setAttribute(charts){
var panelList = [];
for(var el of charts){
var item = JSON.parse(el.dataset.item), type = item.type;
panelList.push({info:this.Cache[type], el:el, item:item, type:type});
}; return panelList;
},
},
}
</script>
<style lang="scss" scope>
.cu-slider{
position:absolute;top:0;left:0;height:100%;width:100%;overflow:hidden;
.el-carousel{
width:100%;height:100%;
}
.el-carousel__container{
.el-carousel__item{
display:flex;flex-direction:column;
h3{
margin:.05rem .08rem .02rem .08rem;color:#00fff0;padding-left:.08rem;
background-image:linear-gradient(to right, #2967AA 15%, transparent 60%);
font-size:.16rem;font-weight:normal;height:.28rem;max-height:.25rem;
display:flex;align-items:center;font-weight:bold;
i{
display:inline-block;margin-right:6px;color:#E29A23;font-size:.20rem;
}
}
.sli-ctn{
flex:1;position:relative;margin:0 .08rem .05rem;
//border:1px solid green;
}
.t_10{
>div{display:flex;}
.chart_ctn{flex:1;}
.info{
display:flex;align-items:center;width:2.04rem;max-width:175px;
ul{width:100%;}
li{
display:flex;justify-content:space-between;height:.49rem;line-height:.47rem;
border:1px solid #0f5680;margin:.06rem 0;background-color:#13286b;padding:0 .04rem;
h5{font-weight:normal;color:#5fbfef;font-size:.14rem;}
>div{color:#35ecfa;}
span{font-size:.22rem;}
font{font-size:.14rem;}
}
}
}
.t_11, .t_12{
>div{
height:100%;overflow-y:scroll;user-select:none;
}
}
.t_1{
.info{
display:flex;color:#fff;height:100%;
ul{
flex:1;display:flex;flex-direction:row;flex-wrap:wrap;padding:.10rem 0 .15rem;
li{
display:flex;flex-direction:column;justify-content:center;width:33.33%;
>div{
border:1px solid #04a3b8;height:.36rem;line-height:.36rem;margin:0 .04rem;text-align:center;color:#01fdfe;font-size:.14rem;
box-shadow:inset 0rem 0rem 0.10rem 0.02rem rgba(4,163,184, .8);
}
}
h5{
position:relative;display:flex;align-items:center;color:#5ebded;font-size:.15rem;
margin:0 .04rem;
&:before{
content:"";height:.10rem;width:.08rem;background-color:#02ffff;margin-right:.10rem;
}
}
}
}
}
.t_8{
>div{
display:flex;align-items:center;
}
.chart_ctn{
height:1.5rem;width:100%;display:flex;
background:no-repeat center center url('~@/assets/images/layout/view_2.png');background-size:auto 100%;
ul{
flex:1;display:flex;margin:.09rem 0;flex-direction:column;
li{
display:flex;width:100%;height:0.43rem;
&:last-child{margin-bottom:0;}
>div{
flex:1;display:flex;align-items:center;color:#fff;font-size:.15rem;
}
div:first-child{
margin-right:2rem;justify-content:end;
span{margin:0 .15rem 0 .1rem;}
}
div:last-child{
text-align:right;justify-content:start;
span{margin:0 .1rem 0 .15rem;}
}
}
}
}
}
.t_12{
h5{
display:flex;align-items:center;
i{
position:relative;width:.30rem;height:.24rem;margin-right:.06rem;
display:flex;justify-content:center;
&:before{
content:"";position:absolute;height:0;width:0;bottom:0;
border-width:.24rem .14rem;border-style:solid;
}
&:after{
content:"!";position:absolute;font-style:normal;line-height:.30rem;font-size:.14rem;color:black;
}
}
.level1{
&:before{
border-color:transparent transparent #F93C58 transparent;
}
}
.level2{
&:before{
border-color:transparent transparent #FA953A transparent;
}
}
.level3{
&:before{
border-color:transparent transparent #E9FA3C transparent;
}
}
.level4{
&:before{
border-color:transparent transparent #3BAFFB transparent;
}
}
}
}
.info-list{
li{
display:flex;justify-content:space-between;height:.49rem;line-height:.47rem;
border:1px solid #0f5680;margin:.06rem 0;padding:0 .10rem;
background-image:linear-gradient(to right, transparent 30%, #13286b 80%);color:#35ecfa;
h5{font-weight:normal;color:#fff;font-size:.14rem;margin-right:5px;}
span{font-size:.16rem;display:inline-block;margin-right:5px;}
font{font-size:.14rem;}
>div{display:flex;}
h5, span, font, div{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;word-wrap:normal;}
}
}
}
}
.el-carousel__arrow{display:none;}
}
</style>
\ No newline at end of file
<!--
/**
* 表单通用组件
* @example1:
1, 引入
import Slider from '@/components/Slider';
2, 注册
3, 创建
<Carousel
ref="Carousel"
/>
* @author: Kimber
* @createtime: 2021/12/21(周二)
*/
-->
<template>
<div class="center-flx">
<nav v-if="list.length > 1">
<a v-for="(child, i) in list" :class="{'actv': viewActive === i}" @click="navEvent(i, child.type)">{{child.sumtitle}}</a>
</nav>
<div class="b2a2_a" id="agentFigure">
<div class="list-wrap" v-for="(child, i) in list" :class="{'show':viewActive === i}">
<div class="b2a2_a1" v-if="child.type === 't_15'" >
<div id="figure" class="figure">
<div class="img-box" id="pictureArea">
<img id="drawingImg">
</div>
<div id="pointsLayer" class="cview_ctn wkk-ctn" :data-index="i" :class="child.className" :data-item="JSON.stringify(child)" :id="child.id">
<ul></ul>
</div>
</div>
</div>
<div v-else>
<div class="cview_ctn ctn-absfull" :data-index="i" :class="child.className" :data-item="JSON.stringify(child)" :id="child.id">
<EZUIKitJs ref="EZUIKit" selectSeat="none" autoPlayer="false"/>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
//import {Carousel, CarouselItem} from 'element-ui';
//import cuAmap from '@/components/AMap';
import EZUIKitJs from '@/components/EZUIKitJs'
export default {
components: { EZUIKitJs },
data() {
return {
list:[],
Cache:{
},
config:{
},
amapinfo:{
zoom:6,
//longitude: 120.651884,
//latitude: 36.962533,
},
viewActive:0,
/* gis:{
isShow:0,
}, */
}
},
props:{
},
beforeCreate(){
},
created(){
},
mounted() {
},
methods: {
createViews(item){
var that = this;
this.list = item.children;this.config.interval = item.interval;
var carouselCtn = this.$el.firstElementChild;
return new Promise((resolve, reject) => {
this.$nextTick(() => {
var chartEls = carouselCtn.querySelectorAll('.cview_ctn');
var panelList = this.setAttribute(chartEls);
resolve(panelList);
});
})
},
setAttribute(charts){
var panelList = [];
for(var el of charts){
var item = JSON.parse(el.dataset.item), type = item.type;
var setData = type === 't_15' ? this.showPointView : this.setPlayInfo;
panelList.push({info:this.Cache[type], el:el, item:item, type:type, setData:setData});
}; return panelList;
},
showPointView(data, Tools, pageApi, initModule){
var that = this;
var agentFigure = this.$el.querySelector("#agentFigure");
this.mapWidget = new qf.UI.pointCharts({
chartsBox:this.$el.querySelector("#figure"),
width:agentFigure.offsetWidth,
height:agentFigure.offsetHeight,
isRelieveAlarm:true,
itemClick: function(id){
var params = {equipno:id};
that.$parent.openRelieveAlarm(params, function(){
initModule()
});
},
});
this.mapWidget.setBackground(data.chart.picture);
this.mapWidget.createPoints(data.points, data.chart);
},
setPlayInfo(param){
var EZUIKit = this.$refs.EZUIKit[0];
EZUIKit.playerToParam(param);
},
navEvent(id, key){
this.viewActive = ~~id;
},
},
}
</script>
<style lang="scss" scope>
.center-flx{
height:100%;width:100%;
display:flex;flex-direction:column;padding:.12rem 0.12rem 0.12rem;
/* padding:0 0.08rem 0.08rem; */
nav{
height:.26rem;text-align:center;color:#89B7C6;font-size:0;user-select:none;margin-top:-0.12rem;
a{
display:inline-block;font-size:.15rem;line-height:.22rem;padding:0 .10rem;
cursor:pointer;border-radius:.05rem .05rem 0 0;
}
.actv{color:#0CE2CE;background-color:#2271C6;};
}
.b2a2_a1{
height:100%;width:100%;position:relative;
>div{
/* display:none; */
}
>div.show{display:block;}
>div:first-child{}
>div:last-child{}
.figure{
position:relative;top:0;left:0;height:100%;width:100%;
user-select:none;font-family:serif;color:#444;
}
.figure{
.img-box{
position:absolute;top:0;left:0;height:100%;width:100%;z-index:10;
img{display:block;border:0;max-height:100%;max-width:100%;}
&:before {
position: absolute;
content: '';
width: 100%;
height: 100%;
top: 0;
left: 0;
box-shadow: inset 0rem 0rem 0.55rem 0.20rem rgba(0,31,60, .8);
}
}
.wkk-ctn{
position:absolute;top:0;left:0;height:100%;width:100%;z-index:20;
}
}
.figure .wkk-ctn{position:absolute;top:0;left:0;height:100%;width:100%;}
.figure .wkk-ctn li{position:absolute;}
.figure .wkk-ctn li::marker{content:close-quote;}
.figure .wkk-ctn li i{
position:absolute;top:0;left:0;height:100%;width:100%;
background-repeat:no-repeat;background-position:center bottom;background-size:contain;
}
.figure .wkk-ctn li.d_01 i{background-image:url('~@/assets/images/icon/d_01.png');}
.figure .wkk-ctn li.d_02 i{background-image:url('~@/assets/images/icon/d_02.png');}
.figure .wkk-ctn li.d_03 i{background-image:url('~@/assets/images/icon/d_03.png');}
.figure .wkk-ctn li.d_04 i{background-image:url('~@/assets/images/icon/d_04.png');}
.figure .wkk-ctn li.d_05 i{background-image:url('~@/assets/images/icon/d_05.png');}
.figure .wkk-ctn li.d_06 i{background-image:url('~@/assets/images/icon/d_06.png');}
.figure .wkk-ctn li.d_07 i{background-image:url('~@/assets/images/icon/d_07.png');}
.figure .wkk-ctn li.d_08 i{background-image:url('~@/assets/images/icon/d_08.png');}
.figure .wkk-ctn li>div{position:absolute;display:flex;align-items:center;justify-content:center;}
.figure .wkk-ctn li>div .text{position:absolute;padding:0.0402rem;background-color:#fff;border-radius:0.0643rem;line-height:1.2;color:#1A688C;font-weight:bold;z-index:1;}
.figure .wkk-ctn .text h4{text-align:center;color:#1284b3;font-weight:normal;}
.figure .wkk-ctn .text dd{display:block;line-height:normal;margin-top:3px;}
.figure .wkk-ctn .text dd:before{font-size:15px;margin-right:3px;}
.figure .wkk-ctn .text .normal:before{font-size:13px;margin-right:1px;}
.figure .wkk-ctn .text .red{background-color:red;color:#fff;}
.figure .wkk-ctn .text .orange{background-color:orange;color:#fff;}
.figure .wkk-ctn .text .yellow{background-color:#e8cb08;color:#fff;}
.figure .wkk-ctn .text .blue{background-color:#0991FF;color:#fff;}
.figure .wkk-ctn .text .relieve{cursor:pointer;}
.figure .wkk-ctn .text .offline{color:#aaa;}
.figure .wkk-ctn .text .online{color:#000;}
/* .figure .wkk-ctn .text .el-icon-info{
animation:twinkle 1100ms infinite;
} */
.figure .wkk-ctn li>div .text:before{content:'';position:absolute;height:0;width:0;border-style:solid;border-width:0.0643rem;border-color:transparent;}
.figure .wkk-ctn .up{top:0;left:0;height:0;width:100%;}
.figure .wkk-ctn .up .text{bottom:0.0804rem;width:max-content;}
.figure .wkk-ctn .up .text:before{bottom:-0.1287rem;left:50%;margin-left:-0.0643rem;border-color:#fff transparent transparent transparent;}
.figure .wkk-ctn .down{bottom:0;left:0;height:0;width:100%;}
.figure .wkk-ctn .down .text{top:0.0804rem;width:max-content;}
.figure .wkk-ctn .down .text:before{top:-0.1287rem;left:50%;margin-left:-0.0643rem;border-color:transparent transparent #fff transparent;}
.figure .wkk-ctn .left{top:0;left:0;height:100%;width:0;}
.figure .wkk-ctn .left .text{right:0.0804rem;width:max-content;}
.figure .wkk-ctn .left .text:before{top:50%;right:-0.1287rem;margin-top:-0.0643rem;border-color:transparent transparent transparent #fff;}
.figure .wkk-ctn .right{top:0;right:0;height:100%;width:0;}
.figure .wkk-ctn .right .text{left:0.0804rem;width:max-content;}
.figure .wkk-ctn .right .text:before{top:50%;left:-0.1287rem;margin-top:-0.0643rem;border-color:transparent #fff transparent transparent;}
@keyframes red {
0% {opacity: 1.0;}
12.5% {opacity: 0.2;}
25% {opacity: 1.0;}
}
@keyframes orange {
0% {opacity: 1.0;}
10% {opacity: 0.2;}
20% {opacity: 1.0;}
}
@keyframes yellow {
0% {opacity: 1.0;}
9% {opacity: 0.2;}
18% {opacity: 1.0;}
}
@keyframes blue {
0% {opacity: 1.0;}
7.5% {opacity: 0.2;}
15% {opacity: 1.0;}
}
}
}
div.screenAlart{
.el-message-box__header{
padding:10px 5px 5px 5px;
.el-message-box__headerbtn{color:#eee;top:10px;right:10px;}
}
.kmb-message-box{
background-color:rgba(0,0,0,.7);border:1px solid #00B2FC;
.el-message-box__title{color:#eee;}
.el-message-box__content{color:#ddd;}
}
.alert-ctbox{
.item{line-height:30px;}
span{display:inline-block;width:115px;}
input{height:25px;line-height:25px;outline:none;padding:5px 5px;background:transparent;border:1px solid #aaa;color:#fff;}
input::-webkit-input-placeholder{color:#888;}
}
}
</style>
\ No newline at end of file
<!--
/**
* Cesium 地图组件
* @param: Vue Params
* @example1:
1, 引入
import cesiumMap from '@/components/Cesium';
2, 注册
export default {
components: {
cesiumMap
},
}
3, 创建
<cesium
ref="cesium"
:mapinfo="mapinfo"
:onload="mapOnload"
@click="mapClick"
/>
4, 使用
var cuCesium = this.$refs.cesium;
cuCesium.addMarker({});
* @example2: this.$refs.CesiumMap.addMarkers(marks);
* @author: Kimber
* @createtime: 2021/11/18
*/
-->
<template>
<div id="cesiumContainer" class="cesium-ctn"></div>
</template>
<script>
export default {
name: 'cesium',
data() {
return {
icons:{
},
}
},
props:{
mapinfo: {
type: Object,
default: {},
},
onload: {
type: Function,
},
},
watch: {
},
created() {
var that = this;
/**
* 初始化地图
* @return:
* @author: Kimber
* @updatetime: 2021/11/18(周四)
* @createtime: 2021/11/18(周四)
*/
this.$nextTick(() => {
var mapinfo = this.mapinfo;
var viewer = this.viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider : Cesium.createWorldTerrain(),
baseLayerPicker : false,
timeline:false,
homeButton:false,
fullscreenButton:false,
infoBox:false,
sceneModePicker:false,
navigationInstructionsInitiallyVisible:false,
navigationHelpButton:false,
geocoder:false,
animation:false, // 底部指针
selectionIndicator:false,
});
viewer._cesiumWidget._creditContainer.style.display = "none";
if(mapinfo.tileConfig && mapinfo.tileConfig.url){
this.addTile(mapinfo.tileConfig, function(){
that.setView(mapinfo.view);
});
}else{
that.setView(mapinfo.view);
};
this.onload && this.onload()
});
},
mounted() {
},
methods: {
getGuid(prefix, len){
var id = len ? new Array(len+1).join('x') : 'xxxxxxxx';
return (prefix || '')+id.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
})
},
/**
* 添加瓦片
* @param: {Object} options []
* @example1: this.addTile(param, fn);
* @example2:
* @method: Kimber
* @return:
* @create: 2021/11/18
*/
addTile(param, fn){
var that = this;
var tileset = this.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: param.url,
maximumScreenSpaceError:1, // 用于驱动细节细化级别的最大屏幕空间误差。
maximumMemoryUsage:1024, // 图块集可以使用的最大内存量(以 MB 为单位)。
}));
tileset.readyPromise.then(function () {
var boundingSphere = tileset.boundingSphere;
that.viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.0, -0.5, boundingSphere.radius));
that.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
fn && fn()
}).otherwise(function (error) {
throw (error);
});
},
/**
* 设置视角
* @return:
* @author: Kimber
* @updatetime: 2021/11/18(周四)
* @createtime: 2021/11/18(周四)
*/
setView(view){
if(view.longitude){
// 设备位置、视角
this.viewer.camera.setView({
destination:Cesium.Cartesian3.fromDegrees(view.longitude, view.latitude, view.height),
orientation:{
// 指向
heading:view.heading,
// 视角
pitch:view.pitch,
// 倾斜
roll:view.roll,
}
});
};
},
/**
* 添加标记
* @example1: this.$refs.CesiumMap.addMarkers(marks);
* @return:
* @author: Kimber
* @updatetime: 2021/11/18(周四)
* @createtime: 2021/11/18(周四)
*/
addMarkers(list){
if(Object.prototype.toString.call(list) === '[object Array]'){
for(var item of list){
this.createMarker(item);
};
}
},
addMarker(item){
return this.createMarker(item);
},
createMarker(item){
return this.viewer.entities.add({
id: this.getGuid(),
name: item.name,
position: Cesium.Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude), Number(item.height) + 2),
//立广告牌
/* billboard: {
image: this.img,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
show: true, // default
width: 50, // default: undefined
height: 55
}, */
/* billboard:{ // 图片
image: './acting.png',
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
scale: 1,
} */
//字体标签样式
label: {
text: item.name,
font:'normal 32px MicroSoft YaHei',
scale:0.5,
color: Cesium.Color.WHITE,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
showBackground: true,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10.0, 8000.0),
// disableDepthTestDistance: 100.0,
pixelOffset: new Cesium.Cartesian2(0, -50) // 调整偏移位置
},
});
},
removeMarker(marker){
return first.viewer.entities.remove(marker);
},
}
}
</script>
<style lang="scss" scoped>
#cesiumContainer {height:100%;width:100%;}
#cesiumContainer .cesium-viewer{height:100%;width:100%;}
#cesiumContainer .cesium-viewer-cesiumWidgetContainer{height:100%;width:100%;}
#cesiumContainer .cesium-widget{width:100%;height:100%;touch-action:none;}
#cesiumContainer .cesium-widget canvas{width:100%;height:100%;touch-action:none;}
</style>
<template>
<div class="crud-opts">
<span class="crud-opts-left">
<!--左侧插槽-->
<slot name="left" />
<el-button
v-if="crud.optShow.add"
v-permission="permission.add"
class="filter-item"
size="mini"
type="primary"
icon="el-icon-plus"
@click="crud.toAdd"
>
新增
</el-button>
<el-button
v-if="crud.optShow.edit"
v-permission="permission.edit"
class="filter-item"
size="mini"
type="success"
icon="el-icon-edit"
:disabled="crud.selections.length !== 1"
@click="crud.toEdit(crud.selections[0])"
>
修改
</el-button>
<el-button
v-if="crud.optShow.del"
slot="reference"
v-permission="permission.del"
class="filter-item"
type="danger"
icon="el-icon-delete"
size="mini"
:loading="crud.delAllLoading"
:disabled="crud.selections.length === 0"
@click="toDelete(crud.selections)"
>
删除
</el-button>
<el-button
v-if="crud.optShow.download"
:loading="crud.downloadLoading"
:disabled="!crud.data.length"
class="filter-item"
size="mini"
type="warning"
icon="el-icon-download"
@click="crud.doExport"
>导出</el-button>
<!--右侧-->
<slot name="right" />
</span>
<el-button-group class="crud-opts-right">
<el-button
size="mini"
plain
type="info"
icon="el-icon-search"
@click="toggleSearch()"
/>
<el-button
size="mini"
icon="el-icon-refresh"
@click="crud.refresh()"
/>
<el-popover
placement="bottom-end"
width="150"
trigger="click"
>
<el-button
slot="reference"
size="mini"
icon="el-icon-s-grid"
>
<i
class="fa fa-caret-down"
aria-hidden="true"
/>
</el-button>
<el-checkbox
v-model="allColumnsSelected"
:indeterminate="allColumnsSelectedIndeterminate"
@change="handleCheckAllChange"
>
全选
</el-checkbox>
<el-checkbox
v-for="item in tableColumns"
:key="item.property"
v-model="item.visible"
@change="handleCheckedTableColumnsChange(item)"
>
{{ item.label }}
</el-checkbox>
</el-popover>
</el-button-group>
</div>
</template>
<script>
import CRUD, { crud } from '@crud/crud'
function sortWithRef(src, ref) {
const result = Object.assign([], ref)
let cursor = -1
src.forEach(e => {
const idx = result.indexOf(e)
if (idx === -1) {
cursor += 1
result.splice(cursor, 0, e)
} else {
cursor = idx
}
})
return result
}
export default {
mixins: [crud()],
props: {
permission: {
type: Object,
default: () => { return {} }
},
hiddenColumns: {
type: Array,
default: () => { return [] }
},
ignoreColumns: {
type: Array,
default: () => { return [] }
}
},
data() {
return {
tableColumns: [],
allColumnsSelected: true,
allColumnsSelectedIndeterminate: false,
tableUnwatcher: null,
// 忽略下次表格列变动
ignoreNextTableColumnsChange: false
}
},
watch: {
'crud.props.table'() {
this.updateTableColumns()
this.tableColumns.forEach(column => {
if (this.hiddenColumns.indexOf(column.property) !== -1) {
column.visible = false
this.updateColumnVisible(column)
}
})
},
'crud.props.table.store.states.columns'() {
this.updateTableColumns()
}
},
created() {
this.crud.updateProp('searchToggle', true)
},
methods: {
updateTableColumns() {
const table = this.crud.getTable()
if (!table) {
this.tableColumns = []
return
}
let cols = null
const columnFilter = e => e && e.type === 'default' && e.property && this.ignoreColumns.indexOf(e.property) === -1
const refCols = table.columns.filter(columnFilter)
if (this.ignoreNextTableColumnsChange) {
this.ignoreNextTableColumnsChange = false
return
}
this.ignoreNextTableColumnsChange = false
const columns = []
const fullTableColumns = table.$children.map(e => e.columnConfig).filter(columnFilter)
cols = sortWithRef(fullTableColumns, refCols)
cols.forEach(config => {
const column = {
property: config.property,
label: config.label,
visible: refCols.indexOf(config) !== -1
}
columns.push(column)
})
this.tableColumns = columns
},
toDelete(datas) {
this.$confirm(`确认删除选中的${datas.length}条数据?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.crud.delAllLoading = true
this.crud.doDelete(datas)
}).catch(() => {
})
},
handleCheckAllChange(val) {
if (val === false) {
this.allColumnsSelected = true
return
}
this.tableColumns.forEach(column => {
if (!column.visible) {
column.visible = true
this.updateColumnVisible(column)
}
})
this.allColumnsSelected = val
this.allColumnsSelectedIndeterminate = false
},
handleCheckedTableColumnsChange(item) {
let totalCount = 0
let selectedCount = 0
this.tableColumns.forEach(column => {
++totalCount
selectedCount += column.visible ? 1 : 0
})
if (selectedCount === 0) {
this.crud.notify('请至少选择一列', CRUD.NOTIFICATION_TYPE.WARNING)
this.$nextTick(function() {
item.visible = true
})
return
}
this.allColumnsSelected = selectedCount === totalCount
this.allColumnsSelectedIndeterminate = selectedCount !== totalCount && selectedCount !== 0
this.updateColumnVisible(item)
},
updateColumnVisible(item) {
const table = this.crud.props.table
const vm = table.$children.find(e => e.prop === item.property)
const columnConfig = vm.columnConfig
if (item.visible) {
// 找出合适的插入点
const columnIndex = this.tableColumns.indexOf(item)
vm.owner.store.commit('insertColumn', columnConfig, columnIndex + 1, null)
} else {
vm.owner.store.commit('removeColumn', columnConfig, null)
}
this.ignoreNextTableColumnsChange = true
},
toggleSearch() {
this.crud.props.searchToggle = !this.crud.props.searchToggle
}
}
}
</script>
<style>
.crud-opts {
padding: 4px 0;
display: -webkit-flex;
display: flex;
align-items: center;
}
.crud-opts .crud-opts-right {
margin-left: auto;
}
.crud-opts .crud-opts-right span {
float: left;
}
</style>
<!--分页-->
<template>
<el-pagination
:page-size.sync="page.size"
:total="page.total"
:current-page.sync="page.page"
style="margin-top: 8px;"
layout="total, prev, pager, next, sizes"
@size-change="crud.sizeChangeHandler($event)"
@current-change="crud.pageChangeHandler"
/>
</template>
<script>
import { pagination } from '@crud/crud'
export default {
mixins: [pagination()]
}
</script>
<!--搜索与重置-->
<template>
<span>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="crud.toQuery">搜索</el-button>
<el-button v-if="crud.optShow.reset" class="filter-item" size="mini" type="warning" icon="el-icon-refresh-left" @click="crud.resetQuery()">重置</el-button>
</span>
</template>
<script>
import { crud } from '@crud/crud'
export default {
mixins: [crud()],
props: {
itemClass: {
type: String,
required: false,
default: ''
}
}
}
</script>
<template>
<div>
<el-button v-permission="permission.edit" :loading="crud.status.cu === 2" :disabled="disabledEdit" size="mini" type="primary" icon="el-icon-edit" @click="crud.toEdit(data)" />
<el-popover v-model="pop" v-permission="permission.del" placement="top" width="180" trigger="manual" @show="onPopoverShow" @hide="onPopoverHide">
<p>{{ msg }}</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="doCancel">取消</el-button>
<el-button :loading="crud.dataStatus[crud.getDataId(data)].delete === 2" type="primary" size="mini" @click="crud.doDelete(data)">确定</el-button>
</div>
<el-button slot="reference" :disabled="disabledDle" type="danger" icon="el-icon-delete" size="mini" @click="toDelete" />
</el-popover>
</div>
</template>
<script>
import CRUD, { crud } from '@crud/crud'
export default {
mixins: [crud()],
props: {
data: {
type: Object,
required: true
},
permission: {
type: Object,
required: true
},
disabledEdit: {
type: Boolean,
default: false
},
disabledDle: {
type: Boolean,
default: false
},
msg: {
type: String,
default: '确定删除本条数据吗?'
}
},
data() {
return {
pop: false
}
},
methods: {
doCancel() {
this.pop = false
this.crud.cancelDelete(this.data)
},
toDelete() {
this.pop = true
},
[CRUD.HOOK.afterDelete](crud, data) {
if (data === this.data) {
this.pop = false
}
},
onPopoverShow() {
setTimeout(() => {
document.addEventListener('click', this.handleDocumentClick)
}, 0)
},
onPopoverHide() {
document.removeEventListener('click', this.handleDocumentClick)
},
handleDocumentClick(event) {
this.pop = false
}
}
}
</script>
import { initData, download } from '@/api/data'
import { parseTime, downloadFile } from '@/utils/index'
import Vue from 'vue'
/**
* CRUD配置
* @author moxun
* @param {*} options <br>
* @return crud instance.
* @example
* 要使用多crud时,请在关联crud的组件处使用crud-tag进行标记,如:<jobForm :job-status="dict.job_status" crud-tag="job" />
*/
function CRUD(options) {
const defaultOptions = {
tag: 'default',
// id字段名
idField: 'id',
// 标题
title: '',
// 请求数据的url
url: '',
// 表格数据
data: [],
// 选择项
selections: [],
// 待查询的对象
query: {},
// 查询数据的参数
params: {},
// Form 表单
form: {},
// 重置表单
defaultForm: () => {},
// 排序规则,默认 id 降序, 支持多字段排序 ['id,desc', 'createTime,asc']
sort: ['id,desc'],
// 等待时间
time: 50,
// CRUD Method
crudMethod: {
add: (form) => {},
del: (id) => {},
edit: (form) => {},
get: (id) => {}
},
// 主页操作栏显示哪些按钮
optShow: {
add: true,
edit: true,
del: true,
download: true,
reset: true
},
// 自定义一些扩展属性
props: {},
// 在主页准备
queryOnPresenterCreated: true,
// 调试开关
debug: false
}
options = mergeOptions(defaultOptions, options)
const data = {
...options,
// 记录数据状态
dataStatus: {},
status: {
add: CRUD.STATUS.NORMAL,
edit: CRUD.STATUS.NORMAL,
// 添加或编辑状态
get cu() {
if (this.add === CRUD.STATUS.NORMAL && this.edit === CRUD.STATUS.NORMAL) {
return CRUD.STATUS.NORMAL
} else if (this.add === CRUD.STATUS.PREPARED || this.edit === CRUD.STATUS.PREPARED) {
return CRUD.STATUS.PREPARED
} else if (this.add === CRUD.STATUS.PROCESSING || this.edit === CRUD.STATUS.PROCESSING) {
return CRUD.STATUS.PROCESSING
}
throw new Error('wrong crud\'s cu status')
},
// 标题
get title() {
return this.add > CRUD.STATUS.NORMAL ? `新增${crud.title}` : this.edit > CRUD.STATUS.NORMAL ? `编辑${crud.title}` : crud.title
}
},
msg: {
submit: '提交成功',
add: '新增成功',
edit: '编辑成功',
del: '删除成功'
},
page: {
// 页码
page: 0,
// 每页数据条数
size: 10,
// 总数据条数
total: 0
},
// 整体loading
loading: false,
// 导出的 Loading
downloadLoading: false,
// 删除的 Loading
delAllLoading: false
}
const methods = {
/**
* 通用的提示
*/
submitSuccessNotify() {
crud.notify(crud.msg.submit, CRUD.NOTIFICATION_TYPE.SUCCESS)
},
addSuccessNotify() {
crud.notify(crud.msg.add, CRUD.NOTIFICATION_TYPE.SUCCESS)
},
editSuccessNotify() {
crud.notify(crud.msg.edit, CRUD.NOTIFICATION_TYPE.SUCCESS)
},
delSuccessNotify() {
crud.notify(crud.msg.del, CRUD.NOTIFICATION_TYPE.SUCCESS)
},
// 搜索
toQuery() {
crud.page.page = 1
crud.refresh()
},
// 刷新
refresh() {
if (!callVmHook(crud, CRUD.HOOK.beforeRefresh)) {
return
}
return new Promise((resolve, reject) => {
crud.loading = true
// 请求数据
initData(crud.url, crud.getQueryParams()).then(data => {
const table = crud.getTable()
if (table && table.lazy) { // 懒加载子节点数据,清掉已加载的数据
table.store.states.treeData = {}
table.store.states.lazyTreeNodeMap = {}
}
crud.page.total = data.totalElements
crud.data = data.content
crud.resetDataStatus()
// time 毫秒后显示表格
setTimeout(() => {
crud.loading = false
callVmHook(crud, CRUD.HOOK.afterRefresh)
}, crud.time)
resolve(data)
}).catch(err => {
crud.loading = false
reject(err)
})
})
},
/**
* 启动添加
*/
toAdd() {
crud.resetForm()
if (!(callVmHook(crud, CRUD.HOOK.beforeToAdd, crud.form) && callVmHook(crud, CRUD.HOOK.beforeToCU, crud.form))) {
return
}
crud.status.add = CRUD.STATUS.PREPARED
callVmHook(crud, CRUD.HOOK.afterToAdd, crud.form)
callVmHook(crud, CRUD.HOOK.afterToCU, crud.form)
},
/**
* 启动编辑
* @param {*} data 数据项
*/
toEdit(data) {
crud.resetForm(JSON.parse(JSON.stringify(data)))
if (!(callVmHook(crud, CRUD.HOOK.beforeToEdit, crud.form) && callVmHook(crud, CRUD.HOOK.beforeToCU, crud.form))) {
return
}
crud.status.edit = CRUD.STATUS.PREPARED
crud.getDataStatus(crud.getDataId(data)).edit = CRUD.STATUS.PREPARED
callVmHook(crud, CRUD.HOOK.afterToEdit, crud.form)
callVmHook(crud, CRUD.HOOK.afterToCU, crud.form)
},
/**
* 启动删除
* @param {*} data 数据项
*/
toDelete(data) {
crud.getDataStatus(crud.getDataId(data)).delete = CRUD.STATUS.PREPARED
},
/**
* 取消删除
* @param {*} data 数据项
*/
cancelDelete(data) {
if (!callVmHook(crud, CRUD.HOOK.beforeDeleteCancel, data)) {
return
}
crud.getDataStatus(crud.getDataId(data)).delete = CRUD.STATUS.NORMAL
callVmHook(crud, CRUD.HOOK.afterDeleteCancel, data)
},
/**
* 取消新增/编辑
*/
cancelCU() {
const addStatus = crud.status.add
const editStatus = crud.status.edit
if (addStatus === CRUD.STATUS.PREPARED) {
if (!callVmHook(crud, CRUD.HOOK.beforeAddCancel, crud.form)) {
return
}
crud.status.add = CRUD.STATUS.NORMAL
}
if (editStatus === CRUD.STATUS.PREPARED) {
if (!callVmHook(crud, CRUD.HOOK.beforeEditCancel, crud.form)) {
return
}
crud.status.edit = CRUD.STATUS.NORMAL
crud.getDataStatus(crud.getDataId(crud.form)).edit = CRUD.STATUS.NORMAL
}
crud.resetForm()
if (addStatus === CRUD.STATUS.PREPARED) {
callVmHook(crud, CRUD.HOOK.afterAddCancel, crud.form)
}
if (editStatus === CRUD.STATUS.PREPARED) {
callVmHook(crud, CRUD.HOOK.afterEditCancel, crud.form)
}
// 清除表单验证
if (crud.findVM('form').$refs['form']) {
crud.findVM('form').$refs['form'].clearValidate()
}
},
/**
* 提交新增/编辑
*/
submitCU() {
if (!callVmHook(crud, CRUD.HOOK.beforeValidateCU)) {
return
}
crud.findVM('form').$refs['form'].validate(valid => {
if (!valid) {
return
}
if (!callVmHook(crud, CRUD.HOOK.afterValidateCU)) {
return
}
if (crud.status.add === CRUD.STATUS.PREPARED) {
crud.doAdd()
} else if (crud.status.edit === CRUD.STATUS.PREPARED) {
crud.doEdit()
}
})
},
/**
* 执行添加
*/
doAdd() {
if (!callVmHook(crud, CRUD.HOOK.beforeSubmit)) {
return
}
crud.status.add = CRUD.STATUS.PROCESSING
crud.crudMethod.add(crud.form).then(() => {
crud.status.add = CRUD.STATUS.NORMAL
crud.resetForm()
crud.addSuccessNotify()
callVmHook(crud, CRUD.HOOK.afterSubmit)
crud.toQuery()
}).catch(() => {
crud.status.add = CRUD.STATUS.PREPARED
callVmHook(crud, CRUD.HOOK.afterAddError)
})
},
/**
* 执行编辑
*/
doEdit() {
if (!callVmHook(crud, CRUD.HOOK.beforeSubmit)) {
return
}
crud.status.edit = CRUD.STATUS.PROCESSING
crud.crudMethod.edit(crud.form).then(() => {
crud.status.edit = CRUD.STATUS.NORMAL
crud.getDataStatus(crud.getDataId(crud.form)).edit = CRUD.STATUS.NORMAL
crud.editSuccessNotify()
crud.resetForm()
callVmHook(crud, CRUD.HOOK.afterSubmit)
crud.refresh()
}).catch(() => {
crud.status.edit = CRUD.STATUS.PREPARED
callVmHook(crud, CRUD.HOOK.afterEditError)
})
},
/**
* 执行删除
* @param {*} data 数据项
*/
doDelete(data) {
let delAll = false
let dataStatus
const ids = []
if (data instanceof Array) {
delAll = true
data.forEach(val => {
ids.push(this.getDataId(val))
})
} else {
ids.push(this.getDataId(data))
dataStatus = crud.getDataStatus(this.getDataId(data))
}
if (!callVmHook(crud, CRUD.HOOK.beforeDelete, data)) {
return
}
if (!delAll) {
dataStatus.delete = CRUD.STATUS.PROCESSING
}
return crud.crudMethod.del(ids).then(() => {
if (delAll) {
crud.delAllLoading = false
} else dataStatus.delete = CRUD.STATUS.PREPARED
crud.dleChangePage(1)
crud.delSuccessNotify()
callVmHook(crud, CRUD.HOOK.afterDelete, data)
crud.refresh()
}).catch(() => {
if (delAll) {
crud.delAllLoading = false
} else dataStatus.delete = CRUD.STATUS.PREPARED
})
},
/**
* 通用导出
*/
doExport() {
crud.downloadLoading = true
download(crud.url + '/download', crud.getQueryParams()).then(result => {
downloadFile(result, crud.title + '数据', 'xlsx')
crud.downloadLoading = false
}).catch(() => {
crud.downloadLoading = false
})
},
/**
* 获取查询参数
*/
getQueryParams: function() {
// 清除参数无值的情况
Object.keys(crud.query).length !== 0 && Object.keys(crud.query).forEach(item => {
if (crud.query[item] === null || crud.query[item] === '') crud.query[item] = undefined
})
Object.keys(crud.params).length !== 0 && Object.keys(crud.params).forEach(item => {
if (crud.params[item] === null || crud.params[item] === '') crud.params[item] = undefined
})
return {
page: crud.page.page - 1,
size: crud.page.size,
sort: crud.sort,
...crud.query,
...crud.params
}
},
// 当前页改变
pageChangeHandler(e) {
crud.page.page = e
crud.refresh()
},
// 每页条数改变
sizeChangeHandler(e) {
crud.page.size = e
crud.page.page = 1
crud.refresh()
},
// 预防删除第二页最后一条数据时,或者多选删除第二页的数据时,页码错误导致请求无数据
dleChangePage(size) {
if (crud.data.length === size && crud.page.page !== 1) {
crud.page.page -= 1
}
},
// 选择改变
selectionChangeHandler(val) {
crud.selections = val
},
/**
* 重置查询参数
* @param {Boolean} toQuery 重置后进行查询操作
*/
resetQuery(toQuery = true) {
const defaultQuery = JSON.parse(JSON.stringify(crud.defaultQuery))
const query = crud.query
Object.keys(query).forEach(key => {
query[key] = defaultQuery[key]
})
// 重置参数
this.params = {}
if (toQuery) {
crud.toQuery()
}
},
/**
* 重置表单
* @param {Array} data 数据
*/
resetForm(data) {
const form = data || (typeof crud.defaultForm === 'object' ? JSON.parse(JSON.stringify(crud.defaultForm)) : crud.defaultForm.apply(crud.findVM('form')))
const crudFrom = crud.form
for (const key in form) {
if (crudFrom.hasOwnProperty(key)) {
crudFrom[key] = form[key]
} else {
Vue.set(crudFrom, key, form[key])
}
}
// add by ghl 2020-10-04 页面重复添加信息时,下拉框的校验会存在,需要找工取消
if (crud.findVM('form').$refs['form']) {
crud.findVM('form').$refs['form'].clearValidate()
}
},
/**
* 重置数据状态
*/
resetDataStatus() {
const dataStatus = {}
function resetStatus(datas) {
datas.forEach(e => {
dataStatus[crud.getDataId(e)] = {
delete: 0,
edit: 0
}
if (e.children) {
resetStatus(e.children)
}
})
}
resetStatus(crud.data)
crud.dataStatus = dataStatus
},
/**
* 获取数据状态
* @param {Number | String} id 数据项id
*/
getDataStatus(id) {
return crud.dataStatus[id]
},
/**
* 用于树形表格多选, 选中所有
* @param selection
*/
selectAllChange(selection) {
// 如果选中的数目与请求到的数目相同就选中子节点,否则就清空选中
if (selection && selection.length === crud.data.length) {
selection.forEach(val => {
crud.selectChange(selection, val)
})
} else {
crud.getTable().clearSelection()
}
},
/**
* 用于树形表格多选,单选的封装
* @param selection
* @param row
*/
selectChange(selection, row) {
// 如果selection中存在row代表是选中,否则是取消选中
if (selection.find(val => { return crud.getDataId(val) === crud.getDataId(row) })) {
if (row.children) {
row.children.forEach(val => {
crud.getTable().toggleRowSelection(val, true)
selection.push(val)
if (val.children) {
crud.selectChange(selection, val)
}
})
}
} else {
crud.toggleRowSelection(selection, row)
}
},
/**
* 切换选中状态
* @param selection
* @param data
*/
toggleRowSelection(selection, data) {
if (data.children) {
data.children.forEach(val => {
crud.getTable().toggleRowSelection(val, false)
if (val.children) {
crud.toggleRowSelection(selection, val)
}
})
}
},
findVM(type) {
return crud.vms.find(vm => vm && vm.type === type).vm
},
notify(title, type = CRUD.NOTIFICATION_TYPE.INFO) {
crud.vms[0].vm.$notify({
title,
type,
duration: 2500
})
},
updateProp(name, value) {
Vue.set(crud.props, name, value)
},
getDataId(data) {
return data[this.idField]
},
getTable() {
return this.findVM('presenter').$refs.table
},
attchTable() {
const table = this.getTable()
this.updateProp('table', table)
const that = this
table.$on('expand-change', (row, expanded) => {
if (!expanded) {
return
}
const lazyTreeNodeMap = table.store.states.lazyTreeNodeMap
row.children = lazyTreeNodeMap[crud.getDataId(row)]
if (row.children) {
row.children.forEach(ele => {
const id = crud.getDataId(ele)
if (that.dataStatus[id] === undefined) {
that.dataStatus[id] = {
delete: 0,
edit: 0
}
}
})
}
})
}
}
const crud = Object.assign({}, data)
// 可观测化
Vue.observable(crud)
// 附加方法
Object.assign(crud, methods)
// 记录初始默认的查询参数,后续重置查询时使用
Object.assign(crud, {
defaultQuery: JSON.parse(JSON.stringify(data.query)),
// 预留4位存储:组件 主页、头部、分页、表单,调试查看也方便找
vms: Array(4),
/**
* 注册组件实例
* @param {String} type 类型
* @param {*} vm 组件实例
* @param {Number} index 该参数内部使用
*/
registerVM(type, vm, index = -1) {
const vmObj = {
type,
vm: vm
}
if (index < 0) {
this.vms.push(vmObj)
return
}
if (index < 4) { // 内置预留vm数
this.vms[index] = vmObj
return
}
this.vms.length = Math.max(this.vms.length, index)
this.vms.splice(index, 1, vmObj)
},
/**
* 取消注册组件实例
* @param {*} vm 组件实例
*/
unregisterVM(type, vm) {
for (let i = this.vms.length - 1; i >= 0; i--) {
if (this.vms[i] === undefined) {
continue
}
if (this.vms[i].type === type && this.vms[i].vm === vm) {
if (i < 4) { // 内置预留vm数
this.vms[i] = undefined
} else {
this.vms.splice(i, 1)
}
break
}
}
}
})
// 冻结处理,需要扩展数据的话,使用crud.updateProp(name, value),以crud.props.name形式访问,这个是响应式的,可以做数据绑定
Object.freeze(crud)
return crud
}
// hook VM
function callVmHook(crud, hook) {
if (crud.debug) {
console.log('callVmHook: ' + hook)
}
const tagHook = crud.tag ? hook + '$' + crud.tag : null
let ret = true
const nargs = [crud]
for (let i = 2; i < arguments.length; ++i) {
nargs.push(arguments[i])
}
// 有些组件扮演了多个角色,调用钩子时,需要去重
const vmSet = new Set()
crud.vms.forEach(vm => vm && vmSet.add(vm.vm))
vmSet.forEach(vm => {
if (vm[hook]) {
ret = vm[hook].apply(vm, nargs) !== false && ret
}
if (tagHook && vm[tagHook]) {
ret = vm[tagHook].apply(vm, nargs) !== false && ret
}
})
return ret
}
function mergeOptions(src, opts) {
const optsRet = {
...src
}
for (const key in src) {
if (opts.hasOwnProperty(key)) {
optsRet[key] = opts[key]
}
}
return optsRet
}
/**
* 查找crud
* @param {*} vm
* @param {string} tag
*/
function lookupCrud(vm, tag) {
tag = tag || vm.$attrs['crud-tag'] || 'default'
// function lookupCrud(vm, tag) {
if (vm.$crud) {
const ret = vm.$crud[tag]
if (ret) {
return ret
}
}
return vm.$parent ? lookupCrud(vm.$parent, tag) : undefined
}
/**
* crud主页
*/
function presenter(crud) {
if (crud) {
console.warn('[CRUD warn]: ' + 'please use $options.cruds() { return CRUD(...) or [CRUD(...), ...] }')
}
return {
data() {
// 在data中返回crud,是为了将crud与当前实例关联,组件观测crud相关属性变化
return {
crud: this.crud
}
},
beforeCreate() {
this.$crud = this.$crud || {}
let cruds = this.$options.cruds instanceof Function ? this.$options.cruds() : crud
if (!(cruds instanceof Array)) {
cruds = [cruds]
}
cruds.forEach(ele => {
if (this.$crud[ele.tag]) {
console.error('[CRUD error]: ' + 'crud with tag [' + ele.tag + ' is already exist')
}
this.$crud[ele.tag] = ele
ele.registerVM('presenter', this, 0)
})
this.crud = this.$crud['defalut'] || cruds[0]
},
methods: {
parseTime
},
created() {
for (const k in this.$crud) {
if (this.$crud[k].queryOnPresenterCreated) {
this.$crud[k].toQuery()
}
}
},
destroyed() {
for (const k in this.$crud) {
this.$crud[k].unregisterVM('presenter', this)
}
},
mounted() {
// 如果table未实例化(例如使用了v-if),请稍后在适当时机crud.attchTable刷新table信息
if (this.$refs.table !== undefined) {
this.crud.attchTable()
}
}
}
}
/**
* 头部
*/
function header() {
return {
data() {
return {
crud: this.crud,
query: this.crud.query
}
},
beforeCreate() {
this.crud = lookupCrud(this)
this.crud.registerVM('header', this, 1)
},
destroyed() {
this.crud.unregisterVM('header', this)
}
}
}
/**
* 分页
*/
function pagination() {
return {
data() {
return {
crud: this.crud,
page: this.crud.page
}
},
beforeCreate() {
this.crud = lookupCrud(this)
this.crud.registerVM('pagination', this, 2)
},
destroyed() {
this.crud.unregisterVM('pagination', this)
}
}
}
/**
* 表单
*/
function form(defaultForm) {
return {
data() {
return {
crud: this.crud,
form: this.crud.form
}
},
beforeCreate() {
this.crud = lookupCrud(this)
this.crud.registerVM('form', this, 3)
},
created() {
this.crud.defaultForm = defaultForm
this.crud.resetForm()
},
destroyed() {
this.crud.unregisterVM('form', this)
}
}
}
/**
* crud
*/
function crud(options = {}) {
const defaultOptions = {
type: undefined
}
options = mergeOptions(defaultOptions, options)
return {
data() {
return {
crud: this.crud
}
},
beforeCreate() {
this.crud = lookupCrud(this)
this.crud.registerVM(options.type, this)
},
destroyed() {
this.crud.unregisterVM(options.type, this)
}
}
}
/**
* CRUD钩子
*/
CRUD.HOOK = {
/** 刷新 - 之前 */
beforeRefresh: 'beforeCrudRefresh',
/** 刷新 - 之后 */
afterRefresh: 'afterCrudRefresh',
/** 删除 - 之前 */
beforeDelete: 'beforeCrudDelete',
/** 删除 - 之后 */
afterDelete: 'afterCrudDelete',
/** 删除取消 - 之前 */
beforeDeleteCancel: 'beforeCrudDeleteCancel',
/** 删除取消 - 之后 */
afterDeleteCancel: 'afterCrudDeleteCancel',
/** 新建 - 之前 */
beforeToAdd: 'beforeCrudToAdd',
/** 新建 - 之后 */
afterToAdd: 'afterCrudToAdd',
/** 编辑 - 之前 */
beforeToEdit: 'beforeCrudToEdit',
/** 编辑 - 之后 */
afterToEdit: 'afterCrudToEdit',
/** 开始 "新建/编辑" - 之前 */
beforeToCU: 'beforeCrudToCU',
/** 开始 "新建/编辑" - 之后 */
afterToCU: 'afterCrudToCU',
/** "新建/编辑" 验证 - 之前 */
beforeValidateCU: 'beforeCrudValidateCU',
/** "新建/编辑" 验证 - 之后 */
afterValidateCU: 'afterCrudValidateCU',
/** 添加取消 - 之前 */
beforeAddCancel: 'beforeCrudAddCancel',
/** 添加取消 - 之后 */
afterAddCancel: 'afterCrudAddCancel',
/** 编辑取消 - 之前 */
beforeEditCancel: 'beforeCrudEditCancel',
/** 编辑取消 - 之后 */
afterEditCancel: 'afterCrudEditCancel',
/** 提交 - 之前 */
beforeSubmit: 'beforeCrudSubmitCU',
/** 提交 - 之后 */
afterSubmit: 'afterCrudSubmitCU',
afterAddError: 'afterCrudAddError',
afterEditError: 'afterCrudEditError'
}
/**
* CRUD状态
*/
CRUD.STATUS = {
NORMAL: 0,
PREPARED: 1,
PROCESSING: 2
}
/**
* CRUD通知类型
*/
CRUD.NOTIFICATION_TYPE = {
SUCCESS: 'success',
WARNING: 'warning',
INFO: 'info',
ERROR: 'error'
}
export default CRUD
export {
presenter,
header,
form,
pagination,
crud
}
<script>
import { DatePicker, DatePickerOptions } from 'element-ui'
//import { calendarShortcuts } from '@/utils/shortcuts'
export default {
name: 'DateRangePicker',
mixins: [DatePicker],
props: {
type: {
type: String,
default: 'daterange'
},
valueFormat: {
type: String,
default: 'yyyy-MM-dd HH:mm:ss'
},
defaultTime: {
type: Array,
default: _ => ['00:00:00', '23:59:59']
},
pickerOptions: {
type: DatePickerOptions,
default: _ => {
//return { shortcuts: calendarShortcuts }
}
},
size: {
type: String,
default: 'small'
},
rangeSeparator: {
type: String,
default: ':'
},
startPlaceholder: {
type: String,
default: '开始日期'
},
endPlaceholder: {
type: String,
default: '结束日期'
}
}
}
</script>
import Vue from 'vue'
import { get as getDictDetail } from '@/api/system/dictDetail'
export default class Dict {
constructor(dict) {
this.dict = dict
}
async init(names, completeCallback) {
if (names === undefined || name === null) {
throw new Error('need Dict names')
}
const ps = []
names.forEach(n => {
Vue.set(this.dict.dict, n, {})
Vue.set(this.dict.label, n, {})
Vue.set(this.dict, n, [])
ps.push(getDictDetail(n).then(data => {
this.dict[n].splice(0, 0, ...data.content)
data.content.forEach(d => {
Vue.set(this.dict.dict[n], d.value, d)
Vue.set(this.dict.label[n], d.value, d.label)
})
}))
})
await Promise.all(ps)
completeCallback()
}
}
import Dict from './Dict'
const install = function(Vue) {
Vue.mixin({
data() {
if (this.$options.dicts instanceof Array) {
const dict = {
dict: {},
label: {}
}
return {
dict
}
}
return {}
},
created() {
if (this.$options.dicts instanceof Array) {
new Dict(this.dict).init(this.$options.dicts, () => {
this.$nextTick(() => {
this.$emit('dictReady')
})
})
}
}
})
}
export default { install }
/**
* Created by jiachenpan on 16/11/18.
*/
const Config = {
};
export function getVideoInfo(key){
return Config[key];
}
\ No newline at end of file
<!--
/**
* 荧石云播放器组件
* @param: {Object} opts [top, left, eventOutClose(事件超出容器后关闭, 默认false), showCloseBtn(默认false)]
* @example1:
npm install --save-dev ezuikit-js
1, 引入
import EZUIKitJs from '@/components/EZUIKitJs'
2, 注册
export default {
components: {
EZUIKitJs,
},
}
3, 创建
{
autoPlayer: // 是否自动播放
selectSeat: // 选择列表的位置 'right' || 'left' || 'none'
playerToParam // 根据传入参数播放 param[Object]
}
<EZUIKitJs ref="EZUIKit" selectSeat="right | none" autoPlayer="true"/>
* @author: Kimber
* @createtime: 2021/11/30(周二)
*/
-->
<template>
<div class="cv-inbox">
<div class="vi-select" v-if="selectSeat!=='none'" :class="{'dir-right':selectSeat==='right'}">
<el-select v-model="videoIndex" class="cus-select" placeholder="请选择视频" size="small" @change="selectVideo" label="操作">
<el-option v-for="(obj, index) in videoList" :label="obj.name" :value="index"></el-option>
</el-select>
</div>
<div class="cv-inbody">
<div class="EZUIKit-video" id="video-container"></div>
</div>
</div>
</template>
<script>
import EZUIKit from "ezuikit-js";
import axios from 'axios';
import { getVideoInfo } from './config'
const request = axios.create({});
request.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
export default {
name: "EZUIKit",
data() {
return {
videoIndex:0,
videoList:[],
}
},
props: {
selectSeat: String,
autoPlayer: String,
},
mounted(){
this.videoContainer = this.$el.querySelector("#video-container");
//var configInfo = getVideoInfo(this.$store.state.user.user.username);
//this.info = configInfo.info;
//this.videoList = configInfo.list;
if(this.autoPlayer !== 'false'){
// 播放视频
this.selectVideo(this.videoIndex);
};
// setTimeout(()=>{
// player.stop(); // 方法调用示例,10秒后关闭视频
// },10000)
},
methods: {
/**
* 获取Token
* @param: {Object} item
* @return:
* @author: Kimber
* @updatetime:
* @createtime: 2021/11/23(周二)
*/
playerVideo(item){
if(this.videoContainer.firstElementChild){
this.videoContainer.innerHTML = '';
setTimeout(() => {
this.createVideo(item);
}, 500);
}else{
this.createVideo(item);
};
},
createVideo(item){
this.getAccessToken(this.info.appKey, this.info.appSecret).then(accessToken => {
var url = this.getUrl(item);
this.player = new EZUIKit.EZUIKitPlayer({
autoplay: true,
id: "video-container",
accessToken:accessToken,
url: url,
template: "standard", // simple - 极简版;standard-标准版;security - 安防版(预览回放);voice-语音版;
// 视频上方头部控件
//header: ["capturePicture", "save", "zoom"], // 如果templete参数不为simple,该字段将被覆盖
//plugin: ['talk'], // 加载插件,talk-对讲
// 视频下方底部控件
// footer: ["talk", "broadcast", "hd", "fullScreen"], // 如果template参数不为simple,该字段将被覆盖
// audio: 1, // 是否默认开启声音 0 - 关闭 1 - 开启
// openSoundCallBack: data => console.log("开启声音回调", data),
// closeSoundCallBack: data => console.log("关闭声音回调", data),
// startSaveCallBack: data => console.log("开始录像回调", data),
// stopSaveCallBack: data => console.log("录像回调", data),
// capturePictureCallBack: data => console.log("截图成功回调", data),
// fullScreenCallBack: data => console.log("全屏回调", data),
// getOSDTimeCallBack: data => console.log("获取OSDTime回调", data),
});
})
},
/**
* 获取Token
* @param: {String} appKey
* @param: {String} appSecret
* @example1: getAccessToken('appKey', 'appSecret').then(accessToken => {});
* @return:
* @author: Kimber
* @updatetime:
* @createtime: 2021/9/1
*/
getAccessToken(appKey, appSecret){
var dataJson = 'appKey='+appKey+'&appSecret='+appSecret;
return request.post("/ys7com", dataJson).then(res=>{
var data = res.data || {};
if (data['code'] == '200') {
return data['data']['accessToken']
}else{
return null
}
}).catch(err=>{
console.log(err);
return err
})
},
getUrl(item){
var captcha = item.captcha ? item.captcha + '@' : '';
var id = item.id || this.info.id || '';
return 'ezopen://'+captcha+'open.ys7.com/'+id+'/'+item.channel;
},
// 视频选择事件
selectVideo(index){
var item = this.videoList[index];
this.playerVideo(item)
},
playerToParam(param){
this.info = {
id: param.id,
appKey:param.appKey,
appSecret:param.appSecret,
};
this.playerVideo(param)
},
// 视频选择事件
playVideoName(key){
var configInfo = getVideoInfo(key);
if(configInfo && configInfo.info){
this.info = configInfo.info;
this.videoList = configInfo.list;
var item = this.videoList[0];
this.playerVideo(item)
}else{
this.videoContainer.innerHTML = '';
};
},
}
};
</script>
<style lang="scss">
.cv-inbox{
position:relative;height:100%;width:100%;display:flex;flex-direction:column;
.vi-select{
.cus-select{
margin:5px;
input{display:inline-block;width:150px;border:1px solid #d0d2ff;background-color:#014468;
color:#d0d2ff;font-size:12px;
}
.el-input{}
.el-input__inner{
height:20px;line-height:20px
}
.el-input__suffix-inner{
.el-select__caret{line-height:20px}
}
}
}
.dir-right{text-align:right;}
.cv-inbody{
flex:1;position:relative;
.EZUIKit-video{
background-color:#01050f;
position:absolute;top:0;left:0;height:100%;width:100%;
iframe{height:100%;width:100%;}
}
}
}
</style>
<!-- @author zhengjie -->
<template>
<div class="icon-body">
<el-input v-model="name" style="position: relative;" clearable placeholder="请输入图标名称" @clear="filterIcons" @input.native="filterIcons">
<i slot="suffix" class="el-icon-search el-input__icon" />
</el-input>
<div class="icon-list">
<div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)">
<svg-icon :icon-class="item" style="height: 30px;width: 16px;" />
<span>{{ item }}</span>
</div>
</div>
</div>
</template>
<script>
import icons from './requireIcons'
export default {
name: 'IconSelect',
data() {
return {
name: '',
iconList: icons
}
},
methods: {
filterIcons() {
this.iconList = icons
if (this.name) {
this.iconList = this.iconList.filter(item => item.includes(this.name))
}
},
selectedIcon(name) {
this.$emit('selected', name)
document.body.click()
},
reset() {
this.name = ''
this.iconList = icons
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.icon-body {
width: 100%;
padding: 10px;
.icon-list {
height: 200px;
overflow-y: scroll;
div {
height: 30px;
line-height: 30px;
margin-bottom: -5px;
cursor: pointer;
width: 33%;
float: left;
}
span {
display: inline-block;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
}
}
</style>
const req = require.context('../../assets/icons/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys()
const re = /\.\/(.*)\.svg/
const icons = requireAll(req).map(i => {
return i.match(re)[1]
})
export default icons
<template>
<div v-loading="loading" :style="'height:'+ height">
<iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" />
</div>
</template>
<script>
export default {
props: {
src: {
type: String,
required: true
}
},
data() {
return {
height: document.documentElement.clientHeight - 94.5 + 'px;',
loading: true
}
},
mounted: function() {
setTimeout(() => {
this.loading = false
}, 230)
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 94.5 + 'px;'
}
}
}
</script>
import layer from './layer';
import Vue from 'vue'
var Layers = function(opts){
// 这里我们return一个新的Vue实例并且将实例挂载到我们刚创建的DOM节点上
return new Vue({
render: (create) => {
return create(layer, {
props: {
text: '111111111',
options:opts,
onload: function(){
console.log('onload ________________ ', 4444444444444);
}
}
})
},
}).$mount()
return ;
layer.install = function(Vue) {
console.log('install ________________ ', Vue);
var Layer = Vue.component('layer', layer);
new Layer({data:{aaa:'1111111111111'}})
};
Vue.use(layer)
return ;
var Layer = Vue.component(layer.name, {data: function(ssss){
console.log('ssss ________________ ', ssss);
}, template:'<button >点击计算点击次数:</button>'});
Vue.component('layer', layer)
console.log('Layer ________________ ', new Layer({data:{}}));
/* Vue.component("counter",{ //1.组件名为"conter"; 2.data 写函数; 3.template 写组件的内容(元素和触发的事件)
data:function(){
return {count:0}
},
//template 是模板的意思,在 html 里面是一个可以同时控制多个子元素的父元素。在这里定义了组件的内容
template:'<button v-on:click="count++">点击计算点击次数:{{count}}次</button>'
}); */
//var aaa = new Layer(layer);
//console.log('Layers ________________ ', aaa, options);
/* new Vue({
el:layer
}) */
};
export {
Layers,
}
\ No newline at end of file
<template>
<el-dialog append-to-body :close-on-click-modal="false" :before-close="cancelForm" :visible.sync="visible" :title="options.title" width="520px">
<div class="class">33333333333333333333333333</div>
</el-dialog>
</template>
<script>
export default {
name: 'formLayer',
data() {
return {
visible:false
}
},
props:{
options: {
type: Object,
default: {},
},
},
watch: {
},
created() {
var that = this;
console.log('created ________________ ', this);
this.$nextTick(() => {
//this.Map = Map;
})
this.visible = true;
},
methods: {
cancelForm(param){
this.visible = false;
setTimeout(() => {
this.$destroy()
}, 1000)
},
}
}
</script>
<style lang="scss" scoped>
.amap{height:100%;width:100%;}
</style>
<template>
<div :class="{'hidden':hidden}" class="pagination-container">
<el-pagination
:background="background"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:total="total"
v-bind="$attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script>
import { scrollTo } from '@/utils/scroll-to'
export default {
name: 'Pagination',
props: {
total: {
required: true,
type: Number
},
page: {
type: Number,
default: 1
},
limit: {
type: Number,
default: 20
},
pageSizes: {
type: Array,
default() {
return [10, 20, 30, 50]
}
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
background: {
type: Boolean,
default: true
},
autoScroll: {
type: Boolean,
default: true
},
hidden: {
type: Boolean,
default: false
}
},
computed: {
currentPage: {
get() {
return this.page
},
set(val) {
this.$emit('update:page', val)
}
},
pageSize: {
get() {
return this.limit
},
set(val) {
this.$emit('update:limit', val)
}
}
},
methods: {
handleSizeChange(val) {
this.$emit('pagination', { page: this.currentPage, limit: val })
if (this.autoScroll) {
scrollTo(0, 800)
}
},
handleCurrentChange(val) {
this.$emit('pagination', { page: val, limit: this.pageSize })
if (this.autoScroll) {
scrollTo(0, 800)
}
}
}
}
</script>
<style scoped>
.pagination-container {
background: #fff;
padding: 32px 16px;
}
.pagination-container.hidden {
display: none;
}
</style>
<template>
<router-view />
</template>
import permission from './permission'
const install = function(Vue) {
Vue.directive('permission', permission)
}
if (window.Vue) {
window['permission'] = permission
Vue.use(install); // eslint-disable-line
}
permission.install = install
export default permission
import store from '@/store'
export default {
inserted(el, binding) {
const { value } = binding
const roles = store.getters && store.getters.roles
if (value && value instanceof Array) {
if (value.length > 0) {
const permissionRoles = value
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
}
} else {
throw new Error(`使用方式: v-permission="['admin','editor']"`)
}
}
}
<template>
<div>
<svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" />
</div>
</template>
<script>
import screenfull from 'screenfull'
export default {
name: 'Screenfull',
data() {
return {
isFullscreen: false
}
},
mounted() {
this.init()
},
beforeDestroy() {
this.destroy()
},
methods: {
click() {
if (!screenfull.enabled) {
this.$message({
message: 'you browser can not work',
type: 'warning'
})
return false
}
screenfull.toggle()
},
change() {
this.isFullscreen = screenfull.isFullscreen
},
init() {
if (screenfull.enabled) {
screenfull.on('change', this.change)
}
},
destroy() {
if (screenfull.enabled) {
screenfull.off('change', this.change)
}
}
}
}
</script>
<style scoped>
.screenfull-svg {
display: inline-block;
cursor: pointer;
fill: #5a5e66;;
width: 20px;
height: 20px;
vertical-align: 10px;
}
</style>
<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :href="iconName" />
</svg>
</template>
<script>
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
import { isExternal } from '@/utils/validate'
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
/* vertical-align: -0.15em; */
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
display: inline-block;
}
</style>
<!--
/**
* 表单通用组件
* @example1:
1, 引入
import cuTable from '@/components/cuTable';
2, 注册
export default {
components: {
cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
}
},
mounted(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
},
methods: {
loadData(searchItem) {
var that = this;
//reqApi.common.getRequst.call(this, searchItem);
},
}
}
3, 创建
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
/>
#4, 使用
* @author: Kimber
* @createtime: 2022/4/22(周五)
*/
-->
<template>
<!--工具栏-->
<div class="head-container" v-if="form.config.search && form.config.search[0]">
<!-- 搜索 -->
<template v-for="(item, index) in form.config.search">
<label v-if="item.name" class="el-form-item-label">{{item.name}}</label>
<template v-if="item.type==='string'">
<el-input v-model="form.query[item.word]" clearable :placeholder="'请输入'+item.name" :style="'width:'+item.width" @clear="item.clear && item.clear.call(_self.$parent)"/>
</template>
<template v-if="item.type==='select'">
<el-select v-model="form.query[item.word]" :placeholder="'请选择'+item.name" size="small" :style="'width:'+(item.width || 'auto')" :disabled="item.disabled" clearable @change="onEventInfos(item.change)" @clear="item.clear && item.clear.call(_self.$parent)">
<el-option v-for="obj in Dict.selectList[item.word]" :label="obj[item.key] || obj.name" :value="obj[item.val] || obj.value" ></el-option>
</el-select>
</template>
<template v-else-if="item.type === 'checkbox'">
<el-checkbox v-model="form.query[item.word]" :label="item.label"></el-checkbox>
</template>
<template v-else-if="item.type.indexOf('date') > -1">
<el-date-picker
v-model="form.query[item.word]"
:style="'width:'+item.width"
:type="item.type"
:value-format="item.format || 'yyyy-MM-dd'"
:default-time="item.defaultTime"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
clearable
@change="item.change && item.change.call(_self, $event)"
>
</el-date-picker>
</template>
<el-button v-else-if="item.type==='button'" size="mini" :type="item.btntype || 'success'" :icon="item.icon" @click="item.click && item.click.call(_self.$parent, $event)">{{item.label}}</el-button>
</template>
</div>
</template>
<script>
export default {
data() {
return {
}
},
props:{
form: {
type: Object,
default: {},
},
Dict: {
type: Object,
default: {},
},
},
beforeCreate(){
},
created(){
},
mounted() {
},
methods: {
onEventInfos:qf.vue.onEventInfos,
},
}
</script>
<style lang="scss" scope>
.head-container{
.el-form-item-label{
font-weight:500;margin-left:15px;
&:first-child{margin-left:0;}
}
.el-button{margin-left:20px;}
.el-checkbox{margin-right:5px;}
}
</style>
<template>
<el-color-picker
v-model="theme"
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d']"
class="theme-picker"
popper-class="theme-picker-dropdown"
/>
</template>
<script>
const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color
import Cookies from 'js-cookie'
export default {
data() {
return {
chalk: '', // content of theme-chalk css
theme: ''
}
},
computed: {
defaultTheme() {
return this.$store.state.settings.theme
}
},
watch: {
defaultTheme: {
handler: function(val, oldVal) {
this.theme = val
},
immediate: true
},
async theme(val) {
Cookies.set('theme', val, { expires: 365 })
const oldVal = this.chalk ? this.theme : Cookies.get('theme') ? Cookies.get('theme') : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
let styleTag = document.getElementById(id)
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
styleTag.innerText = newStyle
}
}
if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
await this.getCSSString(url, 'chalk')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
})
styles.forEach(style => {
const { innerText } = style
if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
})
this.$emit('change', val)
}
},
methods: {
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
},
getCSSString(url, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
}
xhr.open('GET', url)
xhr.send()
})
},
getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',')
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
}
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
const clusters = [theme]
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
return clusters
}
}
}
</script>
<style>
.theme-message,
.theme-picker-dropdown {
z-index: 99999 !important;
}
.theme-picker .el-color-picker__trigger {
height: 26px !important;
width: 26px !important;
padding: 2px;
}
.theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
}
</style>
<template>
<div>
<input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick">
<div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">
拖拽excel文件到此处 或者
<el-button :loading="loading" style="margin-left:16px;" size="mini" type="primary" @click="handleUpload">
浏览
</el-button>
</div>
</div>
</template>
<script>
import XLSX from 'xlsx'
export default {
props: {
beforeUpload: Function, // eslint-disable-line
onSuccess: Function// eslint-disable-line
},
data() {
return {
loading: false,
excelData: {
header: null,
results: null
}
}
},
methods: {
generateData({ header, results }) {
this.excelData.header = header
this.excelData.results = results
this.onSuccess && this.onSuccess(this.excelData)
},
handleDrop(e) {
e.stopPropagation()
e.preventDefault()
if (this.loading) return
const files = e.dataTransfer.files
if (files.length !== 1) {
this.$message.error('只支持单个文件上传!')
return
}
const rawFile = files[0]
if (!this.isExcel(rawFile)) {
this.$message.error('只支持.xlsx, .xls, .csv 格式文件')
return false
}
this.upload(rawFile)
e.stopPropagation()
e.preventDefault()
},
handleDragover(e) {
e.stopPropagation()
e.preventDefault()
e.dataTransfer.dropEffect = 'copy'
},
handleUpload() {
this.$refs['excel-upload-input'].click()
},
handleClick(e) {
const files = e.target.files
const rawFile = files[0] // only use files[0]
if (!rawFile) return
this.upload(rawFile)
},
upload(rawFile) {
this.$refs['excel-upload-input'].value = null // fix can't select the same excel
if (!this.beforeUpload) {
this.readerData(rawFile)
return
}
const before = this.beforeUpload(rawFile)
if (before) {
this.readerData(rawFile)
}
},
readerData(rawFile) {
this.loading = true
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = e => {
const data = e.target.result
const workbook = XLSX.read(data, { type: 'array' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const header = this.getHeaderRow(worksheet)
const results = XLSX.utils.sheet_to_json(worksheet)
this.generateData({ header, results })
this.loading = false
resolve()
}
reader.readAsArrayBuffer(rawFile)
})
},
getHeaderRow(sheet) {
const headers = []
const range = XLSX.utils.decode_range(sheet['!ref'])
let C
const R = range.s.r
/* start in the first row */
for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
/* find the cell in the first row */
let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
headers.push(hdr)
}
return headers
},
isExcel(file) {
return /\.(xlsx|xls|csv)$/.test(file.name)
}
}
}
</script>
<style scoped>
.excel-upload-input{
display: none;
z-index: -9999;
}
.drop{
border: 2px dashed #bbb;
width: 600px;
height: 160px;
line-height: 160px;
margin: 0 auto;
font-size: 24px;
border-radius: 5px;
text-align: center;
color: #bbb;
position: relative;
}
</style>
<!--
/**
* 表单通用组件
* @example1:
1, 引入
import cuForm from '@/components/cuForm';
2, 注册
export default {
components: {
cuForm
},
data() {
return {
Dict:{selectList:[]},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.search = this.Dict.search;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
},
methods: {
upload(e, key){
},
submitForm(form, item){
},
}
}
3, 创建
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:upload="upload"
/>
#4, 使用
* @author: Kimber
* @updatetime: 2022/5/19(周四)
* @createtime: 2021/12/09
*/
-->
<template>
<el-dialog id="printJS-form" class="qyzz-dialog" append-to-body :close-on-click-modal="false" :before-close="cancelForm" :visible.sync="form.visible" :title="form.title" :width="form.config.formWidth || '50%'">
<el-form :model="form.item" :rules="rules" :ref="ref" :inline="true" size="small" :label-width="(form.config.labelWidth || 80) + 'px'">
<el-form-item v-for="(item, key) in Dict.baseInfo" :prop="item.rule || key" :label="item.name" v-if="item.form !== 0" :style="item.style">
<template v-if="item.type === 'img'">
<div class="img-upload">
<label class="upload-area" for="imgUpload">
<div class="img-box" v-show="form.item[key]">
<img :src="form.item[key]" v-model="form.item[key]">
</div>
<div class="upload-layer el-icon-plus" :class="{'show':!form.item[key]}">
<input type="file" style="display:none" id="imgUpload" @change="item.change && item.change.call(_self.$parent, $event, key)">
</div>
</label>
</div>
</template>
<template v-else-if="new String(item.type).indexOf('date') === 0">
<el-date-picker
v-model="form.item[key]"
:type="item.type"
:value-format="item.format || 'yyyy-MM-dd'"
:disabled="item.disabled"
placeholder="选择日期时间">
</el-date-picker>
</template>
<template v-else-if="item.type === 'select'">
<el-select v-model="form.item[key]" :placeholder="item.name" size="small" :style="'width:'+(item.width || 'auto')" :disabled="item.disabled" :multiple="item.multiple || false" @change="eventTransmit(item.change)">
<el-option v-for="obj in Dict.selectList[key]" :label="obj[item.key||'name']" :value="obj[item.val] || obj.value" ></el-option>
</el-select>
</template>
<template v-else-if="item.type === 'filename'">
<div class="file-box">
<div v-if="!!form.item[key]" style="width:260px;">
{{form.item[key]}} <label class="el-icon-edit btn2" for="cufilename"></label>
</div>
<label v-else class="upload-area el-icon-folder-add" for="cufilename" style="width:260px;font-size:30px"></label>
<input type="file" style="display:none" id="cufilename" @change="item.change && item.change.call(_self.$parent, $event, key)">
</div>
</template>
<template v-else-if="item.type === 'textarea'">
<el-input v-model="form.item[key]" :style="'width:'+(item.width || 380)+'px;'" type="textarea" :rows="item.rows" :disabled="item.disabled"/>
</template>
<template v-else-if="item.type === 'number'">
<el-input-number v-model.number="form.item[key]" :min="0" controls-position="right" />
</template>
<template v-else-if="item.type === 'text'">
<div class="form-text">{{form.item[key]}}</div>
</template>
<template v-else-if="item.type === 'radio'">
<el-radio-group v-model="form.item[key]" @change="eventTransmit(item.change)">
<el-radio v-for="obj in Dict.selectList[key]" :label="obj[item.val]" >{{obj[item.key]}}</el-radio>
</el-radio-group>
</template>
<template v-else-if="item.type === 'checkbox'">
<el-checkbox-group v-model="form.item[key]" @change="eventTransmit(item.change)">
<el-checkbox v-for="obj in Dict.selectList[key]" :label="obj[item.val]" >{{obj[item.key]}}</el-checkbox>
</el-checkbox-group>
</template>
<template v-else-if="item.type === 'map'">
<el-input v-model="form.item[key]" :style="'width:'+(item.width || 260)+'px;'" :placeholder="item.placeholder || ('请输入' + item.name)" :disabled="item.disabled"/>
<div class="map-ctn" style="width:80%;height:180px;">
<cu-amap
ref="amap"
:options="item.mapConfig.options"
:parent="_self"
/>
</div>
</template>
<template v-else>
<el-input v-if="item.ruleType==='number'" v-model.number="form.item[key]" :style="'width:'+(item.width || 260)+'px;'" :placeholder="item.placeholder || ('请输入' + item.name)" :disabled="item.disabled" @input="item.input && item.input.call(_self, $event)"/>
<el-input v-else v-model="form.item[key]" :style="'width:'+(item.width || 260)+'px;'" :placeholder="item.placeholder || ('请输入' + item.name)" :disabled="item.disabled" @input="item.input && item.input.call(_self, $event)"/>
</template>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="cancelForm">取消</el-button>
<el-button :loading="form.status.cu === 2" type="primary" @click="submit($refs[ref], form.item)">确认</el-button>
<!-- <el-button v-for="(item, i) in form.config.formBtn" :type="item.type" @click="item.callback && item.callback.call(_self, $refs[ref], form.item)">{{item.name}}</el-button> -->
</div>
</el-dialog>
</template>
<script>
import cuAmap from '@/components/AMap';
export default {
data() {
return {
ref:'form1',
}
},
components: {cuAmap},
props:{
form: {
type: Object,
default: {},
},
rules: {
type: Object,
default: {},
},
Dict: {
type: Object,
default: {},
},
submit: {
type: Function,
default: () => {}
},
},
beforeCreate(){
},
created(){
},
mounted() {
},
methods: {
eventTransmit:qf.vue.onEventInfos,
cancelForm(){this.$parent.form.visible = false;},
},
}
</script>
<style lang="scss" scope>
.qyzz-dialog{
display:flex;justify-content:center;align-items:center;
.el-form .block{display:block;}
.el-form .flex{display:flex;}
.img-upload{
position:relative;
.img-box{width:300px;height:200px;}
img{display:block;border:0;height:100%;width:100%;}
.upload-layer{
width:250px;height:100px;display:none;justify-content:center;align-items:center;
background-color:#fff;
border:1px dashed rgba(0, 0, 0, 0.1);background-color:rgba(0, 0, 0, 0.05);cursor:pointer;color:#999;
flex-direction:column;justify-content:center;align-items:center;
&:before{display:block;font-size:34px;}
&:after{display:block;content:"上传图片,支持小于2MB的图片";line-height:18px;}
}
.upload-area{
height:100%;width:100%;
}
.upload-layer.show{display:flex;}
}
.el-dialog{
margin-top:0 !important;
.el-dialog__body{
overflow-y:auto;max-height:78vh;
.el-form-item{
display:inline-flex;align-items:center;
.el-form-item__content{flex:1;}
}
.form-text{line-height:20px;}
.el-form-item__label{line-height:1.5;}
}
}
.file-box{
.btn2{font-size:23px;margin-left:10px;color:#48A2FF;cursor:pointer;}
}
}
</style>
\ No newline at end of file
<!--
/**
* 表单通用组件
* @example1:
1, 引入
import cuTable from '@/components/cuTable';
2, 注册
export default {
components: {
cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
}
},
mounted(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
},
methods: {
loadData(searchItem) {
var that = this;
//reqApi.common.getRequst.call(this, searchItem);
},
}
}
3, 创建
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
/>
#4, 使用
* @author: Kimber
* @updatetime: 2022/5/13(周五)
* @createtime: 2021/12/09
*/
-->
<template>
<div class="content cu-table">
<el-table :data="table.dataList" v-loading="table.loading" border style="width:auto" :row-class-name="tableRowClassName">
<template v-for="(item, key) in Dict.baseInfo" v-if="item.table !== 0">
<el-table-column v-if="item.type === 'select'" :prop="key" :label="item.name">
<template slot-scope="scope">
<template v-for="sitem in Dict.selectList[key]">
<template v-if="typeof scope.row[key] === 'object'">
<span v-for="val in scope.row[key]" v-if="val===sitem[item.val||'value']">
{{sitem[item.key||'name']}}
</span>
</template>
<span v-else-if="sitem[item.val||'value']===scope.row[key]" class="orange" :style="'color:'+(sitem.color||'')+';'">
<i v-if="item.icon" :class="item.icon" style="font-size:16px;"></i>{{sitem[item.key||'name']}}
</span>
</template>
</template>
</el-table-column>
<el-table-column v-else-if="item.type === 'img'" :prop="key" :label="item.name" width="150px">
<img slot-scope="scope" :src="scope.row[key]" style="width:100%;border:0;height:auto;"/>
</el-table-column>
<el-table-column v-else-if="item.type === 'tableFormat'" :prop="key" :label="item.name">
<template slot-scope="scope">{{item.tableFormat.call(scope.row, scope.row[key])}}</template>
</el-table-column>
<el-table-column v-else-if="item.type === 'button'" :prop="key" :label="item.name" :align="item.align">
<el-button size="mini" slot-scope="scope" :type="item.btnType" :icon="item.icon" @click="item.click.call(_self, scope.row[key])">{{item.name}}</el-button>
</el-table-column>
<el-table-column v-else :prop="key" :label="item.name"></el-table-column>
</template>
<el-table-column v-if="config.buttons && config.buttons[0]" label="操作" :width="(config.operWidth || 180)+'px'" align="center" fixed="right">
<template slot-scope="scope">
<el-button v-for="(bitem, i) in config.buttons" size="mini" :type="bitem.type" :icon="bitem.icon" :disabled="bitem.isvalid && (typeof bitem.isvalid==='function'?bitem.isvalid(scope.row):!scope.row[bitem.isvalid])" @click="bitem.callback ? bitem.callback.call(_self, scope.row, $event) : btnClick(scope.row, bitem.fn)"></el-button>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<el-pagination v-if="config.pagination!==false" :total="table.total" :current-page="table.page" style="margin-top:8px;" layout="total, prev, pager, next, sizes" @size-change="sizeChange" @current-change="pageChange" />
</div>
</template>
<script>
var watchParams = {};
export default {
data() {
return {
loading: false,
}
},
props:{
table: {
type: Object,
default: {},
},
Dict: {
type: Object,
default: {},
},
config: {
type: Object,
default: {},
},
loadData:{
type: Function,
default: () => {}
},
},
beforeCreate(){
},
created(){
},
mounted() {
},
/* watch:{
'form.item.paperfilename':{
immediate:true,
handler(aa){
this.form.item.paperfilename = aa;
},
},
}, */
methods: {
tableRowClassName({row, rowIndex}) {
if (rowIndex === 1) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}return '';
},
pageChange(e) {
this.table.page = e
this.loadData()
},
sizeChange(e) {
this.table.page = 1
this.table.size = e
this.loadData()
},
btnClick(row, fnName){
new Function('this.$parent.'+fnName+'('+JSON.stringify(row)+')').call(this);
},
},
}
</script>
<style lang="scss" scope>
.cu-table{
.el-table{
font-size:14px;
thead{
th{color:#666;background-color:#f8f8f8;}
}
tbody{color:#777;}
}
.content-between{
padding-right:10px;height:40px;line-height:40px;
.r-btn{padding:5px 10px;border:1px solid #58ACFF;border-radius:5px;}
}
.el-button{margin-left:5px;}
}
</style>
\ No newline at end of file
import Vue from 'vue'
//import Element from 'element-ui'
//import './assets/icons' // icon
// global css
import './assets/styles/common.css'
import App from './EdgeApp'
import store from './store'
import router from './router/routers'
import './router/index' // permission control
Vue.config.productionTip = false
new Vue({
el: '#edge',
router,
store,
render: h => h(App)
});
Vue.__proto__.$state = store;
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews">
<router-view :key="key" />
</keep-alive>
</transition>
<footer v-if="$route.path!=='/dashboard'" class="page-footer"></footer>
<!-- <div v-if="$store.state.settings.showFooter" id="el-main-footer">
<span v-html="$store.state.settings.footerTxt" />
<span></span>
<a href="https://beian.miit.gov.cn" target="_blank">{{ $store.state.settings.caseNumber }}</a>
</div> -->
<!-- <div class="page-inline">
</div> -->
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
cachedViews() {
return this.$store.state.tagsView.cachedViews
},
key() {
return this.$route.path
}
},
mounted() {},
}
</script>
<style lang="scss" scoped>
.app-main {
/* 50= navbar 50 */
//min-height: calc(100vh - 50px);
width: 100%;
position: relative;
overflow: hidden;
/* overflow-y: auto; */
flex:1;
display:flex;
flex-direction:column;
//padding:.925vh 0;
background-color:#00154e;
}
//.page-inline{height:100%;width:100%;display:flex;}
.page-footer{
display:flex;justify-content:center;background-color:#fff;line-height:2;
&:after{
color:#888;display:inline-block;font-weight:bold;
content:'© ⋅ 技术支持:威海晶合数字矿山技术有限公司';
}
}
</style>
<style lang="scss">
// fix css style bug in open el-dialog
.el-popup-parent--hidden {
.fixed-header {
padding-right: 15px;
}
}
</style>
<template>
<div class="mian-navbar">
<div class="title-ctn">
<h2 v-if="!!pondName">{{pondName}}<!-- 安全监测系统 --></h2>
</div>
<div class="navbar">
<div class="right">
<div class="right-menu">
<div>
<el-tooltip content="风险大屏" v-if="risk_entrance" effect="dark" placement="bottom">
<a class="el-icon-data-line" href="/edge/ScreenFX" target="_blank" ></a>
</el-tooltip>
<el-tooltip content="可视化大屏" effect="dark" placement="bottom">
<a class="el-icon-s-platform" href="/edge/Screen" target="_blank" ></a>
</el-tooltip>
</div>
<!-- <template >
<el-tooltip content="全屏缩放" effect="dark" placement="bottom">
<screenfull id="screenfull" class="right-menu-item hover-effect" />
</el-tooltip>
</template> -->
</div>
<div class="navbar-line">
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper el-icon-caret-bottom">
<img :src="user.avatarName ? baseApi + '/avatar/' + user.avatarName : Avatar" class="user-avatar">
<span>{{user.nickName}}</span>
</div>
<el-dropdown-menu slot="dropdown">
<!-- <span style="display:block;" @click="show = true">
<el-dropdown-item>
布局设置
</el-dropdown-item>
</span> -->
<router-link to="/user/center">
<el-dropdown-item>
个人中心
</el-dropdown-item>
</router-link>
<span style="display:block;" @click="open">
<el-dropdown-item divided>
退出登录
</el-dropdown-item>
</span>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
//import Screenfull from '@/components/Screenfull'
import { reqApi} from '@/assets/js/httpApi.js';
export default {
//components: {Screenfull},
data() {
return {
dialogVisible: false,
pondName:'',
risk_entrance:0,
}
},
computed: {
...mapGetters([
'user',
'baseApi',
'device',
]),
show: {
get() {
return this.$store.state.settings.showSettings
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'showSettings',
value: val
})
}
}
},
created() {
var self = this;
reqApi.common.requstEdge('get', 'tab/tailpondinfor/dryinfo', {}).then(function(res){
var body = res.body || {};
var tailingname = body.tailingname;
//self.pondName = tailingname.indexOf('尾矿库') > -1 ? tailingname : (tailingname||'') + '尾矿库';
self.pondName = tailingname;
self.risk_entrance = body.risk_entrance;
//var $appMain = self.$parent.$el.querySelector(".app-main").__vue__;
//var $cmPage = $appMain.$children[0];
});
},
methods: {
open() {
this.$confirm('确定注销并退出系统吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.logout()
})
},
logout() {
this.$store.dispatch('LogOut').then(() => {
location.reload()
})
}
}
}
</script>
<style lang="scss" scoped>
.mian-navbar{
position:relative;height:.65rem;width:100%;line-height:.65rem;
background-image:linear-gradient(to right, #071C6B, #0C5AAF, #138FE7);
display:flex;
.title-ctn{
height:100%;display:flex;align-items:center;margin-left:1.093vw;
h2{
font-size:.29rem;background-image:-webkit-linear-gradient(top, white, white, #b5cbfa);
-webkit-background-clip:text;
-webkit-text-fill-color:transparent;
}
}
.navbar{
flex:1;height:100%;
background:no-repeat left bottom url('~@/assets/images/layout/title_3.png');
background-size:100% auto;
.right{
display:flex;align-items:center;justify-content:flex-end;user-select:none;cursor:normal;
position:absolute;top:0;right:1.2vw;height:100%;
&>div{
display:flex;align-items:center;
a{font-size:24px;margin-right:.10rem;}
}
}
.avatar-wrapper{
&:before{position:absolute;right:0;height:auto;width:12px;}
position:relative;display:flex;align-items:center;padding-right:15px;color:#51dbff;font-size:13px;
img{height:26px;width:26px;border-radius:4px;margin-right:4px;border:0;}
span{display:block;max-width:55px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;word-wrap:normal;}
}
&:focus {
outline: none;
}
.right-menu{
flex:1;color:#ADCBBC;margin-right:.20rem;
&>div:last-child{
display:flex;margin-left:10px;
&:not(rect){
font-size:18px;
}
}
}
}
.errLog-container {
display: inline-block;
vertical-align: top;
}
}
</style>
<template>
<div class="drawer-container">
<div>
<h3 class="drawer-title">系统布局设置</h3>
<div class="drawer-item">
<span>主题颜色</span>
<theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
</div>
<div class="drawer-item">
<span>显示标签</span>
<el-switch v-model="tagsView" class="drawer-switch" />
</div>
<div class="drawer-item">
<span>固定头部</span>
<el-switch v-model="fixedHeader" class="drawer-switch" />
</div>
<div class="drawer-item">
<span>显示LOGO</span>
<el-switch v-model="sidebarLogo" class="drawer-switch" />
</div>
<div class="drawer-item">
<span>菜单UniqueOpened</span>
<el-switch v-model="uniqueOpened" class="drawer-switch" />
</div>
</div>
</div>
</template>
<script>
import ThemePicker from '@/components/ThemePicker'
export default {
components: { ThemePicker },
data() {
return {}
},
computed: {
fixedHeader: {
get() {
return this.$store.state.settings.fixedHeader
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'fixedHeader',
value: val
})
}
},
tagsView: {
get() {
return this.$store.state.settings.tagsView
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'tagsView',
value: val
})
}
},
sidebarLogo: {
get() {
return this.$store.state.settings.sidebarLogo
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'sidebarLogo',
value: val
})
}
},
uniqueOpened: {
get() {
return this.$store.state.settings.uniqueOpened
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'uniqueOpened',
value: val
})
}
}
},
methods: {
themeChange(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'theme',
value: val
})
}
}
}
</script>
<style lang="scss" scoped>
.drawer-container {
padding: 24px;
font-size: 14px;
line-height: 1.5;
word-wrap: break-word;
.drawer-title {
margin-bottom: 12px;
color: rgba(0, 0, 0, .85);
font-size: 14px;
line-height: 22px;
}
.drawer-item {
color: rgba(0, 0, 0, .65);
font-size: 14px;
padding: 12px 0;
}
.drawer-switch {
float: right
}
}
</style>
<script>
export default {
name: 'MenuItem',
functional: true,
props: {
icon: {
type: String,
default: ''
},
title: {
type: String,
default: ''
}
},
render(h, context) {
const { icon, title } = context.props
const vnodes = []
if (icon) {
vnodes.push(<svg-icon icon-class={icon}/>)
}
if (title) {
// vnodes.push(<span slot='title'>{(title)}</span>)
vnodes.push(<span>{(title)}</span>)
}
return vnodes
}
}
</script>
<template>
<!-- eslint-disable vue/require-component-is -->
<component v-bind="linkProps(to)">
<slot />
</component>
</template>
<script>
import { isExternal } from '@/utils/validate'
export default {
props: {
to: {
type: String,
required: true
}
},
methods: {
linkProps(url) {
if (isExternal(url)) {
return {
is: 'a',
href: url,
target: '_blank',
rel: 'noopener'
}
}
return {
is: 'router-link',
to: url
}
}
}
}
</script>
<!--
-->
<template>
<div v-if="!item.hidden" class="menu-wrapper">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<li role="menuitem" :index="resolvePath(onlyOneChild.path, 4)" class="el-menu-item" :class="{'submenu-title-noDropdown':!isNest, 'menu-note':'true'}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
</li>
</app-link>
</template>
<ul v-else ref="subMenu" :index="resolvePath(item.path, 1)">
<li role="menuitem" aria-haspopup="true" class="el-submenu" :class="{'main-node':item.isFirst}" @click="menuEvent($event, item)">
<div v-if="item.meta" class="el-submenu__title" >
<app-link v-if="isCustomPath(item.path)" :to="resolvePath(item.path, 3)">
<item :icon="item.meta && item.meta.icon" :title="item.meta.title" />
</app-link>
<item v-else :icon="item.meta && item.meta.icon" :title="item.meta.title" />
<i v-show="!item.isFirst" class="el-submenu__icon-arrow el-icon-arrow-right"></i>
</div>
<ul role="menu" class="el-menu el-menu--inline">
<sidebar-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path, 2)"
class="nest-menu dir-menu"
/>
</ul>
</li>
</ul>
</div>
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
export default {
name: 'SidebarItem',
components: { Item, AppLink },
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
},
},
data() {
this.onlyOneChild = null;
return {
}
},
methods: {
hasOneShowingChild(children, parent) {
children = children || []
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
}
return false
},
resolvePath(routePath, mark) {
if (isExternal(routePath)) {
return routePath
}
/* if (isExternal(this.basePath)) {
return this.basePath
} */
return path.resolve(this.basePath, routePath)
},
isCustomPath(path){
path = typeof path === 'string' ? path : '';
var pathArr = path.split('/');
return pathArr[pathArr.length-1] ? 0 : 1
},
menuEvent(e, item){
var tag = e.target || e.srcElement;
if(item.isFirst){
var menu = this.$el.firstElementChild.firstElementChild.lastElementChild;
// is-active
var vms = this.$parent.$el.children;
for(var vm of vms){
vm.classList.contains('is-active') && vm.classList.remove('is-active');
if(vm === this.$el){
vm.classList.add('is-active');
};
};
// hide menu
menu.style.display = 'none';
setTimeout(() => {
menu.style.display = '';
}, 50);
};
},
}
}
</script>
<style lang="scss" scope>
@import "~@/assets/styles/mixin.scss";
@import "~@/assets/styles/variables.scss";
.cu-nav {
height:.65rem;background-color:#2a3350;font-size:0;z-index:1001;max-height:50px;
//width:$sideBarWidth !important;transition:width 0.28s;overflow:hidden;
.el-menu{
/* background-color:$leftMenuBg !important; */
.el-menu-item{
color:#fff;
}
.submenu-title-noDropdown{
display:flex;align-items:center;
&:hover{
background:$subMenuHover !important;
span, .svg-icon{color:#fff;}
}
}
}
.el-scrollbar__view{
>.el-menu {
display:flex;border:none;height:100%;/* width:100% !important; */
>.menu-wrapper{
height:100%;
>a{
>.el-menu-item{
height:100%;
background-color:$leftMenuBg;
}
}
>ul{height:100%;}
}
}
}
.el-submenu{
position:relative;
&:hover{
>.el-menu--inline{
display:block;
}
}
>.el-menu {
position:absolute;top:100%;left:0;height:auto;min-width:100%;margin-top:3px;
}
.el-submenu{
&:hover{
.el-submenu__title{
background:$subMenuHover !important;
span{color:#fff;}
.el-submenu__icon-arrow{color:#fff;}
}
}
}
.el-menu-item{
&:hover{
background:$subMenuHover !important;
span, .svg-icon{color:#fff;}
}
}
}
.main-node{
position:relative;height:100%;
>.el-submenu__title{
display:flex;align-items:center;color:#fff;height:100%;line-height:normal;/* line-height:.66rem; */
border-bottom:2px solid transparent;
span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;word-wrap:normal;}
&:hover{
background: $leftMenuHover !important;
}
}
.el-menu--inline{
display:none;background-color:#f5f8ff;
>.dir-menu{border-style:solid;border-width:0 1px;border-color:#888;}
>.dir-menu:first-child{border-top-width:1px;}
>.dir-menu:last-child{border-bottom-width:1px;}
}
>.el-menu{
margin-top:0;
.el-submenu__title{
height:43px;line-height:43px;
}
}
.menu-note, .el-submenu{
//background:linear-gradient(to right, #0d225b, #092469, #082374) !important;
color:#000;
}
.menu-note{
padding:0 !important;min-width:auto;text-align:center;height:40px;line-height:40px;
//background-color: $subMenuBg !important;
span{margin-right:18px;color:#333;}
}
.dir-menu{
a{
display:block;width:100%;overflow:hidden;
}
.el-submenu{
.el-menu--inline{
position:absolute;top:0;left:100%;height:auto;width:auto;
}
}
}
.el-icon-arrow-right {
right:4px;margin-top:-4px;
}
.router-link-active{
span, .svg-icon{color:#258EF6;}
}
}
.is-active{
.main-node{
>.el-submenu__title{
border-bottom-color:rgb(255, 208, 75);
color:rgb(255, 208, 75)
}
}
}
.el-scrollbar{
overflow:visible;height:100%;display:flex;
.scrollbar-wrapper {
//overflow-x:hidden !important;
overflow:visible;margin:0 !important;flex:1;
>div{height:100%;}
}
}
.el-scrollbar__bar.is-vertical {
right: 0;
}
.is-horizontal {
display: none;
}
.svg-icon {
margin-right: 8px;
}
}
</style>
<template>
<div :class="{'has-logo':showLogo}">
<!-- :collapse="isCollapse" -->
<!-- <logo v-if="showLogo" /> -->
<el-scrollbar wrap-class="scrollbar-wrapper">
<!-- :collapse="isCollapse" -->
<el-menu
:default-active="activeMenu"
:text-color="variables.menuText"
:unique-opened="$store.state.settings.uniqueOpened"
:active-text-color="variables.menuActiveText"
:collapse-transition="false"
mode="horizontal"
class="el-menu-demo"
background-color="transparent"
text-color="#fff"
active-text-color="#ffd04b"
>
<sidebar-item v-for="route in sidebarRouters" :key="route.path" :item="route" :base-path="route.path" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
//import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/assets/styles/variables.scss'
export default {
components: { SidebarItem},
computed: {
...mapGetters([
'sidebarRouters',
'sidebar'
]),
activeMenu() {
const route = this.$route
const { meta, path } = route
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu
}
return path
},
showLogo() {
return this.$store.state.settings.sidebarLogo
},
variables() {
return variables
},
isCollapse() {
return !this.sidebar.opened
}
}
}
</script>
<template>
<el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
<slot />
</el-scrollbar>
</template>
<script>
const tagAndTagSpacing = 4 // tagAndTagSpacing
export default {
name: 'ScrollPane',
data() {
return {
left: 0
}
},
computed: {
scrollWrapper() {
return this.$refs.scrollContainer.$refs.wrap
}
},
methods: {
handleScroll(e) {
const eventDelta = e.wheelDelta || -e.deltaY * 40
const $scrollWrapper = this.scrollWrapper
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
},
moveToTarget(currentTag) {
const $container = this.$refs.scrollContainer.$el
const $containerWidth = $container.offsetWidth
const $scrollWrapper = this.scrollWrapper
const tagList = this.$parent.$refs.tag
let firstTag = null
let lastTag = null
// find first tag and last tag
if (tagList.length > 0) {
firstTag = tagList[0]
lastTag = tagList[tagList.length - 1]
}
if (firstTag === currentTag) {
$scrollWrapper.scrollLeft = 0
} else if (lastTag === currentTag) {
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
} else {
// find preTag and nextTag
const currentIndex = tagList.findIndex(item => item === currentTag)
const prevTag = tagList[currentIndex - 1]
const nextTag = tagList[currentIndex + 1]
// the tag's offsetLeft after of nextTag
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
// the tag's offsetLeft before of prevTag
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
}
}
}
}
}
</script>
<style lang="scss" scoped>
.scroll-container {
white-space: nowrap;
position: relative;
overflow: hidden;
width: 100%;
::v-deep {
.el-scrollbar__bar {
bottom: 0px;
}
.el-scrollbar__wrap {
height: 40px;
margin:0 !important;
overflow-y:hidden;
/* cursor:pointer; */
&::-webkit-scrollbar{width:0.3vw;height:5px;}
&::-webkit-scrollbar-thumb{border-radius: 10px;background: #1674ee;margin-right: 10px;}
&::-webkit-scrollbar-thumb:hover{background-color: #1854e8;}
&::-webkit-scrollbar-track{border-radius: 10px;background: rgba(255, 255, 255, 0.1);margin-right: 10px;}
/* */
scrollbar-width:none;
}
}
}
</style>
<template>
<div id="tags-view-container" class="tags-view-container">
<scroll-pane ref="scrollPane" class="tags-view-wrapper">
<router-link
v-for="tag in visitedViews"
ref="tag"
:key="tag.path"
:class="isActive(tag)?'active':''"
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
tag="span"
class="tags-view-item"
@click.middle.native="closeSelectedTag(tag)"
@contextmenu.prevent.native="openMenu(tag,$event)"
>
{{ tag.title }}
<span v-if="!tag.meta.affix" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
</router-link>
</scroll-pane>
<!-- <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="refreshSelectedTag(selectedTag)">刷新</li>
<li v-if="!(selectedTag.meta&&selectedTag.meta.affix)" @click="closeSelectedTag(selectedTag)">关闭</li>
<li @click="closeOthersTags">关闭其他</li>
<li @click="closeAllTags(selectedTag)">关闭全部</li>
</ul> -->
</div>
</template>
<script>
import ScrollPane from './ScrollPane'
import path from 'path'
export default {
components: { ScrollPane },
data() {
return {
visible: false,
top: 0,
left: 0,
selectedTag: {},
affixTags: []
}
},
computed: {
visitedViews() {
return this.$store.state.tagsView.visitedViews
},
routes() {
return this.$store.state.permission.routers
}
},
watch: {
$route() {
this.addTags()
this.moveToCurrentTag()
},
visible(value) {
if (value) {
document.body.addEventListener('click', this.closeMenu)
} else {
document.body.removeEventListener('click', this.closeMenu)
}
}
},
mounted() {
this.initTags()
this.addTags()
},
methods: {
isActive(route) {
return route.path === this.$route.path
},
filterAffixTags(routes, basePath = '/') {
let tags = []
routes.forEach(route => {
if (route.meta && route.meta.affix) {
const tagPath = path.resolve(basePath, route.path)
tags.push({
fullPath: tagPath,
path: tagPath,
name: route.name,
meta: { ...route.meta }
})
}
if (route.children) {
const tempTags = this.filterAffixTags(route.children, route.path)
if (tempTags.length >= 1) {
tags = [...tags, ...tempTags]
}
}
})
return tags
},
initTags() {
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
for (const tag of affixTags) {
// Must have tag name
if (tag.name) {
this.$store.dispatch('tagsView/addVisitedView', tag)
}
}
},
addTags() {
const { name } = this.$route
if (name) {
this.$store.dispatch('tagsView/addView', this.$route)
}
return false
},
moveToCurrentTag() {
const tags = this.$refs.tag
this.$nextTick(() => {
for (const tag of tags) {
if (tag.to.path === this.$route.path) {
this.$refs.scrollPane.moveToTarget(tag)
// when query is different then update
if (tag.to.fullPath !== this.$route.fullPath) {
this.$store.dispatch('tagsView/updateVisitedView', this.$route)
}
break
}
}
})
},
refreshSelectedTag(view) {
this.$store.dispatch('tagsView/delCachedView', view).then(() => {
const { fullPath } = view
this.$nextTick(() => {
this.$router.replace({
path: '/redirect' + fullPath
})
})
})
},
closeSelectedTag(view) {
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
if (this.isActive(view)) {
this.toLastView(visitedViews, view)
}
})
},
closeOthersTags() {
this.$router.push(this.selectedTag)
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
this.moveToCurrentTag()
})
},
closeAllTags(view) {
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
if (this.affixTags.some(tag => tag.path === view.path)) {
return
}
this.toLastView(visitedViews, view)
})
},
toLastView(visitedViews, view) {
const latestView = visitedViews.slice(-1)[0]
if (latestView) {
this.$router.push(latestView)
} else {
// now the default is to redirect to the home page if there is no tags-view,
// you can adjust it according to your needs.
if (view.name === 'Dashboard') {
// to reload home page
this.$router.replace({ path: '/redirect' + view.fullPath })
} else {
this.$router.push('/')
}
}
},
openMenu(tag, e) {
const menuMinWidth = 105
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
const offsetWidth = this.$el.offsetWidth // container width
const maxLeft = offsetWidth - menuMinWidth // left boundary
const left = e.clientX - offsetLeft + 15 // 15: margin right
if (left > maxLeft) {
this.left = maxLeft
} else {
this.left = left
}
this.top = e.clientY
this.visible = true
this.selectedTag = tag
},
closeMenu() {
this.visible = false
}
}
}
</script>
<style lang="scss" scoped>
.tags-view-container {
height: 34px;
width: 100%;
/* background: #fff; */
border-bottom: 1px solid #004689;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
.tags-view-wrapper {
.tags-view-item {
display: inline-block;
position: relative;
cursor: pointer;
height: 26px;
line-height: 26px;
border: 1px solid #d8dce5;
color: #495060;
background: #fff;
padding: 0 8px;
font-size: 12px;
margin-left: 5px;
margin-top: 4px;
&:first-of-type {
margin-left:0px;
}
&:last-of-type {
margin-right: 15px;
}
&.active {
background-color: #42b983;
color: #fff;
border-color: #42b983;
&::before {
content: '';
background: #fff;
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
position: relative;
margin-right: 2px;
}
}
}
}
.contextmenu {
margin: 0;
background: #fff;
z-index: 3000;
position: absolute;
list-style-type: none;
padding: 5px 0;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
li {
margin: 0;
padding: 7px 16px;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
}
</style>
<style lang="scss">
//reset element css of el-icon-close
.tags-view-wrapper {
.tags-view-item {
.el-icon-close {
width: 16px;
height: 16px;
vertical-align: 2px;
border-radius: 50%;
text-align: center;
transition: all .3s cubic-bezier(.645, .045, .355, 1);
transform-origin: 100% 50%;
&:before {
transform: scale(.6);
display: inline-block;
vertical-align: -3px;
}
&:hover {
background-color: #b4bccc;
color: #fff;
}
}
}
}
</style>
export { default as AppMain } from './AppMain'
export { default as MainNavbar } from './MainNavbar'
//export { default as Navbar } from './Navbar'
export { default as Settings } from './Settings'
export { default as Sidebar } from './Sidebar/index.vue'
export { default as TagsView } from './TagsView/index.vue'
<template>
<!-- <div :class="classObj" class="app-wrapper"> -->
<div class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<main-navbar />
<div class="main-body">
<sidebar class="sidebar-container cu-nav"/>
<div :class="{hasTagsView:needTagsView}" class="main-container">
<div class="main-container-liner">
<div class="main-inright">
<div :class="{'fixed-header':fixedHeader}">
<!-- <navbar /> -->
<!-- <tags-view v-if="needTagsView" /> -->
</div>
<app-main />
<right-panel v-if="showSettings">
<settings />
</right-panel>
</div>
</div>
</div>
</div>
<!-- 防止刷新后主题丢失 -->
<Theme v-show="false" ref="theme" />
</div>
</template>
<script>
import { AppMain, Settings, Sidebar, TagsView, MainNavbar } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'
import Theme from '@/components/ThemePicker'
import Cookies from 'js-cookie'
export default {
name: 'Layout',
components: {
AppMain,
//Navbar,
//RightPanel,
Settings,
Sidebar,
TagsView,
Theme,
MainNavbar
},
mixins: [ResizeMixin],
computed: {
...mapState({
sidebar: state => state.app.sidebar,
device: state => state.app.device,
showSettings: state => state.settings.showSettings,
needTagsView: state => state.settings.tagsView,
fixedHeader: state => state.settings.fixedHeader
}),
classObj() {
return {
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
}
},
mounted() {
if (Cookies.get('theme')) {
this.$refs.theme.theme = Cookies.get('theme')
this.$store.dispatch('settings/changeSetting', {
key: 'theme',
value: Cookies.get('theme')
})
}
},
methods: {
handleClickOutside() {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
}
}
</script>
<style lang="scss" scope>
#app .app-wrapper{
.main-container{
background-color:#02133e;
flex:1;position:relative;width:100%;/* border-top:1px solid #002B56;margin-left:1.041vw; */
.main-container-liner{height:100%;/* position:absolute;top:0;left:0;width:100%; */display:flex;}
.main-inright{height:100%;width:100%;flex:1;display:flex;flex-direction:column;}
}
}
.app-wrapper{
/* @include clearfix; */position:relative;height:100%;width:100%;
display:flex;flex-direction:column;box-orient:vertical;overflow-x:auto;
.main-body{/* margin-top:0.26vh;margin-top:0.5vh; */
position:relative;
display:flex;flex:1;flex-direction:column;
}
&.mobile.openSidebar {position:fixed;top: 0;}
}
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position:absolute;
z-index: 999;
}
.fixed-header {
/* position: absolute;
top: 0;
left: 0;
z-index: 9; */
width:100%;
transition: width 0.28s;
padding: 0;
}
.mobile .fixed-header {
width: 100%;
}
</style>
import store from '@/store'
const { body } = document
const WIDTH = 992 // refer to Bootstrap's responsive design
export default {
watch: {
$route(route) {
if (this.device === 'mobile' && this.sidebar.opened) {
store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
}
},
beforeMount() {
window.addEventListener('resize', this.$_resizeHandler)
},
beforeDestroy() {
window.removeEventListener('resize', this.$_resizeHandler)
},
mounted() {
const isMobile = this.$_isMobile()
if (isMobile) {
store.dispatch('app/toggleDevice', 'mobile')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_isMobile() {
const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH
},
$_resizeHandler() {
if (!document.hidden) {
const isMobile = this.$_isMobile()
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
if (isMobile) {
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
}
}
}
}
import Vue from 'vue'
import Cookies from 'js-cookie'
import Element from 'element-ui'
// 数据字典
import dict from './components/Dict'
// 权限指令
import checkPer from '@/utils/permission'
import permission from './components/Permission'
//import './assets/styles/element-variables.scss'
// global css
import './assets/styles/index.scss'
// global css
import './assets/styles/common.css'
// 代码高亮
//import VueHighlightJS from 'vue-highlightjs'
//import 'highlight.js/styles/atom-one-dark.css'
import App from './App'
import store from './store'
import router from './router/routers'
import './assets/icons' // icon
import './router/index' // permission control
//import 'echarts-gl';
Vue.use(checkPer)
//Vue.use(VueHighlightJS)
//Vue.use(mavonEditor)
Vue.use(permission)
Vue.use(dict)
Vue.use(Element, {
size: Cookies.get('size') || 'small' // set element-ui default size
})
Vue.config.productionTip = false;
new Vue({
el: '#app',
router,
store,
render: h => h(App)
});
Vue.__proto__.$state = store;
import {
initData,
download
} from '@/api/data'
import {
parseTime,
downloadFile
} from '@/utils/index'
export default {
data() {
return {
// 表格数据
data: [],
// 排序规则,默认 id 降序, 支持多字段排序 ['id,desc', 'createTime,asc']
sort: ['id,desc'],
// 页码
page: 0,
// 每页数据条数
size: 10,
// 总数据条数
total: 0,
// 请求数据的url
url: '',
// 查询数据的参数
params: {},
// 待查询的对象
query: {},
// 等待时间
time: 50,
// 是否为新增类型的表单
isAdd: false,
// 导出的 Loading
downloadLoading: false,
// 表格 Loading 属性
loading: true,
// 删除 Loading 属性
delLoading: false,
delAllLoading: false,
// 弹窗属性
dialog: false,
// Form 表单
form: {},
// 重置表单
resetForm: {},
// 标题
title: ''
}
},
methods: {
parseTime,
downloadFile,
async init() {
if (!await this.beforeInit()) {
return
}
return new Promise((resolve, reject) => {
this.loading = true
// 请求数据
initData(this.url, this.getQueryParame()).then(data => {
this.total = data.totalElements
this.data = data.content
// time 毫秒后显示表格
setTimeout(() => {
this.loading = false
}, this.time)
resolve(data)
}).catch(err => {
this.loading = false
reject(err)
})
})
},
beforeInit() {
return true
},
getQueryParame: function() {
return {
page: this.page,
size: this.size,
sort: this.sort,
...this.query,
...this.params
}
},
// 改变页码
pageChange(e) {
this.page = e - 1
this.init()
},
// 改变每页显示数
sizeChange(e) {
this.page = 0
this.size = e
this.init()
},
// 预防删除第二页最后一条数据时,或者多选删除第二页的数据时,页码错误导致请求无数据
dleChangePage(size) {
if (size === undefined) {
size = 1
}
if (this.data.length === size && this.page !== 0) {
this.page = this.page - 1
}
},
// 查询方法
toQuery() {
this.page = 0
this.init()
},
/**
* 通用的提示封装
*/
submitSuccessNotify() {
this.$notify({
title: '提交成功',
type: 'success',
duration: 2500
})
},
addSuccessNotify() {
this.$notify({
title: '新增成功',
type: 'success',
duration: 2500
})
},
editSuccessNotify() {
this.$notify({
title: '编辑成功',
type: 'success',
duration: 2500
})
},
delSuccessNotify() {
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
},
notify(title, type) {
this.$notify({
title: title,
type: type,
duration: 2500
})
},
/**
* 删除前可以调用 beforeDelMethod 做一些操作
*/
beforeDelMethod() {
return true
},
/**
* 通用的删除
*/
delMethod(id) {
if (!this.beforeDelMethod()) {
return
}
this.delLoading = true
this.crudMethod.del(id).then(() => {
this.delLoading = false
this.$refs[id].doClose()
this.dleChangePage()
this.delSuccessNotify()
this.afterDelMethod()
this.init()
}).catch(() => {
this.delLoading = false
this.$refs[id].doClose()
})
},
afterDelMethod() {},
/**
* 多选删除提示
*/
beforeDelAllMethod() {
this.$confirm('你确定删除选中的数据吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.delAllMethod()
})
},
/**
* 多选删除
*/
delAllMethod() {
this.delAllLoading = true
const data = this.$refs.table.selection
const ids = []
for (let i = 0; i < data.length; i++) {
ids.push(data[i].id)
}
this.crudMethod.delAll(ids).then(() => {
this.delAllLoading = false
this.dleChangePage(ids.length)
this.init()
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
}).catch(() => {
this.delAllLoading = false
})
},
/**
* 显示新增弹窗前可以调用该方法
*/
beforeShowAddForm() {},
/**
* 显示新增弹窗
*/
showAddFormDialog() {
this.isAdd = true
this.resetForm = JSON.parse(JSON.stringify(this.form))
this.beforeShowAddForm()
this.dialog = true
},
/**
* 显示编辑弹窗前可以调用该方法
*/
beforeShowEditForm(data) {},
/**
* 显示编辑弹窗
*/
showEditFormDialog(data = '') {
this.isAdd = false
if (data) {
this.resetForm = JSON.parse(JSON.stringify(this.form))
this.form = JSON.parse(JSON.stringify(data))
}
this.beforeShowEditForm(data)
this.dialog = true
},
/**
* 新增方法
*/
addMethod() {
this.crudMethod.add(this.form).then(() => {
this.addSuccessNotify()
this.loading = false
this.afterAddMethod()
this.cancel()
this.init()
}).catch(() => {
this.loading = false
this.afterAddErrorMethod()
})
},
/**
* 新增后可以调用该方法
*/
afterAddMethod() {},
/**
* 新增失败后调用该方法
*/
afterAddErrorMethod() {},
/**
* 通用的编辑方法
*/
editMethod() {
this.crudMethod.edit(this.form).then(() => {
this.editSuccessNotify()
this.loading = false
this.afterEditMethod()
this.cancel()
this.init()
}).catch(() => {
this.loading = false
})
},
/**
* 编辑后可以调用该方法
*/
afterEditMethod() {},
/**
* 提交前可以调用该方法
*/
beforeSubmitMethod() {
return true
},
/**
* 提交
*/
submitMethod() {
if (!this.beforeSubmitMethod()) {
return
}
if (this.$refs['form']) {
this.$refs['form'].validate((valid) => {
if (valid) {
this.loading = true
if (this.isAdd) {
this.addMethod()
} else this.editMethod()
}
})
}
},
/**
* 隐藏弹窗
*/
cancel() {
this.dialog = false
if (this.$refs['form']) {
this.$refs['form'].clearValidate()
this.form = this.resetForm
}
},
/**
* 获取弹窗的标题
*/
getFormTitle() {
return this.isAdd ? `新增${this.title}` : `编辑${this.title}`
},
/**
* 通用导出
*/
downloadMethod() {
this.beforeInit()
this.downloadLoading = true
download(this.url + '/download', this.params).then(result => {
this.downloadFile(result, this.title + '数据', 'xlsx')
this.downloadLoading = false
}).catch(() => {
this.downloadLoading = false
})
}
}
}
import router from './routers'
import store from '@/store'
import Config from '@/settings'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css'// progress bar style
import { getToken } from '@/utils/auth' // getToken from cookie
import { buildMenus } from '@/api/system/menu'
import { filterAsyncRouter } from '@/store/modules/permission'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/plus/login', '/register'] // no redirect whitelist
router.beforeEach((to, from, next) => {
if (to.meta.title) {
//document.title = to.meta.title + ' - ' + Config.title
document.title = to.meta.title
}
NProgress.start();
if (getToken()) {
// 已登录且要跳转的页面是登录页
if (to.path === '/plus/login') {
next({ path: '/' })
NProgress.done()
} else {
if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(() => { // 拉取user_info
// 动态路由,拉取菜单
loadMenus(next, to)
}).catch(() => {
store.dispatch('LogOut').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug
})
})
// 登录时未拉取 菜单,在此处拉取
} else if (store.getters.loadMenus) {
// 修改成false,防止死循环
store.dispatch('updateLoadMenus')
loadMenus(next, to)
} else {
next()
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
next()
} else {
window.location.href = `/plus/login?redirect=${to.fullPath}`;
NProgress.done()
}
}
})
export const loadMenus = (next, to) => {
buildMenus().then(res => {
const sdata = JSON.parse(JSON.stringify(res))
const rdata = JSON.parse(JSON.stringify(res))
const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, true)
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
store.dispatch('GenerateRoutes', rewriteRoutes).then(() => { // 存储路由
router.addRoutes(rewriteRoutes) // 动态添加可访问路由表
next({ ...to, replace: true })
})
store.dispatch('SetSidebarRouters', sidebarRoutes)
})
}
router.afterEach(() => {
NProgress.done() // finish progress bar
})
import Vue from "vue";
import Router from "vue-router";
//import Layout from "../layout/index";
import HomeLayout from "../layout/home";
Vue.use(Router);
export const constantRouterMap = [
{
path: "/plus/login",
meta: { title: "登录login", noCache: true },
component: (resolve) => {
require(["@/views/system/user/login"], resolve)
},
hidden: true
},
{
path: "/404",
redirect: "/dashboard",
component: resolve => require(["@/views/features/404"], resolve),
hidden: true
},
{
path: "/401",
component: resolve => require(["@/views/features/401"], resolve),
hidden: true
},
{
path: "/redirect",
//component: Layout,
component: HomeLayout,
hidden: true,
children: [
{
path: "/redirect/:path*",
component: resolve => require(["@/views/features/redirect"], resolve)
}
]
},
{
path: "/",
component: HomeLayout,
redirect: "/dashboard",
children: [
{
path: 'dashboard',
component: (resolve) => require(['@/views/home_manage'], resolve),
name: 'Dashboard',
meta: { title: '主页面', icon: 'index', affix: true, noCache: true }
}
]
},
{
path: "/user",
//component: Layout,
component: HomeLayout,
hidden: true,
redirect: "noredirect",
children: [
{
path: "center",
component: resolve => require(["@/views/system/user/center"], resolve),
name: "个人中心",
meta: { title: "个人中心" }
}
]
},
{
path: "/edge/Screen",
meta: { title: "数据大屏", noCache: true },
component: (resolve) => {
return require(["@/views/Screen/index"], resolve)
},
hidden: true
},
{
path: "/edge/ScreenFX",
meta: { title: "风险数据大屏", noCache: true },
component: (resolve) => {
return require(["@/views/Screen/fx"], resolve)
},
hidden: true
},
];
export default new Router({
// mode: 'hash',
mode:"history",
//base: '/mobile/',
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
});
module.exports = {
/**
* @description 网站标题
*/
title: '尾矿库安全监测系统',
/**
* @description 是否显示 tagsView
*/
tagsView: true,
/**
* @description 固定头部
*/
fixedHeader: true,
/**
* @description 记住密码状态下的token在Cookie中存储的天数,默认1天
*/
tokenCookieExpires: 1,
/**
* @description 记住密码状态下的密码在Cookie中存储的天数,默认1天s
*/
passCookieExpires: 1,
/**
* @description 是否只保持一个子菜单的展开
*/
uniqueOpened: true,
/**
* @description token key
*/
TokenKey: 'V3-TailingPond',
/**
* @description 请求超时时间,毫秒(默认2分钟)
*/
timeout: 1200000,
/**
* @description 是否显示logo
*/
sidebarLogo: true,
/**
* 是否显示设置的底部信息
*/
showFooter: true,
/**
* 底部文字,支持html语法
*/
//footerTxt: '© 2019 Zheng Jie <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License 2.0</a>',
footerTxt: '© ',
/**
* 备案号
*/
caseNumber: '鲁ICP备09100748号-5',
"version": "0.950"
}
const getters = {
deployUploadApi: state => state.api.deployUploadApi,
databaseUploadApi: state => state.api.databaseUploadApi,
size: state => state.app.size,
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
roles: state => state.user.roles,
user: state => state.user.user,
loadMenus: state => state.user.loadMenus,
permission_routers: state => state.permission.routers,
addRouters: state => state.permission.addRouters,
socketApi: state => state.api.socketApi,
imagesUploadApi: state => state.api.imagesUploadApi,
baseApi: state => state.api.baseApi,
fileUploadApi: state => state.api.fileUploadApi,
updateAvatarApi: state => state.api.updateAvatarApi,
qiNiuUploadApi: state => state.api.qiNiuUploadApi,
sqlApi: state => state.api.sqlApi,
swaggerApi: state => state.api.swaggerApi,
sidebarRouters: state => state.permission.sidebarRouters
}
export default getters
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
Vue.use(Vuex)
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)
// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
// set './app.js' => 'app'
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
const store = new Vuex.Store({
modules,
getters
})
export default store
// 适配 Nginx 反向代理
const baseUrl = process.env.VUE_APP_LOCAL_API === '/' ? '' : process.env.VUE_APP_LOCAL_API
const api = {
state: {
// 部署包上传
deployUploadApi: baseUrl + '/api/deploy/upload',
// SQL脚本上传
databaseUploadApi: baseUrl + '/api/database/upload',
// 实时控制台
socketApi: baseUrl + '/websocket?token=kl',
// 图片上传
imagesUploadApi: baseUrl + '/api/localStorage/pictures',
// 修改头像
updateAvatarApi: baseUrl + '/api/users/updateAvatar',
// 上传文件到七牛云
qiNiuUploadApi: baseUrl + '/api/qiNiuContent',
// Sql 监控
sqlApi: baseUrl + '/druid/index.html',
// swagger
swaggerApi: baseUrl + '/swagger-ui.html',
// 文件上传
fileUploadApi: baseUrl + '/api/localStorage',
// baseUrl,
baseApi: baseUrl
}
}
export default api
import Cookies from 'js-cookie'
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
device: 'desktop',
size: Cookies.get('size') || 'small'
}
const mutations = {
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
},
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
}
}
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
import { constantRouterMap } from '@/router/routers'
//import Layout from '@/layout/index'
import HomeLayout from "@/layout/home";
import ParentView from '@/components/ParentView'
const permission = {
state: {
routers: constantRouterMap,
addRouters: [],
sidebarRouters: []
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers
state.routers = constantRouterMap.concat(routers)
},
SET_SIDEBAR_ROUTERS: (state, routers) => {
state.sidebarRouters = constantRouterMap.concat(routers)
}
},
actions: {
GenerateRoutes({ commit }, asyncRouter) {
commit('SET_ROUTERS', asyncRouter)
},
SetSidebarRouters({ commit }, sidebarRouter) {
commit('SET_SIDEBAR_ROUTERS', sidebarRouter)
}
}
}
export const filterAsyncRouter = (routers, isRewrite = false) => { // 遍历后台传来的路由字符串,转换为组件对象
return routers.filter(router => {
if (isRewrite && router.children) {
router.children = filterChildren(router.children)
}
if (router.component) {
if (router.component === 'Layout') { // Layout组件特殊处理
//router.component = Layout;
router.component = HomeLayout
} else if (router.component === 'ParentView') {
router.component = ParentView
} else {
const component = router.component
router.component = loadView(component)
}
}
if (router.children && router.children.length) {
router.children = filterAsyncRouter(router.children, router, isRewrite)
}
return true
})
}
function filterChildren(childrenMap) {
var children = []
childrenMap.forEach((el, index) => {
if (el.children && el.children.length) {
if (el.component === 'ParentView') {
el.children.forEach(c => {
c.path = el.path + '/' + c.path
if (c.children && c.children.length) {
children = children.concat(filterChildren(c.children, c))
return
}
children.push(c)
})
return
}
}
children = children.concat(el)
})
return children
}
export const loadView = (view) => {
return (resolve) => require([`@/views/${view}`], resolve)
}
export default permission
import variables from '@/assets/styles/element-variables.scss'
import defaultSettings from '@/settings'
const { tagsView, fixedHeader, sidebarLogo, uniqueOpened, showFooter, footerTxt, caseNumber } = defaultSettings
const state = {
theme: variables.theme,
showSettings: false,
tagsView: tagsView,
fixedHeader: fixedHeader,
sidebarLogo: sidebarLogo,
uniqueOpened: uniqueOpened,
showFooter: showFooter,
footerTxt: footerTxt,
caseNumber: caseNumber
}
const mutations = {
CHANGE_SETTING: (state, { key, value }) => {
if (state.hasOwnProperty(key)) {
state[key] = value
}
}
}
const actions = {
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
const state = {
visitedViews: [],
cachedViews: []
}
const mutations = {
ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
ADD_CACHED_VIEW: (state, view) => {
if (state.cachedViews.includes(view.name)) return
if (!view.meta.noCache) {
state.cachedViews.push(view.name)
}
},
DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews.splice(i, 1)
break
}
}
},
DEL_CACHED_VIEW: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews.splice(index, 1)
break
}
}
},
DEL_OTHERS_VISITED_VIEWS: (state, view) => {
state.visitedViews = state.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path
})
},
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews = state.cachedViews.slice(index, index + 1)
break
}
}
},
DEL_ALL_VISITED_VIEWS: state => {
// keep affix tags
const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
state.visitedViews = affixTags
},
DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = []
},
UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) {
if (v.path === view.path) {
v = Object.assign(v, view)
break
}
}
}
}
const actions = {
addView({ dispatch }, view) {
dispatch('addVisitedView', view)
dispatch('addCachedView', view)
},
addVisitedView({ commit }, view) {
commit('ADD_VISITED_VIEW', view)
},
addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view)
},
delView({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delVisitedView', view)
dispatch('delCachedView', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delVisitedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_VISITED_VIEW', view)
resolve([...state.visitedViews])
})
},
delCachedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_CACHED_VIEW', view)
resolve([...state.cachedViews])
})
},
delOthersViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delOthersVisitedViews', view)
dispatch('delOthersCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delOthersVisitedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
},
delOthersCachedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_CACHED_VIEWS', view)
resolve([...state.cachedViews])
})
},
delAllViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delAllVisitedViews', view)
dispatch('delAllCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delAllVisitedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_VISITED_VIEWS')
resolve([...state.visitedViews])
})
},
delAllCachedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_CACHED_VIEWS')
resolve([...state.cachedViews])
})
},
updateVisitedView({ commit }, view) {
commit('UPDATE_VISITED_VIEW', view)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
import { login, getInfo, logout } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
const user = {
state: {
token: getToken(),
user: {},
roles: [],
// 第一次加载菜单时用到
loadMenus: false
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_USER: (state, user) => {
state.user = user
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_LOAD_MENUS: (state, loadMenus) => {
state.loadMenus = loadMenus
},
SET_AREA_CONFIG: (state, config) => {
state.config = config
}
},
actions: {
// 登录
Login({ commit }, userInfo) {
const rememberMe = userInfo.rememberMe;
return new Promise((resolve, reject) => {
login(userInfo).then(res => {
if(/* res.head.code === '0000' || */ !res.code){
var body = res.body || res;
setToken(body.token, rememberMe);
commit('SET_TOKEN', body.token);
setUserInfo(body.user, commit);
// 第一次加载菜单时用到, 具体见 src 目录下的 permission.js
commit('SET_LOAD_MENUS', true);
};
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetInfo({ commit }) {
return new Promise((resolve, reject) => {
getInfo().then(res => {
setUserInfo(res, commit)
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 登出
LogOut({ commit }) {
return new Promise((resolve, reject) => {
logout().then(res => {
logOut(commit)
resolve()
}).catch(error => {
logOut(commit)
reject(error)
})
})
},
updateLoadMenus({ commit }) {
return new Promise((resolve, reject) => {
commit('SET_LOAD_MENUS', false)
})
}
}
}
export const logOut = (commit) => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
}
export const setUserInfo = (res, commit) => {
// 如果没有任何权限,则赋予一个默认的权限,避免请求死循环
if (res.roles.length === 0) {
commit('SET_ROLES', ['ROLE_SYSTEM_DEFAULT'])
} else {
commit('SET_ROLES', res.roles)
};
commit('SET_USER', res.user);
// 去掉自定义权限
//commit('SET_AREA_CONFIG', Config[res.areaId])
}
export default user
\ No newline at end of file
import Cookies from 'js-cookie'
import Config from '@/settings'
const TokenKey = Config.TokenKey
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token, rememberMe) {
if (rememberMe) {
return Cookies.set(TokenKey, token, { expires: Config.tokenCookieExpires })
} else return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
/******* SHA1 ******/
function hex_sha1(txt) {
var hexcase = 0, chrsz = 8;
var hex_sha1 = function(r) {
return binb2hex(core_sha1(AlignSHA1(r)))
}
function sha1_vm_test() {
return "a9993e364706816aba3e25717850c26c9cd0d89d" == hex_sha1("abc")
}
function core_sha1(r) {
for (var e = r, t = Array(80), n = 1732584193, a = -271733879, h = -1732584194, d = 271733878, c = -1009589776, f = 0; f < e.length; f += 16) {
for (var o = n, i = a, _ = h, m = d, g = c, s = 0; 80 > s; s++) {
t[s] = 16 > s ? e[f + s] : rol(t[s - 3] ^ t[s - 8] ^ t[s - 14] ^ t[s - 16], 1);
var l = safe_add(safe_add(rol(n, 5), sha1_ft(s, a, h, d)), safe_add(safe_add(c, t[s]), sha1_kt(s)));
c = d,
d = h,
h = rol(a, 30),
a = n,
n = l
}
n = safe_add(n, o),
a = safe_add(a, i),
h = safe_add(h, _),
d = safe_add(d, m),
c = safe_add(c, g)
}
return new Array(n,a,h,d,c)
}
function sha1_ft(r, e, t, n) {
return 20 > r ? e & t | ~e & n : 40 > r ? e ^ t ^ n : 60 > r ? e & t | e & n | t & n : e ^ t ^ n
}
function sha1_kt(r) {
return 20 > r ? 1518500249 : 40 > r ? 1859775393 : 60 > r ? -1894007588 : -899497514
}
function safe_add(r, e) {
var t = (65535 & r) + (65535 & e)
, n = (r >> 16) + (e >> 16) + (t >> 16);
return n << 16 | 65535 & t
}
function rol(r, e) {
return r << e | r >>> 32 - e
}
function AlignSHA1(r) {
for (var e = (r.length + 8 >> 6) + 1, t = new Array(16 * e), n = 0; 16 * e > n; n++)
t[n] = 0;
for (n = 0; n < r.length; n++)
t[n >> 2] |= r.charCodeAt(n) << 24 - 8 * (3 & n);
return t[n >> 2] |= 128 << 24 - 8 * (3 & n),
t[16 * e - 1] = 8 * r.length,
t
}
function binb2hex(r) {
for (var e = hexcase ? "0123456789ABCDEF" : "0123456789abcdef", t = "", n = 0; n < 4 * r.length; n++)
t += e.charAt(15 & r[n >> 2] >> 8 * (3 - n % 4) + 4) + e.charAt(15 & r[n >> 2] >> 8 * (3 - n % 4));
return t
}
return hex_sha1(txt);
};
module.exports = {
//Base64: Base64,
//hex_md5: hex_md5,
hex_sha1: hex_sha1,
//des: des,
}
\ No newline at end of file
/**
* Created by jiachenpan on 16/11/18.
*/
export function parseTime(time) {
if (time) {
var date = new Date(time)
var year = date.getFullYear()
/* 在日期格式中,月份是从0开始的,因此要加0
* 使用三元表达式在小于10的前面加0,以达到格式统一 如 09:11:05
* */
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
// 拼接
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
} else {
return ''
}
}
// 产生随机数
// min 最小值
// max 最大值
// len 生成随机数量
// isRound 是否取整 true 取整
export function randNum(min, max, len, isRound) {
var arr = []
for (let i = 0; i < len; i++) {
var num
num = Math.random() * (max - min) + min
if (isRound) {
num = Math.round(num)
arr.push(num)
} else {
arr.push(num.toFixed(2))
}
}
return arr
}
export function formatTime(time, option) {
time = +time * 1000
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'' +
d.getDate() +
'' +
d.getHours() +
'' +
d.getMinutes() +
''
)
}
}
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
// 替换邮箱字符
export function regEmail(email) {
if (String(email).indexOf('@') > 0) {
const str = email.split('@')
let _s = ''
if (str[0].length > 3) {
for (var i = 0; i < str[0].length - 3; i++) {
_s += '*'
}
}
var new_email = str[0].substr(0, 3) + _s + '@' + str[1]
}
return new_email
}
// 替换手机字符
export function regMobile(mobile) {
if (mobile.length > 7) {
var new_mobile = mobile.substr(0, 3) + '****' + mobile.substr(7)
}
return new_mobile
}
/**
* Check if an element has a class
* @param {HTMLElement} elm
* @param {string} cls
* @returns {boolean}
*/
export function hasClass(ele, cls) {
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}
export function downloadFile(obj, name, suffix) {
const url = window.URL.createObjectURL(new Blob([obj]))
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
const fileName = parseTime(new Date()) + '-' + name + '.' + suffix
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
import store from '@/store'
/**
* @param {Array} value
* @returns {Boolean}
* @example see @/views/permission/directive.vue
*/
export default {
install(Vue) {
Vue.prototype.checkPer = (value) => {
if (value && value instanceof Array && value.length > 0) {
const roles = store.getters && store.getters.roles
const permissionRoles = value
return roles.some(role => {
return permissionRoles.includes(role)
})
} else {
console.error(`need roles! Like v-permission="['admin','editor']"`)
return false
}
}
}
}
import axios from 'axios'
import { Notification } from 'element-ui'
import { getToken } from '@/utils/auth'
import Config from '@/settings'
// 使请求头可以携带cookie
axios.defaults.withCredentials = true;
//var baseURL = (VUE_APP_API.ServiceURL || process.env.VUE_APP_LOCAL_API) + '/';
var baseURL = process.env.NODE_ENV
=== 'development' ? process.env.VUE_APP_LOCAL_API + '/' : (VUE_APP_API.ServiceURL || process.env.VUE_APP_LOCAL_API) + '/';
// 创建axios实例
const service = axios.create({
baseURL: baseURL,
timeout: Config.timeout // 请求超时时间
})
// request拦截器
service.interceptors.request.use(
config => {
if (getToken()) {
config.headers['Authorization'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
config.headers['Content-Type'] = 'application/json'
return config
},
error => {
Promise.reject(error)
}
)
// response 拦截器
service.interceptors.response.use(
response => {
return response.data
},
error => {
if (error.response.status) {
const responseCode = error.response.status
switch (responseCode) {
case 400:
// Message.error('操作失败');
break
// token 过期
case 401:
Notification({
title: '登录过期,请重新登录',
duration: 2000,
type: 'warning'
})
setTimeout(() => {
window.localStorage.removeItem('token')
window.location = '#/';
location.reload()
}, 1000)
break
default:
break
}
return error.response.data
}
}
)
export default service
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min';
//import jsencrypt from 'jsencrypt'
//import crypto from 'crypto'
import encryption from './encryption'
// 密钥对生成 http://web.chacuo.net/netrsakeypair
/* Node env
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKgzvKMsX/l5eI+12W6reo5VDw5wOS380zdNc6HpmdRYvfwrM02GOKgvx8pJGaSNf7ZF7llofOwNVIaIrCOS6nECAwEAAQ==';
// 加密
export function encrypt(txt) {
var hashCode = encryption.hex_sha1(txt);
var encryptor = new JSEncrypt();
encryptor.setPublicKey(publicKey) // 设置公钥
return encryptor.encrypt(hashCode);
}; */
// eladmin
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD\n2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ==';
// 加密
export function encrypt(txt) {
const encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey) // 设置公钥
return encryptor.encrypt(txt) // 对需要加密的数据进行加密
}
// 解密
/* export function decrypt(txt) {
const encryptor = new JSEncrypt()
encryptor.setPrivateKey(privateKey)
return encryptor.decrypt(txt)
} */
import axios from 'axios'
import { getToken } from '@/utils/auth'
export function upload(api, file) {
var data = new FormData()
data.append('file', file)
const config = {
headers: { 'Authorization': getToken() }
}
return axios.post(api, data, config)
}
/**
* Created by PanJiaChen on 16/11/18.
*/
/**
* @param {string} path
* @returns {Boolean}
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUsername(str) {
const valid_map = ['admin', 'editor']
return valid_map.indexOf(str.trim()) >= 0
}
/**
* @param {string} url
* @returns {Boolean}
*/
export function validURL(url) {
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return reg.test(url)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validLowerCase(str) {
const reg = /^[a-z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUpperCase(str) {
const reg = /^[A-Z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validAlphabets(str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
/**
* @param {string} email
* @returns {Boolean}
*/
export function validEmail(email) {
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return reg.test(email)
}
export function isvalidPhone(phone) {
const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
return reg.test(phone)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function isString(str) {
if (typeof str === 'string' || str instanceof String) {
return true
}
return false
}
/**
* @param {Array} arg
* @returns {Boolean}
*/
export function isArray(arg) {
if (typeof Array.isArray === 'undefined') {
return Object.prototype.toString.call(arg) === '[object Array]'
}
return Array.isArray(arg)
}
/**
* 是否合法IP地址
* @param rule
* @param value
* @param callback
*/
export function validateIP(rule, value, callback) {
if (value === '' || value === undefined || value == null) {
callback()
} else {
const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
if ((!reg.test(value)) && value !== '') {
callback(new Error('请输入正确的IP地址'))
} else {
callback()
}
}
}
/* 是否手机号码或者固话*/
export function validatePhoneTwo(rule, value, callback) {
const reg = /^((0\d{2,3}-\d{7,8})|(1[34578]\d{9}))$/
if (value === '' || value === undefined || value == null) {
callback()
} else {
if ((!reg.test(value)) && value !== '') {
callback(new Error('请输入正确的电话号码或者固话号码'))
} else {
callback()
}
}
}
/* 是否固话*/
export function validateTelephone(rule, value, callback) {
const reg = /0\d{2}-\d{7,8}/
if (value === '' || value === undefined || value == null) {
callback()
} else {
if ((!reg.test(value)) && value !== '') {
callback(new Error('请输入正确的固话(格式:区号+号码,如010-1234567)'))
} else {
callback()
}
}
}
/* 是否手机号码*/
export function validatePhone(rule, value, callback) {
const reg = /^[1][3,4,5,7,8][0-9]{9}$/
if (value === '' || value === undefined || value == null) {
callback()
} else {
if ((!reg.test(value)) && value !== '') {
callback(new Error('请输入正确的电话号码'))
} else {
callback()
}
}
}
/* 是否身份证号码*/
export function validateIdNo(rule, value, callback) {
const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
if (value === '' || value === undefined || value == null) {
callback()
} else {
if ((!reg.test(value)) && value !== '') {
callback(new Error('请输入正确的身份证号码'))
} else {
callback()
}
}
}
<template>
<div class="ScreenFX cm-layout">
<div class="a_0">
</div>
<div class="b_0">
<header>
<div class="b1_a">
<h1>尾矿库数据风险预警监控平台</h1>
</div>
<div class="b1_b">
<a href="/dashboard">返回</a>
<span class="date font_digit" id="nowTime">2021<span></span>12<span></span>01<span></span> 09:12:34</span>
</div>
<div class="b1_c">
<div class="scroll-msg photo-frame" id="scrollMsg">
<div class="in-box">
<ul class="">
<!-- <li v-for="item in alarmList">
<h5><i :class="'level'+(item.alarmlevel)"></i>{{item.name}}</h5>
<span>{{alarmlevel[item.alarmlevel]}}</span><font>{{item.time}}</font>
</li> -->
</ul>
</div>
</div>
</div>
</header>
<section class="b_2">
<div class="b2_a">
<div class="b2_a1 abs-flex">
<div class="flex-disf panle-seat">
<div class="flex-disf-col panle-inbox">
<div class="title">
<h4>各监测项目风险数量月统计</h4>
</div>
<div class="content flex-rel">
<div class="abs-full" id="chart1"></div>
</div>
</div>
</div>
<div class="flex-disf panle-seat">
<div class="flex-disf-col panle-inbox">
<div class="title">
<h4>风险等级数量月统计</h4>
</div>
<div class="content flex-rel">
<div class="abs-full" id="chart2"></div>
</div>
</div>
</div>
</div>
<div class="b2_a2" id="b2_a2">
<div class="b2a_2a text-abs"><a class="">尾矿库风险等级</a></div>
<div class="b2a_2b text-abs"><a class="">在线监测</a></div>
<div class="b2a_2c text-abs"><a class="">实时监测</a></div>
<div class="b2a_2d text-abs"><a class="">尾矿库安全</a></div>
</div>
<div class="b2_a3 abs-flex">
<div class="flex-disf panle-seat">
<div class="flex-disf-col panle-inbox">
<div class="title">
<h4>各监测项目风险数量年统计</h4>
</div>
<div class="content flex-rel">
<div class="abs-full" id="chart3"></div>
</div>
</div>
</div>
<div class="flex-disf panle-seat">
<div class="flex-disf-col panle-inbox">
<div class="title">
<h4>各监测项目当前风险预警级别</h4>
</div>
<div class="content flex-rel">
<div class="abs-full scroll-list scrolling4" id="chart4">
<ul class="info-list">
<li v-for="item in alarmList">
<h5><i :class="'level'+(item.alarmlevel)"></i>{{item.name}}</h5>
<span>{{alarmlevel[item.alarmlevel]}}</span><font>{{item.time}}</font>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
</div>
</template>
<script>
import { Tools } from '@/assets/js/common.js';
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Highchart } from '@/assets/js/chartTemplates.js';
export default {
components: {},
data() {
return {
alarmList:[],
alarmlevel:['正常', '红色预警', '橙色预警', '黄色预警', '蓝色预警'],
}
},
mounted() {
this.$nextTick(() => {
this.pageApi = Config.getModuleInfo(this);
this.chart1 = this.$el.querySelector("#chart1");
this.chart2 = this.$el.querySelector("#chart2");
this.chart3 = this.$el.querySelector("#chart3");
// 时钟
var nowTimeEl = this.$el.querySelector("#nowTime");
var Loop1 = qf.Async.intervalLoop(1000, function(){
var dateTime = Tools.Dates.format('yyyy年MM月dd日 HH:mm:ss');
dateTime = dateTime.replace(/年|月|日/g, function(a){return '<span>'+a+'</span>'});
nowTimeEl.innerHTML = dateTime;
//Loop1.clear();
}, function(){
var dateTime = Tools.Dates.format('yyyy年MM月dd日 HH:mm:ss');
dateTime = dateTime.replace(/年|月|日/g, function(a){return '<span>'+a+'</span>'});
nowTimeEl.innerHTML = dateTime;
});
setTimeout(() => {
this.loadData();
}, 500);
});
},
methods: {
loadData(){
// 风险数量年统计
reqApi.common.requstEdge('get', 'tab/Abnormal/statistics', {date:'year'}).then((res)=>{
var list = res.body || [];
var barSeriesData = [], categories = [], Catch = {}, i = 0;
for(var item of list){
var sum = item.red + item.orange + item.yellow + item.blue;
barSeriesData.push({color:Highchart.getRandomColor(i++), y:sum});
console.log(barSeriesData,"____nian")
categories.push(item.name);
Catch['red'] = ~~Catch['red'] + item.red;
Catch['orange'] = ~~Catch['orange'] + item.orange;
Catch['yellow'] = ~~Catch['yellow'] + item.yellow;
Catch['blue'] = ~~Catch['blue'] + item.blue;
};
var pieSeriesData = [
{name:'红色报警', y:Catch['red'], color:'red'},
{name:'橙色报警', y:Catch['orange'], color:'orange'},
{name:'黄色报警', y:Catch['yellow'], color:'yellow'},
{name:'蓝色报警', y:Catch['blue'], color:'blue'},
];
var opts = {
chartConfig:{
chart: {
marginTop:20,
marginLeft:60,
marginBottom:20,
},
title: {
text:''
},
xAxis: {
labels: {
rotation:0,
y:5,
x:-5,
style:{
fontSize:'.14rem',
},
},
categories: categories,
},
plotOptions: {
series: {
stacking: 'normal'
},
bar: {
dataLabels: {
enabled: true,
allowOverlap: true // 允许数据标签重叠
}
}
},
labels: {
},
tooltip: {
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}:</td>' +
'<td style="padding:0"><b>{point.y}</b> </td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true,
},
series: [{
type:'bar',
name: '设备报警数量',
data: barSeriesData,
borderWidth:0,
}, {
type:'pie',
name:'报警统计',
innerSize:'60%',
data:pieSeriesData,
center: ['85%', '50%'],
size: '40%',
borderWidth:0,
showInLegend: false,
dataLabels: {
enabled: false
}
}]
},
isSeriesData:true,
notExtendsOptions:true,
};
Highchart.template.high(this.chart3, {}, opts);
});
// 监测项滚动列表
reqApi.common.requstEdge('get', '/tab/Abnormal/typelist', {}).then((res)=>{
var body = res.body || [];
this.alarmList = body;
this.$nextTick(() => {
// 小窗口无缝滚动
var scrollMsg = this.$el.querySelector("#scrollMsg");
var listBox = scrollMsg.firstElementChild.firstElementChild;
var risk = this.getHighAlarmLevel(body);
listBox.innerHTML = '<li><h5><i></i>尾矿库风险等级</h5><span class="level'+(risk.level)+'">'+risk.text+'</span></li>';
Tools.singleViewSeamlessScroll(scrollMsg);
// 列表滚动
var chart4 = this.$el.querySelector("#chart4");
qf.UI.scrollingPreview(chart4);
});
});
// 风险数量月统计
reqApi.common.requstEdge('get', 'tab/Abnormal/statistics', {date:'month'}).then((res)=>{
var list = res.body || [];
var barSeriesData = [], categories = [], Catch = {}, i = 0;
for(var item of list){
var sum = item.red + item.orange + item.yellow + item.blue;
barSeriesData.push({name:item.equipname, y:sum, color:Highchart.getRandomColor(i++)});
categories.push(item.name);
Catch['red'] = ~~Catch['red'] + item.red;
Catch['orange'] = ~~Catch['orange'] + item.orange;
Catch['yellow'] = ~~Catch['yellow'] + item.yellow;
Catch['blue'] = ~~Catch['blue'] + item.blue;
};
var pieSeriesData = [
{name:'红色报警', y:Catch['red'], color:'red'},
{name:'橙色报警', y:Catch['orange'], color:'orange'},
{name:'黄色报警', y:Catch['yellow'], color:'yellow'},
{name:'蓝色报警', y:Catch['blue'], color:'blue'},
];
// 监测项按月统计
var itemOptions = {
chartConfig:{
chart: {
type: 'column',
marginTop:15,
marginLeft:20,
marginBottom:15,
},
xAxis: {
labels: {
rotation:-25,
style:{
//fontSize:'.14rem',
},
},
visible:false,
},
tooltip: {
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}:</td>' +
'<td style="padding:0"><b>{point.y}</b> </td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true,
},
series: [{
type: 'column',
name: '设备报警数量',
data: barSeriesData,
borderWidth:0,
dataLabels: {
enabled: true,
rotation: -90,
color: '#FFFFFF',
align: 'right',
//format: '{point.y:.1f}', // :.1f 为保留 1 位小数
y: 10
}
}]
},
isSeriesData:true,
notExtendsOptions:true,
};
Highchart.template.high(this.chart1, {}, itemOptions);
//风险等级数量月统计
var pieOptions = {
chartConfig:{
chart: {
type: 'pie',
animation: false,
events: {
load: function() {
}
},
options3d: {
enabled: true,
alpha: 65,
beta: 0
},
marginLeft:5,
marginRight:5,
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
depth: 35,
dataLabels: {
enabled: true,
connectorPadding:0,
distance:15,
}
}
},
tooltip: {
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}:</td>' +
'<td style="padding:0"><b>{point.y}</b> </td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true,
},
series: [{
type:'pie',
name:'报警统计',
//innerSize:'70%',
data:pieSeriesData,
size: '80%',
borderWidth:0,
}]
},
isSeriesData:true,
notExtendsOptions:true,
};
Highchart.template.high(this.chart2, {}, pieOptions);
});
},
// 获取最高报警值
getHighAlarmLevel(list){
var value = 0;
for(var item of list){
if(!value || item.alarmlevel && item.alarmlevel < value){
value = item.alarmlevel;
}
};return {text:this.alarmlevel[value], level:value};
},
},
}
</script>
<style lang="scss" scope>
@font-face {
font-family:"diget year";
src: url("~@/assets/fonts/DS-Digital.ttf");
};
.font_digit{font-family:diget year;}
.ScreenFX {
position:relative;height:100%;width:100%;overflow:hidden;background-color:#00164e;
.a_0, .b_0, .c_0{position:absolute;}
.a_0{
position:relative;height:100%;width:100%;
background:no-repeat center center url('~@/assets/images/fx_bg_min.png');
background-size:100% 100%;
}
.b_0{
top:0;left:0;width:100%;height:100%;
header{
position:absolute;top:0;left:0;height:0;width:100%;display:flex;justify-content:center;color:#2EF4EE;z-index:10;
.b1_a, .b1_b, .b1_c{position:absolute;}
.b1_a{
position:absolute;width:7.75rem;height:.75rem;margin-left:.20rem;
&:before{
content:"";position:absolute;top:0;left:0;height:100%;width:100%;
background-image:linear-gradient(to bottom, transparent 0%, #005fd3 80%);
transform:scaleY(1.00) perspective(1rem) rotateX(-13deg);
}
h1{
position:relative;z-index:1;
font-size:.45rem;line-height:1;margin-top:-.04rem;text-align:center;line-height:.75rem;
background-image:linear-gradient(to bottom, #f1ffff, #b8ecf9, #7fcfff);
-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:.03rem;
}
}
.b1_b{
top:.49rem;left:.49rem;height:.40rem;width:4.55rem;display:flex;
a{
width:1.10rem;height:.36rem;line-height:.36rem;background-color:#0d3475;margin-right:5px;border-radius:.12rem;text-align:center;font-size:.14rem;cursor:pointer;color:#36CCD4;
}
.date{
line-height:.43rem;font-size:.28rem;margin-left:.10rem;
span{font-family:serif;font-size:.24rem;margin:0 .05rem;}
}
}
.b1_c{
top:.49rem;right:.49rem;height:.43rem;width:4.30rem;line-height:.40rem;font-size:.16rem;
.photo-frame{
position:relative;height:100%;width:100%;
&:before, &:after, .in-box:before, .in-box:after{
content:"";position:absolute;height:.10rem;width:.10rem;z-index:1;
border-style:solid;border-color:#C0E2FF;
}
&:before, &:after{top:-1px;}
&:before{left:-1px;border-width:.02rem 0 0 .02rem;}
&:after{right:-1px;border-width:.02rem .02rem 0 0;}
.in-box{
position:absolute;top:0;left:0;height:100%;width:100%;
&:before, &:after{bottom:-1px;}
&:before{left:-1px;border-width:0 0 .02rem .02rem;}
&:after{right:-1px;border-width:0 .02rem .02rem 0;}
ul{
position:relative;height:100%;overflow:hidden;margin:0 .15rem;
li{
position:absolute;top:0;left:0;height:100%;width:100%;
display:flex;justify-content:space-between;
transform:scale(1);transform-origin:0px 0px;transform:translateY(100%);
}
.is-animating{
transition:transform .4s ease-in-out;
}
.scroll-in{
transform:translateY(0%) scale(1);
}
.scroll-out{
transform:translateY(-100%) scale(1);
}
.level1{
color:#F93C58,
}
.level2{
color:#FA953A,
}
.level3{
color:#E9FA3C,
}
.level4{
color:#3BAFFB,
}
}
}
}
}
}
.b_2, .b2_a{height:100%;width:100%;}
.b2_a{
position:relative;
.abs-flex{
top:1.12rem;height:9.20rem;width:4.87rem;flex-direction:column;
.panle-seat{
margin-top:.20rem;
background:no-repeat center center url('~@/assets/images/fx_panel_min.png');
background-size:100% 100%;
.panle-inbox{
margin:.14rem;
}
.title{
margin:.10rem 0;
background-image:linear-gradient(to right, transparent 10%, #075CAD, transparent 90%);
h4{
height:.30rem;line-height:.30rem;text-align:center;font-family:serif;font-size:.20rem;
background-image:linear-gradient(to bottom, #f1ffff, #b8ecf9, #7fcfff);
-webkit-background-clip:text;-webkit-text-fill-color:transparent;
}
}
}
.panle-seat:first-child{
margin-top:0;
}
.scroll-list{
overflow-y:scroll;
}
}
.b2_a1{left:.34rem;}
.b2_a3{right:.34rem;}
.b2_a2{
color:#fff;font-size:.30rem;
.b2a_2a{
top:4.07rem;left:9.50rem;
}
.b2a_2b{
top:5.27rem;left:6.25rem;
}
.b2a_2c{
top:5.16rem;left:12.95rem;
}
.b2a_2d{
top:7.55rem;left:9.60rem;
}
}
}
}
.info-list{
li{
display:flex;justify-content:space-between;height:.49rem;line-height:.47rem;
border:1px solid #0f5680;margin:.06rem 0;padding:0 .10rem;
background-image:linear-gradient(to right, transparent 30%, #13286b 80%);color:#35ecfa;
h5{
font-weight:normal;color:#fff;font-size:.14rem;
display:flex;align-items:center;
i{
position:relative;width:.30rem;height:.24rem;margin-right:.06rem;
display:flex;justify-content:center;
&:before{
content:"";position:absolute;height:0;width:0;bottom:0;
border-width:.24rem .14rem;border-style:solid;
}
&:after{
content:"!";position:absolute;font-style:normal;line-height:.30rem;font-size:.14rem;color:black;
}
}
.level0{
&:before{
border-color:transparent;
}
&:after{
content:"";
}
}
.level1{
&:before{
border-color:transparent transparent #F93C58 transparent;
}
}
.level2{
&:before{
border-color:transparent transparent #FA953A transparent;
}
}
.level3{
&:before{
border-color:transparent transparent #E9FA3C transparent;
}
}
.level4{
&:before{
border-color:transparent transparent #3BAFFB transparent;
}
}
}
span{font-size:.16rem;display:inline-block;margin-left:5px;}
font{font-size:.14rem;margin-left:5px;}
h5, span, font, div{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;word-wrap:normal;}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="Screen cm-layout">
<div class="a_0">
<!-- <cesium
ref="CesiumMap"
:mapinfo="mapinfo"
:onload="mapOnload"
@click="mapClick"
/> -->
</div>
<div class="b_0">
<header>
<div class="b1_a">
<h2>{{title}}</h2>
<div class="b1_a1">
<span class="font_digit" id="nowTime"></span>
</div>
<div class="b1_a2 logo"></div>
</div>
</header>
<section class="b_2">
<div class="b_2a">
<div class="b2_a">
<div class="b2_a1">
<div v-for="(item, i) in area.b2_a1" class="view-item">
<div class="view-flx">
<Carousel
:ref="'view_' + item.id"
/>
</div>
</div>
</div>
<div class="b2_a2" id="b2_a2">
<div class="b2a_2a view-item" v-for="(item, i) in area.b2a_2a">
<div class="view-flx">
<Center-Views
:ref="'view_' + item.id"
/>
</div>
</div>
<div class="b2a_2b">
<div v-for="(item, i) in area.b2a_2b" class="view-item">
<div class="view-flx">
<Carousel
:ref="'view_' + item.id"
/>
</div>
</div>
</div>
</div>
<div class="b2_a3">
<div v-for="(item, i) in area.b2_a3" class="view-item">
<div class="view-flx">
<Carousel
:ref="'view_' + item.id"
/>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
</div>
</template>
<script>
import { Tools } from '@/assets/js/common.js';
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Highchart } from '@/assets/js/chartTemplates.js';
//import cesium from '@/components/Cesium';
import Carousel from '@/components/Carousel';
import CenterViews from '@/components/CenterViews';
// style
//import '@/../static/js/Cesium/Widgets/widgets.css';
export default {
components: {Carousel, CenterViews},
data() {
return {
area:{
b2_a1:[],
b2a_2b:[],
b2_a3:[],
views:[],
},
title:'',
}
},
mounted() {
var that = this;
this.$nextTick(() => {
this.pageApi = Config.getModuleInfo(this);
// 时钟
var nowTimeEl = this.$el.querySelector("#nowTime");
var Loop1 = qf.Async.intervalLoop(1000, function(){
var dateTime = Tools.Dates.format('yyyy年MM月dd日 HH:mm:ss');
dateTime = dateTime.replace(/年|月|日/g, function(a){return '<span>'+a+'</span>'});
nowTimeEl.innerHTML = dateTime;
//Loop1.clear();
}, function(){
var dateTime = Tools.Dates.format('yyyy年MM月dd日 HH:mm:ss');
dateTime = dateTime.replace(/年|月|日/g, function(a){return '<span>'+a+'</span>'});
nowTimeEl.innerHTML = dateTime;
});
qf(function(){
this.initData();
}.bind(this));
var user = this.$store.state.user.user;
var roles = user.roles || [];
var userLevel = roles[0] && roles[0].level || 0;
//报警弹窗
(function reqAlarmsPopup(){
that.pageApi.alterAbnormal('get', {}).then((res)=>{
var list = res.body || [];
qf.Async.loopList.call(this, list, function(key, item, next){
var alarmDict = ['',
{name:'红色报警', color:'red'}, {name:'橙色报警', color:'orange'},
{name:'黄色报警', color:'#FFC900'}, {name:'蓝色报警', color:'blue'},
];
var btnCtrl = userLevel === 1 ? '<button data-id="0">解除报警</button><button data-id="1" style="margin-left:30px;">关闭报警</button>' : '';
var alarmItem = alarmDict[item.alarmlevel];
var name = item.equipname;
var Notify = new qf.UI.Notify({
type: 'warning',
duration: 10000,
autoOpen:true,
message: '<div><div>'+name+' <span style="color:'+alarmItem.color+'">'+alarmItem.name+'</span> '+item.evalue+'('+item.unit+')</div><div>时间:'+item.time+'</div><div class="btn-groub" style="margin-top:5px;display:flex;justify-content:flex-end;">'+btnCtrl+'<button data-id="2" style="margin-left:30px;">不再提示</button></div></div>',
onClose: function(v){
setTimeout(function(){
next()
}, ~~(1+Math.random()*3) * 1000);
},
onClick: function(tag){
if(tag.nodeName === 'BUTTON'){
var self = this, id = tag.dataset.id;
if(id === '0'){ // 解除报警
Notify.pause();
that.openRelieveAlarm({equipno:item.equipno}, function(){
Notify.close(true);
reqAlarmsPopup();
}, function(){
Notify.recover();
});
}else if(id === '1'){ // 关闭报警
Notify.pause();
qf.UI.popupLayer({
title:'提示',
className:'confirm',
closeBtnColor:'#eee',
width:'350px',
html:'点击确认后,该条数据仍会处于报警状态,但是不会再提示,您确认要这么做吗?',
confirm: function(el){
var parm = {id:item.id};
that.pageApi.alterAbnormal('put', parm).then((res)=>{
if(res.code === 200){
Notify.close();
};
});
},
close: function(){
Notify.recover();
},
});
}else if(id === '2'){ // 不再提示
delete this.onClose;
Notify.close();
};
};
},
});
}, function(){
setTimeout(function(){
reqAlarmsPopup();
}, 15000);
})
});
}.bind(this))();
});
},
methods: {
// 创建区域列表
initData(list){
var self = this;
this.pageApi.getViewsConfig().then((res)=>{
if(res.code === 200){
var areas = res.body || [];
for(var area of areas){
this.area[area.areaid] = area.views;
this.area.views = this.area.views.concat(area.views);
};
// onload
this.$nextTick(() => {
new qf.Async.intervalLoop(600000, function(){
// 加载数据
self.loadViewData(self.area.views);
})
});
};
});
// 标题
reqApi.system.moduleConfig.reqScreenTitle('get').then((res)=>{
var body = res.body || {};
this.title = body.title || '';
});
},
// 加载模块数据
loadViewData(list){
//list = list.splice(0, 1);
// 模块数据加工
var viewDatas = {};
for(var item of list){
var viewCode = 'view_'+item.id;
viewDatas[viewCode] = item;
var view = (this.$refs[viewCode] || [])[0];
var slider = view && view.createViews(item).then(panels => {
this.moduleInfoDistribute(panels);
});
};
},
// 模块信息分发
moduleInfoDistribute(panels){
Tools.asyncLoop.call(this, panels, function(key, panel, next){
var item = panel.item, param = {range:item.range,subitem:item.subitem,values:item.values, deviceid:item.deviceid}, type = panel.type;
if(type === 't_1'){ // 干滩
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var opts = {
chartConfig:{
},
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_2'){ // 库水位
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var opts = {
chartConfig:{
plotOptions: {
column: {
grouping: false,
shadow: false,
borderWidth: 0
}
},
},
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_3'){ // 表面位移
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var opts = {
chartConfig:{
xAxis: {
labels: {
rotation: 0, // 设置轴标签旋转角度
},
},
},
warningLine:'double',
maxValDev:.5,
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_4'){ // 内部位移
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var chartType = param.values === '水平' ? 'bar' : 'column';
var opts = {
chartConfig:{
chart:{
type:chartType,
borderWidth:0,
marginLeft:55,
},
},
warningLine:'double',
maxValDev:.5,
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_5'){ // 浸润线
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var opts = {
chartConfig:{
chart:{type:'bar', marginLeft:55,},
xAxis: {
labels: {
rotation: 0, // 设置轴标签旋转角度
},
},
/*
plotOptions: {
series: {
stacking: 'normal'
}
}, */
tooltip: {
formatter: function () {
return this.series.name + ""+ this.key +'<br/>'+ Math.abs(this.y)+'';
}
},
},
callback: function(key, extend, give){
if(key === 'series' && give[key].constructor.name === 'Array'){
var mobj = extend[key], asobj = give[key];
var arr = mobj[1].data, len = arr.length;
for(var i=0; i<len; i++){
var val = arr[i];
arr[i] = 0 - val;
};
};
}
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_6'){ // 降雨量
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var opts = {
chartConfig:{
xAxis: [{
labels: {
rotation: -25, // 设置轴标签旋转角度
},
}],
series:[
{type:'column', color:'#1DF7F9', borderRadius:'.05rem'},
{type:'column', color:'#FAE728', borderRadius:'.05rem'}
],
},
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_7'){ // 排流量
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var opts = {
chartConfig:{
chart: {
type: 'cylinder',
marginLeft:10,
marginRight:-5,
options3d:{
enabled: true,
alpha: 10,
beta: 5, // 左右
depth: 50,
viewDistance: 0
}
},
plotOptions: {
series: {
depth: 25,
//colorByPoint: true
}
},
series:[
{type:'column', color:'#00B2FC', showInLegend:false},
//{type:'spline', color:'#FBC000', showInLegend:false, dashStyle:'Dash', lineWidth:1,}
],
},
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_8'){ // 水质
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var info = document.createElement("ul");
info.className = 'info';
var len = data.length > 5 ? 5 : data.length, li;
for(var i=0; i<len; i++){
var item = data[i];
if(!(i%2)){
li = document.createElement("li");
};
var div = document.createElement("div");
if(i%2){
div.innerHTML = '<font>'+item.sensroname+'</font><span>'+item.svalue+'</span>';
}else{ // 左
div.innerHTML = '<span>'+item.svalue+'</span><font>'+item.sensroname+'</font>';
};
li.appendChild(div);
info.appendChild(li);
};
panel.el.appendChild(info);
});
}else if(type === 't_9'){ // 渗流量
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var opts = {
chartConfig:{
series:[
{type:'column', color:'#00B2FC'},
//{type:'spline', color:'#FBC000', dashStyle:'ShortDot',}
],
},
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_10'){ // 设备信息
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
panel.info.sum = data.all;
panel.info.online = data.online;
panel.info.offline = data.unline;
var opts = {
chartConfig:{
chart: {
backgroundColor:'transparent',
marginBottom: null,
marginLeft: null,
},
title: {
floating:true,
text: '总数<br/>'+data.all,
verticalAlign: 'middle',
y:22,
floating: true,
style:{
color:'#00f6ff',
}
},
tooltip: {
formatter: function (e) {
return this.key +''+ this.y;
}
},
plotOptions: {
pie: {
allowPointSelect: true,
borderWidth: 0,
minSize:130,
//size:200,
cursor: 'pointer',
dataLabels: {
enabled: true,
distance:10,
format: '<b>{point.name}</b>: {point.y}',
style: {
color: 'black'
}
},
}
},
series: [{
type: 'pie',
innerSize: '70%',
name: '设备数量',
data: [
{name:'在线', y:data.online, color:'#48abe1'},
{name:'离线', y:data.unline, color:'#064f94'},
],
}]
},
isSeriesData:true,
type:item.type,
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_11'){ // 实时数据
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var datas = res.body || {}, target = panel.el;
var scrolling = target.parentNode;
var dataList = [];
for(var item of datas){
var data = item.data, time = item.time;
if(data){
for(var kitem of item.keys){
dataList.push({
name:item.name+ ' ' + kitem.name, value:data[kitem.key],
unit:item.eqdanwei,
time:time,
});
};
};
};
// 创建列表
var frag = document.createDocumentFragment();
var ul = document.createElement('ul');
ul.calssName = 'list';
for(var item of dataList){
var li = document.createElement('li');
li.innerHTML = '<h5>'+item.name+'</h5><div><span>'+item.value+'</span><font>('+item.unit+')</font></div><font>'+item.time+'</font>';
ul.appendChild(li);
};
target.firstElementChild.innerHTML = '';
target.firstElementChild.appendChild(ul);
qf.UI.scrollingPreview(scrolling);
});
}else if(type === 't_12'){ // 报警信息
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var dataList = res.body || {}, target = panel.el;
var scrolling = target.parentNode;
// 创建列表
var frag = document.createDocumentFragment();
var ul = document.createElement('ul');
ul.calssName = 'list';
for(var item of dataList){
var li = document.createElement('li');
var value = item.evalue + '('+item.eqdanwei+')';
li.innerHTML = '<h5><i class="level'+item.alarmlevel+'"></i>'+item.equipname+'</h5><span> '+value+'</span><font>'+item.time+'</font>';
ul.appendChild(li);
};
target.firstElementChild.innerHTML = '';
target.firstElementChild.appendChild(ul);
qf.UI.scrollingPreview(scrolling);
});
}else if(type === 't_13'){ // 实时天气
var city = panel.item.city_weather || "weihai";
var param = {c:'code', a:'getcode', id:48, icon:1, py:city};
reqApi.getWeather(param).then((res)=>{
var body = document.createElement("div");
setTimeout(function(){
body.innerHTML = res;
var styles = body.querySelectorAll("link");
for(var style of styles){
body.removeChild(style)
};
var scripts = body.querySelectorAll("script");
for(var script of scripts){
script.parentNode.removeChild(script)
};
// 查看图片
var img = body.querySelector("#day_1 .img").firstElementChild;
img.src = 'http://plugin.tianqistatic.com/static/' + img.src.split('static/')[1];
// 修剪dom
var mobile05 = body.querySelector("#mobile05");
var mleft = mobile05.firstElementChild;
var cityCtn = mleft.firstElementChild;
var cityEl = document.createElement("font");
cityEl.innerText = '('+cityCtn.firstElementChild.innerText+')';
mleft.nextElementSibling.firstElementChild.appendChild(cityEl);
mobile05.removeChild(mleft);
mobile05.removeChild(mobile05.lastElementChild);
var childs = mobile05.children;
for(var child of childs){
child.innerHTML = child.firstElementChild.innerHTML;
}
panel.el.innerHTML = '<div class="weather" style="padding-top:0.2rem">'+body.innerHTML+'</div>';
}, 300);
});
}else if(type === 't_14'){ // 视频监控
param.id = item.id;
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var vparam = {
id:data.v_id,
appKey:data.v_appkey,
appSecret:data.v_appsecret,
name:data.v_name,
channel:data.v_channel,
remark:data.v_remark,
};
panel.setData(vparam)
});
}else if(type === 't_15'){ // 监测点
var initModule = () => {
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
panel.setData(data, Tools, this.pageApi, initModule)
});
};
initModule();
/* new qf.Async.intervalLoop(30000, function(){
initModule();
}, function(){
initModule();
}) */
}else if(type === 't_16'){ // 外坡比
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
var opts = {
chartConfig:{
plotOptions: {
column: {
grouping: false,
shadow: false,
borderWidth: 0
}
},
},
};
Highchart.template.high(panel.el, data, opts);
});
}else if(type === 't_17'){ // 浸润线剖面
reqApi.common.requstEdge('get', item.requrl, param).then((res)=>{
var data = res.body || {};
data.alarm.value ={}
this.cuCharts(panel.el, data, {
axisLineWidth:2,
axisColor:'pink',
});
});
};
next();
}, function(){});
},
cuCharts(ctn, data, opts){
var cuCharts=function(ctn,data,opts){var ctn=this.ctn=typeof element==="string"?document.getElementById(ctn):ctn;if(!ctn)return console.log('%c cuCharts Error Element is a invalid param! ','color:red');var self=this,setDpr=1;var dpr=window.devicePixelRatio||qf.envir.dpr;self.dpr=dpr*setDpr;self.Cache={};!ctn.style.position&&(ctn.style.position='relative');var canvas=this.canvas=document.createElement("canvas");canvas.style.cssText='position:absolute;height:100%;width:100%;';this.ctx=canvas.getContext("2d");ctn.appendChild(canvas);var defaults=this.defaults={altitude:1000,damHeight:data.dissect.height||100,damWidth:data.dissect.width||100,axisLineWidth:6,axisColor:'red',margin:{top:14,right:0,bottom:0,left:18},};var left=defaults.margin.left*this.dpr,top=defaults.margin.top*this.dpr,right=defaults.margin.right*this.dpr,bottom=defaults.margin.bottom*this.dpr;this.ladders=data.steps||[];this.devices=this.formatDeviceParam(data.devices);var ladderInfo=this.discernDamHeight(this.ladders);this.options={damWidth:defaults.damWidth,damHeight:ladderInfo.damHeight,axisLineWidth:defaults.axisLineWidth||6,stepAverageHeight:ladderInfo.averageHeight,initX:defaults.margin.left*dpr+(defaults.axisLineWidth/2),initY:defaults.margin.top*dpr,bottomDist:defaults.margin.bottom*dpr,rightDist:defaults.margin.right*dpr,waterArea:{startAngle:data.dissect.sdeg,radius:data.dissect.diameter},alarm:data.alarm,axisLineWidth:opts.axisLineWidth||defaults.axisLineWidth,axisColor:opts.axisColor||defaults.axisColor,};this.init()};cuCharts.prototype={init:function(){this.setModule();this.onresize()},drawAxis:function(color,damHeight){var lw=this.options.axisLineWidth;var wHalf=lw/2;var initX=this.options.initX;var endX=this.options.endX;var endY=this.options.endY;var axisYSX=initX-wHalf;var axisXEY=endY+lw;var axisYEY=endY+wHalf;this.drawLiner({sx:axisYSX,sy:0,ex:axisYSX,ey:axisXEY,width:lw,color:color});var fontY=~~(this.options.damPxHeight/2+this.options.initY);var fontSize=12;var axisXText='剖面高度'+~~damHeight+'';this.drawText({x:this.options.initY/2+2,y:fontY,size:fontSize,width:fontSize*this.dpr,text:axisXText,color:'#fff',align:'center',vertical:'center',});this.drawLiner({sx:initX,sy:axisYEY,ex:endX,ey:axisYEY,width:lw,color:color})},drawSteps:function(ladders){ladders=ladders||[0];var initX=this.options.initX,initY=this.options.initY;var cumulationX=initX,cumulationY=initY;var damLength=this.options.endX;var damDepth=this.options.endY;var pxRetioY=this.options.pxRetioY;var averageHeight=this.options.stepAverageHeight*pxRetioY;var damPxWidth=this.options.damPxWidth;var damPxHeight=this.options.damPxHeight;var len=ladders.length;var stepWidth=damPxWidth/(len+0);var stepHeight=damPxHeight/(len+0);var slopeRatio=damPxHeight/damPxWidth;var maxStepDepth={ratio:slopeRatio};this.Cache.ladders=[];for(var i=0;i<len;i++){var item=ladders[i];var setWidth=item.width*this.dpr*this.options.pxRetioX;var setHeight=item.height*pxRetioY||averageHeight;var slope=item.slope||0;var aCoord=this.byAngleAndHeightToCoord(slope,setHeight);var fEndX,fEndY;if(setWidth){fEndX=cumulationX+setWidth;stepWidth=(damLength-(cumulationX+setWidth+aCoord.x*this.dpr))/(len-(i+1))}else{fEndX=cumulationX+(stepWidth-aCoord.x*this.dpr)};if(setHeight){fEndY=cumulationY+setHeight;stepHeight=(damDepth-(cumulationY+setHeight))/(len-(i+1))}else{fEndY=cumulationY+stepHeight};var lEndX=fEndX+aCoord.x*this.dpr,lEndY=fEndY+aCoord.y*this.dpr;var stepDepthRatio=(damDepth-~~lEndY)/(damLength-lEndX);if(stepDepthRatio&&stepDepthRatio<maxStepDepth.ratio&&i<len-1){maxStepDepth={ratio:stepDepthRatio,x:lEndX,y:lEndY,}};this.drawLiner({sx:cumulationX,sy:cumulationY,ex:fEndX,ey:cumulationY,width:2,color:"#8b8b8b"});this.drawLiner({sx:fEndX,sy:cumulationY,ex:lEndX,ey:lEndY,width:2,color:"#8b8b8b"});this.Cache.ladders[i]={sx:cumulationX,sy:cumulationY,ex:fEndX,ey:cumulationY,slope:slope,slopeX:lEndX,slopeY:lEndY,xy:aCoord.xy};cumulationX=lEndX;cumulationY=lEndY};this.drawLiner({sx:cumulationX,sy:cumulationY,ex:damLength,ey:damDepth,width:2,color:"#8b8b8b"});var damHeight=(cumulationY-this.options.initY)/pxRetioY;return maxStepDepth.damHeight=damHeight,maxStepDepth},drawDevice:function(list){var lineW=4*this.dpr,deviceW=6*this.dpr,deviceH=3*this.dpr;var initX=this.options.initX;var endX=this.options.endX;var endY=this.options.endY;var ladders=this.Cache.ladders||[];var fontSize=11;var fontTopDev=fontSize*this.dpr+3;this.options.deviceCoords=[];for(var device of list){var holeX=~~(endX-device.x*this.options.pxRetioX);var depthText='埋深'+device.depth+'';var holeDistY=device.holeDepth*this.options.pxRetioY;var deviceY=device.value*this.options.pxRetioY;var ladderSY=this.xPixelToStepsYPixel(holeX);this.drawText({x:holeX,y:ladderSY-fontTopDev,size:fontSize,text:depthText,color:'red',align:'center',});var holeEndY=ladderSY+holeDistY;holeEndY=holeEndY>endY?endY:holeEndY;this.drawLiner({sx:holeX,sy:ladderSY,ex:holeX,ey:holeEndY,width:lineW,color:"grey"});var deviceLY=ladderSY+deviceY;var deviceEY=deviceLY+(deviceH/2);var deviceSY=deviceEY-deviceH;this.drawLiner({sx:holeX,sy:deviceSY,ex:holeX,ey:deviceEY,width:deviceW,color:"#3403CB"});this.options.deviceCoords.push({x:holeX,y:deviceLY,stepY:ladderSY});var valFont=11;var valueSY=~~(deviceSY-valFont*this.dpr-6);var text='水位值'+device.waterValue+'';this.drawText({x:holeX,y:valueSY,size:valFont,text:text,color:'white',align:'center',})}},drawAlarmLine:function(alarms,Steps){var alarmValues=alarms.value;var alarmLevel=alarms.alarmLevel;var deviceCoords=this.options.deviceCoords||[];var deviceSX=deviceCoords[0].x;var deviceSY=deviceCoords[0].y;var initX=this.options.initX;var initY=this.options.initY;var endY=this.options.endY;var endX=this.options.endX;var alarmLevelNum=['red','orange','yellow','blue']||Object.keys(alarmValues);var alarmLine={};var level=(~~alarmLevel||alarmLevelNum.length+1)-1;var nearLevel=level?level-1:level;var alarm=alarmLevelNum[level];var nearAlarm=alarmLevelNum[nearLevel];alarmLine[nearAlarm]=alarmValues[nearAlarm];if(alarm){alarmLine[alarm]=alarmValues[alarm]};var alarmRealParam=this.getAlarmRealParam(Object.values(alarmLine))||Steps.ratio;var deviceSlopeRatio=alarmRealParam.ratio;for(var key in alarmLine){var value=alarmValues[key];if(key){var ladderSY=this.xPixelToStepsYPixel(deviceSX)-initX+6;var lineSY=(value*this.options.pxRetioY+ladderSY)-(deviceSX-initX)*deviceSlopeRatio;var lineEX=(endY-lineSY)/deviceSlopeRatio;this.drawLiner({sx:initX,sy:lineSY+initY,ex:lineEX,ey:endY,width:2,color:key})}}},getCirHeightDev:function(r,x){return r-Math.sqrt(Math.pow(r,2)-Math.pow(x,2))},drawWaterArea:function(depth){depth=100;var startAngle=this.options.waterArea.startAngle;var radiusMultiple=this.options.waterArea.radius;var angleRatio=90/0.5;var initArc=startAngle/angleRatio;var ctx=this.ctx,initX=this.options.initX;var arcOrigin=1.50,arcStart=arcOrigin+initArc;var sAngle=(arcStart-arcOrigin)*angleRatio;var r1=this.options['damPxWidth']*radiusMultiple;var waterApexToAxisXDist=Math.sin(sAngle*0.017453293)*r1;var sAngleToTopSpotDist=(r1-(Math.cos(sAngle*0.017453293)*r1));var depth=(depth||30)*this.options.pxRetioY+sAngleToTopSpotDist;var firstDeviceX=this.devices[0].x*this.options.pxRetioX;var ladderSY=this.xPixelToStepsYPixel(firstDeviceX+initX)-initX+6;var deviceToAxisXDist=firstDeviceX+waterApexToAxisXDist;var deviceToAxisYDist=Math.sqrt(r1*r1-deviceToAxisXDist*deviceToAxisXDist);var deviceAreaToApexDev=r1-deviceToAxisYDist-sAngleToTopSpotDist-ladderSY;var firstDeviceY=this.options.damPxHeight-this.devices[0].value*this.options.pxRetioY;firstDeviceY+=deviceAreaToApexDev;var ry=r1+this.options.endY-sAngleToTopSpotDist-firstDeviceY;var lineToY=r1-sAngleToTopSpotDist-firstDeviceY;var eAngle=Math.acos(lineToY/r1)/0.017453293;var arcEnd=eAngle/angleRatio+arcOrigin;ctx.beginPath();ctx.arc(initX-waterApexToAxisXDist,ry,r1,arcStart*Math.PI,arcEnd*Math.PI,false);ctx.lineTo(initX,ry-lineToY);ctx.fillStyle='#00A2E8';ctx.fill()},byAngleAndHeightToCoord:function(angle,height){var devX=Math.tan(angle*0.017453293)*height;var xy=height/Math.cos(angle*0.017453293);var devY=height-devX;var yRatio=height/devX;var x=0,y=0;if(angle>50){x=height,y=devY*yRatio}else{x=devX,y=0};return{x:x,y:y,xy:xy}},discernDamHeight(list){var not=0,set=0,sum=0;for(var item of list){var height=item.height;height?(set++,sum+=height):not++};var damHeight=not?this.defaults.damHeight:sum;var averageHeight=(damHeight-sum)/not;return{averageHeight:averageHeight,damHeight:damHeight}},setModule:function(){this.ctx.clearRect(0,0,this.SumWidth,this.SumHeight);var canvas=this.canvas;var SumWidth=this.SumWidth=(this.ctn.clientWidth*this.dpr)-this.ctn.clientLeft-0;var SumHeight=this.SumHeight=this.ctn.clientHeight*this.dpr-this.ctn.clientTop-0;canvas.width=SumWidth*this.dpr;canvas.height=SumHeight*this.dpr;canvas.style.cssText='position:absolute;top:0;left:0;height:'+(SumHeight)+'px;width:'+SumWidth+'px;user-select: none;-webkit-tap-highlight-color:rgba(0,0,0,0);padding:0;margin:0;border-width:0;box-sizing: border-box;';var top=this.options.initY,left=this.options.initX,bottom=this.options.bottomDist,right=this.options.rightDist;var damPxWidth=SumWidth-(right+left),damPxHeight=SumHeight-(bottom+top+this.options.axisLineWidth),endX=SumWidth-right,endY=SumHeight-bottom-this.options.axisLineWidth;this.options['endX']=endX;this.options['endY']=endY;this.options['damPxWidth']=damPxWidth;this.options['damPxHeight']=damPxHeight;this.options['pxRetioX']=damPxWidth/this.defaults.damWidth;this.options['pxRetioY']=damPxHeight/this.options.damHeight;this.options['HWRation']=(endY-top)/(endX-left);this.drawChart()},formatDeviceParam:function(devices){var devices=devices||[];var arr=[];for(var item of devices){arr.push({x:item.jrx_coord_x,holeDepth:item.jrx_trepanning,value:item.depth,depth:item.jrx_burial,waterValue:item.stage})};return arr},getAlarmRealParam:function(aValues){var aval=aValues[0];var coords=this.options.deviceCoords||[];var valY=aval*this.options.pxRetioY;var sy=valY+coords[0].stepY,sx=coords[0].x,ey=0,ex=0;var len=coords.length;for(var i=1;i<len;i++){var item=coords[i];ey=valY+item.stepY,ex=item.x};return{ratio:(ey-sy)/(ex-sx),sy:sy,ey:ey}},drawChart:function(){var Steps=this.drawSteps(this.ladders);this.drawAxis(this.options.axisColor,Steps.damHeight);var depth=55;this.drawWaterArea(depth);this.drawDevice(this.devices);this.drawAlarmLine(this.options.alarm,Steps)},onresize:function(){qf.resize(()=>{this.setModule()})},updateData:function(data){data=data||{};this.stations=data.stations||this.stations;this.points=data.points||this.points;this.draw(this.cacheX+this.destX,true)},drawLiner:function(o){var ctx=this.ctx;ctx.beginPath();ctx.moveTo(o.sx,o.sy);ctx.lineTo(o.ex,o.ey);ctx.lineWidth=o.width;ctx.strokeStyle=o.color;ctx.stroke()},drawText:function(o){var ctx=this.ctx;var fontSize=(o.size||14)*this.dpr;var text=o.text||'';var textWidth=this.getTextWidth(text,fontSize);var width=o.width||textWidth;var align=o.align||'normal';ctx.font='normal '+fontSize+"px 'Open Sans', 'PingFang SC', Helvetica, Arial, sans-serif";var rows=[];if(width&&~~width<textWidth){var str='',texts=text.split("");for(var word of texts){var testStr=str+word;var testWidth=ctx.measureText(testStr).width;if(testWidth>width){rows.push(str);str=word}else{if(testWidth===width){rows.push(testStr);str=''}else{str=testStr}}};str&&rows.push(str)}else{rows=text.split(/\r\n|\n/g)};var rlen=rows.length,sumHeight=(rlen+1)*fontSize;var x=o.x;var y=o.vertical==='center'?o.y-(sumHeight/2):o.y;var color=o.randomColor?this.getRandomColor():o.color||'red';var lsx=x,lsy=y;for(var b=0;b<rlen;b++){if(align==='center'){var textW=this.getTextWidth(rows[b],fontSize);lsx=x-(textW/2)};lsy=(b+1)*fontSize;ctx.lineHeight=1;ctx.fillStyle=color;ctx.fillText(rows[b],~~lsx+0.5,y+(~~lsy)+0.5)}},getTextWidth:function(text,fontSize){return(this.ctx.measureText(text).width/parseInt(this.ctx.font))*fontSize},drawImg:function(img,x,y,w,h){x=x-w/2;y=y-h;ctx.drawImage(img,x,y,w,h)},getRandomColor:function(){return"#"+Math.floor(Math.random()*16777215).toString(16)},getEventTarget:function(x,y){if(y>bottomReferY-imgA.height-1&&y<bottomReferY+1){var arr=this.points;var i=arr.length-1,obj,halfW=imgA.width/2-1;while(obj=arr[i]){var ix=this.getDrawDoord(obj.x*1);if(Math.abs(ix-x)<halfW){return obj};i--}};if(y>bottomReferY-imgB.height-1&&y<bottomReferY+1){var arr=this.stations;var i=arr.length-1,obj,halfW=imgA.width/2-1;while(obj=arr[i]){var ix=this.getDrawDoord(obj.x*1);if(Math.abs(ix-x)<halfW){return obj};i--}}},xPixelToStepsYPixel:function(x){var ladders=this.Cache.ladders||[],ladderSY=0;for(var ladder of ladders){if(x>=ladder.sx&&x<ladder.slopeX){if(x<ladder.ex){ladderSY=ladder.sy}else{var slopeWidth=ladder.slopeX-ladder.ex;var slopeHeight=ladder.slopeY-ladder.ey;ladderSY=(x-ladder.ex)*(slopeHeight/slopeWidth)+ladder.ey}}};return ladderSY},};return new cuCharts(ctn,data,opts);
},
mapOnload(){
},
openRelieveAlarm(params, fn, close){
var self = this;
qf.UI.popupLayer({
title:'解除报警',
className:'screenAlart',
closeBtnColor:'#eee',
html:'<div class="item"><span>解除人:</span><input data-name="jcman" placeholder="请输入解除人"/></div><div class="item"><span>解除时长(小时):</span><input data-name="jchours" value=12 placeholder="请输入解除时长"/></div><div class="item"><span>报警原因:</span><input data-name="reason" placeholder="报警原因"/></div><div class="item"><span>解除报警原因:</span><input data-name="jcreason" placeholder="解除报警原因"/></div>',
confirm: function(el){
var inputs = el.querySelectorAll("input");
for(var el of inputs){
var key = el.dataset.name;
var val = el.value;
if(key === 'jchours'){
val = parseInt(val) || 12;
}else{
val = val || '默认原因!';
};
params[key] = val;
};
// 解除
self.pageApi.relieveAlarm(params).then((res)=>{
//if(res.code === 200){};
fn && fn()
});
},
close: function(){
close && close()
},
});
},
},
}
</script>
<style lang="scss" scope>
@font-face {
font-family:"diget year";
src: url("~@/assets/fonts/DS-Digital.ttf");
};
.font_digit{font-family:diget year;}
.Screen {
position:relative;height:100%;width:100%;overflow:hidden;background-color:#00164e;
.a_0, .b_0{position:absolute;}
>.actv{display:block;}
.a_0{
top:0;left:0;height:100%;width:100%;
background:no-repeat center center url('~@/assets/images/layout/s_bg_min.png');
background-size:100% 100%;
}
.b_0{
display:flex;width:100%;height:100%;padding-top:.65rem;background-color:rgba(0,0,0,.15);
header{
position:absolute;top:0;left:0;height:.64rem;width:100%;z-index:5;
display:flex;user-select:none;
.b1_a{
position:absolute;top:0;left:0;height:.64rem;width:100%;
background:no-repeat top left url('~@/assets/images/layout/s_hd_min.png');background-size:100% auto;
display:flex;justify-content:center;align-items:center;
h2{
font-size:.32rem;line-height:1;margin-top:-.04rem;
background-image: -webkit-linear-gradient(top, #fff, #d5f3fe, #7adbfe);
-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:.02rem;
}
.b1_a1{
position:absolute;top:0;right:0;height:100%;width:3.5rem;
display:flex;align-items:center;justify-content:left;
.font_digit{
margin-right:.20rem;font-size:.28rem;color:#2ef4ee;
span{font-family:serif;font-size:.24rem;margin:0 .05rem;}
}
}
.b1_a2{
position:absolute;top:0;left:.20rem;height:100%;
display:flex;align-items:center;
&:before{
content:'';display:block;height:.35rem;width:1.58rem;
background:no-repeat top left url('~@/assets/images/logo_ks.png');background-size:100% auto;
}
}
}
}
.b_2{
flex:1;position:relative;margin:0 .08rem;
.b_2a{
position:absolute;top:0;left:0;height:100%;width:100%;
display:flex;flex-direction:column;
.b2_a{
flex:1;display:flex;
.b2_a1, .b2_a3{
flex:1;
>div{
//background-color:pink;
flex:1;
}
}
.b2_a1, .b2_a2, .b2_a3{
display:flex;flex-direction:column;
>div{margin-bottom:.08rem;}
}
.b2_a2{
width:8.84rem;margin:0 .08rem;
>div:first-child{
height:7.52rem;
/* background-color:yellow; */
box-shadow: inset 0rem 0rem 0.15rem 0.24rem rgba(2,43,80, .8);
}
>div:last-child{
//height:2.46rem;
flex:1;
display:flex;
//height:22.777vh;
>div{
flex:1;margin-right:.08rem;
//background-color:pink;
&:last-child{
margin-right:0;
}
}
}
.b2a2_a{
flex:1;position:relative;
/* background:no-repeat center center url('~@/assets/images/layout/map_min.png');background-size:100% auto; */
>div{
display:none;position:absolute;top:0;left:0;height:100%;width:100%;
}
>div.show{display:block;}
>div:first-child{}
}
}
.b2_a3{
}
.view-item{
border:1px solid #004a8b;
position:relative;
box-shadow:inset 0rem 0rem .15rem .04rem rgba(10,106,180,.8);
&:before, &:after, .view-flx:before, .view-flx:after{
content:"";position:absolute;height:.10rem;width:.10rem;z-index:1;
border-style:solid;border-color:#02f6ff;
}
&:before, &:after{top:-1px;}
&:before{
left:-1px;
border-width:.02rem 0 0 .02rem;
}
&:after{
right:-1px;
border-width:.02rem .02rem 0 0;
}
.view-flx{
position:absolute;top:0;left:0;height:100%;width:100%;
background-color:rgb(1,19,70, .3);
&:before, &:after{bottom:-1px;}
&:before{
left:-1px;
border-width:0 0 .02rem .02rem;
}
&:after{
right:-1px;
border-width:0 .02rem .02rem 0;
}
}
}
}
.weather{
font-size:11px;
.mleft{display:none;}
.wtpath{display:none;}
.mright{flex:1;text-align:center;}
img{display:block;width:2vw !important;height:auto !important;margin:0 auto;}
ul{margin:5px 0;color:#d0d2ff;}
#mobile05{
display:flex;position:relative;padding-top:5vh !important;
}
#mobile05>div:last-child{display:none;}
#mright_1{
position:absolute;top:0;left:0;height:auto;width:100%;display:flex;
ul{margin:0;color:#03d3fe;}
.wt{display:flex;align-items:center;margin-left:140px;}
.day{display:none;}
span:last-child{display:block;
position:absolute;top:4px;left:0px;height:auto;
font-size:26px;
}
font{margin:6px 0 0 10px;color:#35ecfa}
}
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
reqApi.common.getRequst.call(this);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
reqApi.common.getRequst.call(this);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page page-t1">
<div class="option page-row">
<!--工具栏-->
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<template v-for="(item, key) in form.config.otherBtn">
<el-button size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</template>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.search = this.Dict.search;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
var searchItem = reqApi.common.getSearchParam(this.form);
reqApi.common.getRequst.call(this, searchItem);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
created(){
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.pageApi.created && this.pageApi.created();
},
mounted() {
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{next()};
});
},
methods: {
loadData:reqApi.common.getRequst,
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="errPage-container">
<el-button icon="arrow-left" class="pan-back-btn" @click="back">
返回
</el-button>
<el-row>
<el-col :span="12">
<h1 class="text-jumbo text-ginormous">
Oops!
</h1>
<h2>你没有权限去该页面</h2>
<h6>如有不满请联系你领导</h6>
<ul class="list-unstyled">
<li>或者你可以去:</li>
<li class="link-type">
<router-link to="/dashboard">
回首页
</router-link>
</li>
</ul>
</el-col>
<el-col :span="12">
<img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream.">
</el-col>
</el-row>
</div>
</template>
<script>
import errGif from '@/assets/401_images/401.gif'
export default {
name: 'Page401',
data() {
return {
errGif: errGif + '?' + +new Date()
}
},
methods: {
back() {
if (this.$route.query.noGoBack) {
this.$router.push({ path: '/dashboard' })
} else {
this.$router.go(-1)
}
}
}
}
</script>
<style lang="scss" scoped>
.errPage-container {
width: 800px;
max-width: 100%;
margin: 100px auto;
.pan-back-btn {
background: #008489;
color: #fff;
border: none!important;
}
.pan-gif {
margin: 0 auto;
display: block;
}
.pan-img {
display: block;
margin: 0 auto;
width: 100%;
}
.text-jumbo {
font-size: 60px;
font-weight: 700;
color: #484848;
}
.list-unstyled {
font-size: 14px;
li {
padding-bottom: 5px;
}
a {
color: #008489;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
}
</style>
<template>
<div class="wscn-http404-container">
<div class="wscn-http404">
<div class="bullshit">
<h1>404</h1>
<div class="bullshit__oops">OOPS!</div>
<div class="bullshit__headline">{{ message }}</div>
<div class="bullshit__info">请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告</div>
<a href="/" class="bullshit__return-home">返回首页</a>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Page404',
computed: {
message() {
return '网管说这个页面你不能进......'
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
</style>
<script>
export default {
created() {
const { params, query } = this.$route
const { path } = params
this.$router.replace({ path: '/' + path, query })
},
render: function(h) {
return h() // avoid warning message
}
}
</script>
<template>
<div class="home_manage cm-layout">
<div class="m-view">
<cu-amap
ref="amap"
:options="amapOptions()"
/>
<div class="b_0">
<ul>
<li><span>尾矿库名称:</span><span>{{unitInfo.tailingname}}</span></li>
<li><span>尾矿库编号:</span><span>{{unitInfo.tailingno}}</span></li>
<li><span>尾矿库地址:</span><span>{{unitInfo.address}}</span></li>
<li><span>值班电话:</span><span>{{unitInfo.ondutytel}}</span></li>
<li><span>安全负责人姓名:</span><span>{{unitInfo.securityofficer}}</span></li>
<li><span>安全负责人电话:</span><span>{{unitInfo.securityofficertel}}</span></li>
<li><span>运行状态:</span><span>{{unitInfo.operatingstatus}}</span></li>
<li><span>安全度:</span><span>{{unitInfo.safetytypeno}}</span></li>
</ul>
</div>
</div>
</div>
</template>
<script>
import { Tools} from '@/assets/js/common.js';
import { reqApi, Config} from '@/assets/js/httpApi.js';
import cuAmap from '@/components/AMap';
export default {
name: 'Dashboard',
components: {cuAmap},
data() {
return {
query:{
page: 1,
size: 10,
total: 0,
sort: 'date,desc'
},
unitInfo:{
'tailingname':'',
'tailingno':'',
'address':'',
'ondutytel':'',
'securityofficer':'',
'securityofficertel':'',
'operatingstatus':'',
'safetytypeno':'',
},
//UnitList:[],
}
},
mounted() {
var that = this;
this.$nextTick(() => {
this.pageApi = Config.getModuleInfo(this);
//this.loadData();
})
},
methods: {
loadData() {
},
amapOptions(cmap){
var self = this;
/* var disCountry = new AMap.DistrictLayer.World({
zIndex: 1,
rejectMapMask: true
}); */
return {
zoom:6,
center:[107.260044, 36.737982],
//showLabel: true,
//pitch: 40,
satellite:true,
/* layers:[
new AMap.TileLayer.RoadNet({
zIndex:7
}),
disCountry,
new AMap.TileLayer.Satellite()
], */
onload: function(cmap){
self.cmap = cmap;
self.getUnitList(cmap);
},
click: function(e, cmap){
},
};
},
getUnitList(cmap){
var self = this;
reqApi.common.requstEdge('get', 'tab/tailpondinfor', {page:0, size:10}).then((res)=>{
var body = res.body || {}, list = body.list || [], len = list.length;
self.UnitList = list;
for(var i=0; i<len; i++){
var item = list[i];
var marker = cmap.addMarker({
//icon:'red1',
lnglat:[item.longitude, item.latitude],
title:item['address'],
extData:{name:item['tailingname'], index:i,},
});
marker.on('click', function(e){
var lnglat = e.target.getPosition(), extData = e.target.getExtData();
var unitItem = self.UnitList[extData.index];
var infoBox = document.createElement("div");
infoBox.style.cssText = 'display:flex;align-items:center;';
infoBox.innerHTML = '<span>'+extData.name+'</span><a class="el-icon-picture" style="margin-left:10px;color:#1890FF;font-size:20px;"></a>';
// moer
infoBox.onclick = function(e){
var tag = e.target || e.srcElement;
if(tag.nodeName === 'A'){
var tailingno = unitItem.tailingno;
self.openMonitorPoint(tailingno);
};
};
var InfoWindow = cmap.createInfoWindow({
offset: new AMap.Pixel(0, -33),
content:infoBox,
//anchor: 'bottom-center',
});
InfoWindow.open(InfoWindow.Map, lnglat);
// 更新窗口
self.setUnitInfo(unitItem);
});
marker.on('dblclick', function(e){
var extData = e.target.getExtData(), lnglat = e.target.getPosition();
var index = extData.index, tagMarker = cmap.getTargetMarker();
var unitItem = self.UnitList[index];
if(tagMarker !== e.target){
// 请求切换尾矿库接口
self.pageApi.switchPond({tailingno:unitItem.tailingno}).then((res)=>{
if(res.code === 200){
// 重置中心点
//cmap.setCenter([unitItem.longitude, unitItem.latitude]);
/* // 清除原标记样式
tagMarker.setIcon(cmap.icons.Default1);
// 设置新标记样式
e.target.setIcon(cmap.icons.red1);
cmap.setTargetMarker(e.target);
// 设置数据
self.setUnitInfo(unitItem); */
window.location.reload();
};
});
};
});
if(item.defaults){
// 地图设置
cmap.setCenter([item.longitude, item.latitude]);
cmap.setTargetMarker(marker);
marker.setIcon(cmap.icons.red1);
this.setUnitInfo(item);
};
};
});
},
openMonitorPoint(tailingno){
var loading = this.$loading({
lock: true,
text: '请稍后.....',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
reqApi.common.requstEdge('get', 'web/monitorchart/tailingno', {tailingno:tailingno}).then((res)=>{
loading.close();
var body = res.body || [];
if(body.chart && body.chart.picture){
qf.UI.popupLayer({
//title:'<div>标题</div>',
html:'<div class="monitor-points" style="width:13rem;height:8rem;margin-top:20px;"><div class="img-box"><img id="drawingImg"></div><div class="cview_ctn wkk-ctn"><ul></ul></div></div>',
onload: function(el){
var box = el.firstElementChild;
var monitorPoint = new qf.UI.pointCharts({
chartsBox:box,
width:box.offsetWidth,
height:box.offsetHeight,
});
monitorPoint.setBackground(body.chart.picture);
monitorPoint.createPoints(body.points, body.chart);
},
})
}else{
qf.UI.popupLayer({
title:'提示',
html:'暂无数据!',
confirmText:'确定',
})
};
});
},
setUnitInfo(item){
this.unitInfo['tailingname'] = item['tailingname'];
this.unitInfo['tailingno'] = item['tailingno'];
this.unitInfo['address'] = item['address'];
this.unitInfo['ondutytel'] = item['ondutytel'];
this.unitInfo['securityofficer'] = item['securityofficer'];
this.unitInfo['securityofficertel'] = item['securityofficertel'];
this.operatingstatus = item['operatingstatus'];
this.safetytypeno = item['safetytypeno'];
// 请求数据字典
this.reqSelectDict()
},
reqSelectDict(){
var Dict = reqApi.system.pondManage.Dict, self = this;
if(typeof Dict.selectList.damstocktypeno === 'function'){
Dict.selectList.damstocktypeno.call(Dict).then(function(res){
self.operatDict = Tools.arrayJsonToJson(Dict.selectList.operatingstatus, 'name', 'value');
self.safetyDict = Tools.arrayJsonToJson(Dict.selectList.safetytypeno, 'name', 'value');
self.unitInfo['operatingstatus'] = self.operatDict[self.operatingstatus];
self.unitInfo['safetytypeno'] = self.safetyDict[self.safetytypeno];
})
}else{
self.operatDict = Tools.arrayJsonToJson(Dict.selectList.operatingstatus, 'name', 'value');
self.safetyDict = Tools.arrayJsonToJson(Dict.selectList.safetytypeno, 'name', 'value');
self.unitInfo['operatingstatus'] = self.operatDict[self.operatingstatus];
self.unitInfo['safetytypeno'] = self.safetyDict[self.safetytypeno];
};
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.home_manage{
position:relative;height:100%;width:100%;flex:1;display:flex;justify-content:center;
//background:no-repeat bottom center url('~@/assets/images/layout/main_bg.png');background-size:100% 100%;
.m-view{
position:relative;width:100%;
}
.b_0{
border:1px solid #143D96;
position:absolute;top:.20rem;left:.10rem;width:max-content;padding:.10rem;user-select:none;
background-color:rgba(0,16,52, .7);border-radius:.12rem;line-height:26px;
li{
span:first-child{color:#ccc;}
span{color:#fff;}
}
}
}
.monitor-points{
position:relative;top:0;left:0;height:100%;width:100%;user-select:none;font-family:serif;color:#444;
}
.monitor-points .img-box{position:absolute;top:0;left:0;height:100%;width:100%;z-index:10;}
.monitor-points .img-box img{display:block;border:0;max-height:100%;max-width:100%;}
.monitor-points .wkk-ctn{position:absolute;top:0;left:0;height:100%;width:100%;z-index:20;}
.monitor-points .wkk-ctn{position:absolute;top:0;left:0;height:100%;width:100%;}
.monitor-points .wkk-ctn li{position:absolute;}
.monitor-points .wkk-ctn li::marker{content:close-quote;}
.monitor-points .wkk-ctn li i{position:absolute;top:0;left:0;height:100%;width:100%;
background-repeat:no-repeat;background-position:center bottom;background-size:contain;
}
.monitor-points .wkk-ctn li.d_01 i{background-image:url('~@/assets/images/icon/d_01.png');}
.monitor-points .wkk-ctn li.d_02 i{background-image:url('~@/assets/images/icon/d_02.png');}
.monitor-points .wkk-ctn li.d_03 i{background-image:url('~@/assets/images/icon/d_03.png');}
.monitor-points .wkk-ctn li.d_04 i{background-image:url('~@/assets/images/icon/d_04.png');}
.monitor-points .wkk-ctn li.d_05 i{background-image:url('~@/assets/images/icon/d_05.png');}
.monitor-points .wkk-ctn li.d_06 i{background-image:url('~@/assets/images/icon/d_06.png');}
.monitor-points .wkk-ctn li.d_07 i{background-image:url('~@/assets/images/icon/d_07.png');}
.monitor-points .wkk-ctn li.d_08 i{background-image:url('~@/assets/images/icon/d_08.png');}
.monitor-points .wkk-ctn li>div{position:absolute;display:flex;align-items:center;justify-content:center;}
.monitor-points .wkk-ctn li>div .text{position:absolute;padding:0.0402rem;background-color:#fff;border-radius:0.0643rem;line-height:1.2;color:#1A688C;font-weight:bold;}
.monitor-points .wkk-ctn .text h4{text-align:center;color:#1284b3;font-weight:normal;}
.monitor-points .wkk-ctn .text dd{display:block;line-height:1;margin-top:3px;font-size:12px;}
.monitor-points .wkk-ctn .text dd:before{font-size:15px;margin-right:3px;}
.monitor-points .wkk-ctn .text .normal:before{font-size:13px;margin-right:1px;}
.monitor-points .wkk-ctn .text .red{background-color:red;color:#fff;}
.monitor-points .wkk-ctn .text .orange{background-color:orange;color:#fff;}
.monitor-points .wkk-ctn .text .yellow{background-color:#e8cb08;color:#fff;}
.monitor-points .wkk-ctn .text .blue{background-color:#0991FF;color:#fff;}
.monitor-points .wkk-ctn .text .relieve{cursor:pointer;}
.monitor-points .wkk-ctn .text .offline{color:#aaa;}
.monitor-points .wkk-ctn .text .online{color:#000;}
.monitor-points .wkk-ctn li>div .text:before{content:'';position:absolute;height:0;width:0;border-style:solid;border-width:0.0643rem;border-color:transparent;}
.monitor-points .wkk-ctn .up{top:0;left:0;height:0;width:100%;}
.monitor-points .wkk-ctn .up .text{bottom:0.0804rem;width:max-content;}
.monitor-points .wkk-ctn .up .text:before{bottom:-0.1287rem;left:50%;margin-left:-0.0643rem;border-color:#fff transparent transparent transparent;}
.monitor-points .wkk-ctn .down{bottom:0;left:0;height:0;width:100%;}
.monitor-points .wkk-ctn .down .text{top:0.0804rem;width:max-content;}
.monitor-points .wkk-ctn .down .text:before{top:-0.1287rem;left:50%;margin-left:-0.0643rem;border-color:transparent transparent #fff transparent;}
.monitor-points .wkk-ctn .left{top:0;left:0;height:100%;width:0;}
.monitor-points .wkk-ctn .left .text{right:0.0804rem;width:max-content;}
.monitor-points .wkk-ctn .left .text:before{top:50%;right:-0.1287rem;margin-top:-0.0643rem;border-color:transparent transparent transparent #fff;}
.monitor-points .wkk-ctn .right{top:0;right:0;height:100%;width:0;}
.monitor-points .wkk-ctn .right .text{left:0.0804rem;width:max-content;}
.monitor-points .wkk-ctn .right .text:before{top:50%;left:-0.1287rem;margin-top:-0.0643rem;border-color:transparent #fff transparent transparent;}
</style>
<style lang="scss">
.home_manage{
a.amap-logo{
display:flex !important;justify-content:center;align-items:center;
height:.35rem;width:100%;
&:before{
content:'';display:block;
position:absolute;top:0;left:8px;height:100%;width:1.58rem;
background:no-repeat top left url('~@/assets/images/logo_ks.png');background-size:100% auto;
}
&:after{
color:#5C8FF5;display:inline-block;font-weight:bold;
//background-image:-webkit-linear-gradient(top, #8fe9ff, #3d8aff);
background-image:-webkit-linear-gradient(top,#8affe1,#4193ff);
-webkit-background-clip:text;-webkit-text-fill-color:transparent;
content:'© ⋅ 技术支持:威海晶合数字矿山技术有限公司';
}
img{display:none !important;}
}
.amap-copyright{display:none !important;}
}
</style>
<template>
<div class="app-container">
<div class="head-container">
<Search />
<crudOperation>
<el-button
slot="left"
class="filter-item"
type="danger"
icon="el-icon-delete"
size="mini"
:loading="crud.delAllLoading"
@click="confirmDelAll()"
>
清空
</el-button>
</crudOperation>
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="请求方法">
<span>{{ props.row.method }}</span>
</el-form-item>
<el-form-item label="请求参数">
<span>{{ props.row.params }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column prop="username" label="用户名" />
<el-table-column prop="requestIp" label="IP" />
<el-table-column :show-overflow-tooltip="true" prop="address" label="IP来源" />
<el-table-column prop="description" label="描述" />
<el-table-column prop="browser" label="浏览器" />
<el-table-column prop="time" label="请求耗时" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.time <= 300">{{ scope.row.time }}ms</el-tag>
<el-tag v-else-if="scope.row.time <= 1000" type="warning">{{ scope.row.time }}ms</el-tag>
<el-tag v-else type="danger">{{ scope.row.time }}ms</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建日期" width="180px" />
</el-table>
<!--分页组件-->
<pagination />
</div>
</template>
<script>
import Search from './search'
import { delAllInfo } from '@/api/monitor/log'
import CRUD, { presenter } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
export default {
name: 'Log',
components: { Search, crudOperation, pagination },
cruds() {
return CRUD({ title: '日志', url: 'api/logs' })
},
mixins: [presenter()],
created() {
this.crud.optShow = {
add: false,
edit: false,
del: false,
download: true
}
},
methods: {
confirmDelAll() {
this.$confirm(`确认清空所有操作日志吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.crud.delAllLoading = true
delAllInfo().then(res => {
this.crud.delAllLoading = false
this.crud.dleChangePage(1)
this.crud.delSuccessNotify()
this.crud.toQuery()
}).catch(err => {
this.crud.delAllLoading = false
console.log(err.response.data.message)
})
}).catch(() => {
})
}
}
}
</script>
<style>
.demo-table-expand {
font-size: 0;
}
.demo-table-expand label {
width: 70px;
color: #99a9bf;
}
.demo-table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
width: 100%;
}
.demo-table-expand .el-form-item__content {
font-size: 12px;
}
</style>
<template>
<div v-if="crud.props.searchToggle">
<el-input
v-model="query.blurry"
clearable
size="small"
placeholder="请输入你要搜索的内容"
style="width: 200px;"
class="filter-item"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
</template>
<script>
import { header } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import DateRangePicker from '@/components/DateRangePicker'
export default {
components: { rrOperation, DateRangePicker },
mixins: [header()]
}
</script>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
reqApi.common.getRequst.call(this);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
reqApi.common.getRequst.call(this);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
reqApi.common.getRequst.call(this);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
var searchItem = reqApi.common.getSearchParam(this.form);
reqApi.common.getRequst.call(this, searchItem);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
var searchItem = reqApi.common.getSearchParam(this.form);
reqApi.common.getRequst.call(this, searchItem);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="common-page qyzz page-t1">
<el-row>
<el-button type="primary" @click="bakDatabase">备份数据库</el-button>
</el-row>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
export default {
name: 'Dashboard',
components: {
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
},
methods: {
bakDatabase() {
this.$confirm('数据库备份时间较长,您确定要继续吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then((e) => {
var loadingText = '数据备份中,请等待';
var loading = this.$loading({
lock: true,
text: loadingText,
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
var i = 0;
var timerA = new qf.Async.intervalLoop(1500, function(){
i %= 6;
var spots = new Array(i+2).join('.');
loading.text = loadingText + spots;
i++
});
this.pageApi.backupDatabase({}).then((res)=>{
timerA.clear();
loading.close();
if(res.code === 200){
this.$notify({
title: '备份成功!',
type: 'success',
duration: 2500
});
};
});
})
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
</style>
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.name" clearable size="small" placeholder="输入部门名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<date-range-picker v-model="query.createTime" class="date-item" />
<el-select v-model="query.enabled" clearable size="small" placeholder="状态" class="filter-item" style="width: 90px" @change="crud.toQuery">
<el-option v-for="item in enabledTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" />
</el-select>
<rrOperation />
</div>
<crudOperation :permission="permission" />
</div>
<!--表单组件-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="500px">
<el-form ref="form" inline :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="部门名称" prop="name">
<el-input v-model="form.name" style="width: 370px;" />
</el-form-item>
<el-form-item label="部门排序" prop="deptSort">
<el-input-number
v-model.number="form.deptSort"
:min="0"
:max="999"
controls-position="right"
style="width: 370px;"
/>
</el-form-item>
<el-form-item label="顶级部门">
<el-radio-group v-model="form.isTop" style="width: 140px">
<el-radio label="1"></el-radio>
<el-radio label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="状态" prop="enabled">
<el-radio v-for="item in dict.dept_status" :key="item.id" v-model="form.enabled" :label="item.value">{{ item.label }}</el-radio>
</el-form-item>
<el-form-item v-if="form.isTop === '0'" style="margin-bottom: 0;" label="上级部门" prop="pid">
<treeselect
v-model="form.pid"
:load-options="loadDepts"
:options="depts"
style="width: 370px;"
placeholder="选择上级类目"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
</div>
</el-dialog>
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
lazy
:load="getDeptDatas"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
:data="crud.data"
row-key="id"
@select="crud.selectChange"
@select-all="crud.selectAllChange"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column label="名称" prop="name" />
<el-table-column label="排序" prop="deptSort" />
<el-table-column label="状态" align="center" prop="enabled">
<template slot-scope="scope">
<el-switch
v-model="scope.row.enabled"
:disabled="scope.row.id === 1"
active-color="#409EFF"
inactive-color="#F56C6C"
@change="changeEnabled(scope.row, scope.row.enabled,)"
/>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建日期" />
<el-table-column v-if="checkPer(['admin','dept:edit','dept:del'])" label="操作" width="130px" align="center" fixed="right">
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
:disabled-dle="scope.row.id === 1"
msg="确定删除吗,如果存在下级节点则一并删除,此操作不能撤销!"
/>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import crudDept from '@/api/system/dept'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import DateRangePicker from '@/components/DateRangePicker'
const defaultForm = { id: null, name: null, isTop: '1', subCount: 0, pid: null, deptSort: 999, enabled: 'true' }
export default {
name: 'Dept',
components: { Treeselect, crudOperation, rrOperation, udOperation, DateRangePicker },
cruds() {
return CRUD({ title: '部门', url: 'api/dept', crudMethod: { ...crudDept }})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
// 设置数据字典
dicts: ['dept_status'],
data() {
return {
depts: [],
rules: {
name: [
{ required: true, message: '请输入名称', trigger: 'blur' }
],
deptSort: [
{ required: true, message: '请输入序号', trigger: 'blur', type: 'number' }
]
},
permission: {
add: ['admin', 'dept:add'],
edit: ['admin', 'dept:edit'],
del: ['admin', 'dept:del']
},
enabledTypeOptions: [
{ key: 'true', display_name: '正常' },
{ key: 'false', display_name: '禁用' }
]
}
},
methods: {
getDeptDatas(tree, treeNode, resolve) {
const params = { pid: tree.id }
setTimeout(() => {
crudDept.getDepts(params).then(res => {
resolve(res.content)
})
}, 100)
},
// 新增与编辑前做的操作
[CRUD.HOOK.afterToCU](crud, form) {
if (form.pid !== null) {
form.isTop = '0'
} else if (form.id !== null) {
form.isTop = '1'
}
form.enabled = `${form.enabled}`
if (form.id != null) {
this.getSupDepts(form.id)
} else {
this.getDepts()
}
},
getSupDepts(id) {
crudDept.getDeptSuperior(id).then(res => {
const date = res.content
this.buildDepts(date)
this.depts = date
})
},
buildDepts(depts) {
depts.forEach(data => {
if (data.children) {
this.buildDepts(data.children)
}
if (data.hasChildren && !data.children) {
data.children = null
}
})
},
getDepts() {
crudDept.getDepts({ enabled: true }).then(res => {
this.depts = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
})
},
// 获取弹窗内部门数据
loadDepts({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
crudDept.getDepts({ enabled: true, pid: parentNode.id }).then(res => {
parentNode.children = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
setTimeout(() => {
callback()
}, 100)
})
}
},
// 提交前的验证
[CRUD.HOOK.afterValidateCU]() {
if (this.form.pid !== null && this.form.pid === this.form.id) {
this.$message({
message: '上级部门不能为空',
type: 'warning'
})
return false
}
if (this.form.isTop === '1') {
this.form.pid = null
}
return true
},
// 改变状态
changeEnabled(data, val) {
this.$confirm('此操作将 "' + this.dict.label.dept_status[val] + '" ' + data.name + '部门, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
crudDept.edit(data).then(res => {
this.crud.notify(this.dict.label.dept_status[val] + '成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(err => {
data.enabled = !data.enabled
console.log(err.response.data.message)
})
}).catch(() => {
data.enabled = !data.enabled
})
},
checkboxT(row, rowIndex) {
return row.id !== 1
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<!--工具栏-->
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<template v-for="(item, key) in form.config.otherBtn">
<el-button size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</template>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.search = this.Dict.search;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
var searchItem = reqApi.common.getSearchParam(this.form);
reqApi.common.getRequst.call(this, searchItem);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<eHeader :dict="dict" :permission="permission" />
<crudOperation :permission="permission" />
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table-column type="selection" width="55" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="jobSort" label="排序">
<template slot-scope="scope">
{{ scope.row.jobSort }}
</template>
</el-table-column>
<el-table-column prop="status" label="状态" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.enabled"
active-color="#409EFF"
inactive-color="#F56C6C"
@change="changeEnabled(scope.row, scope.row.enabled)"
/>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建日期" />
<!-- 编辑与删除 -->
<el-table-column
v-if="checkPer(['admin','job:edit','job:del'])"
label="操作"
width="130px"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
/>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
<!--表单渲染-->
<eForm :job-status="dict.job_status" />
</div>
</template>
<script>
import crudJob from '@/api/system/job'
import eHeader from './module/header'
import eForm from './module/form'
import CRUD, { presenter } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import udOperation from '@crud/UD.operation'
export default {
name: 'Job',
components: { eHeader, eForm, crudOperation, pagination, udOperation },
cruds() {
return CRUD({
title: '岗位',
url: 'api/job',
sort: ['jobSort,asc', 'id,desc'],
crudMethod: { ...crudJob }
})
},
mixins: [presenter()],
// 数据字典
dicts: ['job_status'],
data() {
return {
permission: {
add: ['admin', 'job:add'],
edit: ['admin', 'job:edit'],
del: ['admin', 'job:del']
}
}
},
methods: {
// 改变状态
changeEnabled(data, val) {
this.$confirm('此操作将 "' + this.dict.label.job_status[val] + '" ' + data.name + '岗位, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// eslint-disable-next-line no-undef
crudJob.edit(data).then(() => {
// eslint-disable-next-line no-undef
this.crud.notify(this.dict.label.job_status[val] + '成功', 'success')
}).catch(err => {
data.enabled = !data.enabled
console.log(err.data.message)
})
}).catch(() => {
data.enabled = !data.enabled
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
</style>
<template>
<el-dialog
append-to-body
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible="crud.status.cu > 0"
:title="crud.status.title"
width="500px"
>
<el-form
ref="form"
:model="form"
:rules="rules"
size="small"
label-width="80px"
>
<el-form-item
label="名称"
prop="name"
>
<el-input
v-model="form.name"
style="width: 370px;"
/>
</el-form-item>
<el-form-item
label="排序"
prop="jobSort"
>
<el-input-number
v-model.number="form.jobSort"
:min="0"
:max="999"
controls-position="right"
style="width: 370px;"
/>
</el-form-item>
<el-form-item
v-if="form.pid !== 0"
label="状态"
prop="enabled"
>
<el-radio
v-for="item in jobStatus"
:key="item.id"
v-model="form.enabled"
:label="item.value === 'true'"
>
{{ item.label }}
</el-radio>
</el-form-item>
</el-form>
<div
slot="footer"
class="dialog-footer"
>
<el-button
type="text"
@click="crud.cancelCU"
>
取消
</el-button>
<el-button
:loading="crud.status.cu === 2"
type="primary"
@click="crud.submitCU"
>
确认
</el-button>
</div>
</el-dialog>
</template>
<script>
import { form } from '@crud/crud'
const defaultForm = {
id: null,
name: '',
jobSort: 999,
enabled: true
}
export default {
mixins: [form(defaultForm)],
props: {
jobStatus: {
type: Array,
required: true
}
},
data() {
return {
rules: {
name: [
{ required: true, message: '请输入名称', trigger: 'blur' }
],
jobSort: [
{ required: true, message: '请输入序号', trigger: 'blur', type: 'number' }
]
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
</style>
<template>
<div
v-if="crud.props.searchToggle"
>
<el-input v-model="query.name" clearable size="small" placeholder="输入岗位名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<date-range-picker v-model="query.createTime" class="date-item" />
<el-select v-model="query.enabled" clearable size="small" placeholder="状态" class="filter-item" style="width: 90px" @change="crud.toQuery">
<el-option v-for="item in dict.dict.job_status" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<rrOperation />
</div>
</template>
<script>
import { header } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import DateRangePicker from '@/components/DateRangePicker'
export default {
components: { rrOperation, DateRangePicker },
mixins: [header()],
props: {
dict: {
type: Object,
required: true
},
permission: {
type: Object,
required: true
}
}
}
</script>
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.blurry" clearable size="small" placeholder="模糊搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
<crudOperation :permission="permission" />
</div>
<!--表单渲染-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="580px">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="菜单类型" prop="type">
<el-radio-group v-model="form.type" size="mini" style="width: 178px">
<el-radio-button label="0">目录</el-radio-button>
<el-radio-button label="1">菜单</el-radio-button>
<el-radio-button label="2">按钮</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item v-show="form.type.toString() !== '2'" label="菜单图标" prop="icon">
<el-popover
placement="bottom-start"
width="450"
trigger="click"
@show="$refs['iconSelect'].reset()"
>
<IconSelect ref="iconSelect" @selected="selected" />
<el-input slot="reference" v-model="form.icon" style="width: 450px;" placeholder="点击选择图标" readonly>
<svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" style="height: 32px;width: 16px;" />
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
</el-input>
</el-popover>
</el-form-item>
<el-form-item v-show="form.type.toString() !== '2'" label="外链菜单" prop="iframe">
<el-radio-group v-model="form.iframe" size="mini">
<el-radio-button label="true"></el-radio-button>
<el-radio-button label="false"></el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item v-show="form.type.toString() === '1'" label="菜单缓存" prop="cache">
<el-radio-group v-model="form.cache" size="mini">
<el-radio-button label="true"></el-radio-button>
<el-radio-button label="false"></el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item v-show="form.type.toString() !== '2'" label="菜单可见" prop="hidden">
<el-radio-group v-model="form.hidden" size="mini">
<el-radio-button label="false"></el-radio-button>
<el-radio-button label="true"></el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.type.toString() !== '2'" label="菜单标题" prop="title">
<el-input v-model="form.title" :style=" form.type.toString() === '0' ? 'width: 450px' : 'width: 178px'" placeholder="菜单标题" />
</el-form-item>
<el-form-item v-if="form.type.toString() === '2'" label="按钮名称" prop="title">
<el-input v-model="form.title" placeholder="按钮名称" style="width: 178px;" />
</el-form-item>
<el-form-item v-show="form.type.toString() !== '0'" label="权限标识" prop="permission">
<el-input v-model="form.permission" :disabled="form.iframe.toString() === 'true'" placeholder="权限标识" style="width: 178px;" />
</el-form-item>
<el-form-item v-if="form.type.toString() !== '2'" label="路由地址" prop="path">
<el-input v-model="form.path" placeholder="路由地址" style="width: 178px;" />
</el-form-item>
<el-form-item label="菜单排序" prop="menuSort">
<el-input-number v-model.number="form.menuSort" :min="0" :max="999" controls-position="right" style="width: 178px;" />
</el-form-item>
<el-form-item v-show="form.iframe.toString() !== 'true' && form.type.toString() === '1'" label="组件名称" prop="componentName">
<el-input v-model="form.componentName" style="width: 178px;" placeholder="匹配组件内Name字段" />
</el-form-item>
<el-form-item v-show="form.iframe.toString() !== 'true' && form.type.toString() === '1'" label="组件路径" prop="component">
<el-input v-model="form.component" style="width: 178px;" placeholder="组件路径" />
</el-form-item>
<el-form-item label="上级类目" prop="pid">
<treeselect
v-model="form.pid"
:options="menus"
:load-options="loadMenus"
style="width: 450px;"
placeholder="选择上级类目"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
</div>
</el-dialog>
<!--表格渲染-->
<el-table
ref="table"
v-loading="crud.loading"
lazy
:load="getMenus"
:data="crud.data"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
row-key="id"
@select="crud.selectChange"
@select-all="crud.selectAllChange"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" label="菜单标题" prop="title" />
<el-table-column prop="icon" label="图标" align="center" width="60px">
<template slot-scope="scope">
<svg-icon :icon-class="scope.row.icon ? scope.row.icon : ''" />
</template>
</el-table-column>
<el-table-column prop="menuSort" align="center" label="排序" width="60px" >
<template slot-scope="scope">
{{ scope.row.menuSort }}
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="permission" label="权限标识" width="100px"/>
<el-table-column :show-overflow-tooltip="true" prop="component" label="组件路径" />
<el-table-column prop="iframe" label="外链" width="60px">
<template slot-scope="scope">
<span v-if="scope.row.iframe"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="cache" label="缓存" width="60px">
<template slot-scope="scope">
<span v-if="scope.row.cache"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="hidden" label="可见" width="60px">
<template slot-scope="scope">
<span v-if="scope.row.hidden"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建日期" width="135px" />
<el-table-column v-if="checkPer(['admin','menu:edit','menu:del'])" label="操作" width="130px" align="center" fixed="right">
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
msg="确定删除吗,如果存在下级节点则一并删除,此操作不能撤销!"
/>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import crudMenu from '@/api/system/menu'
import IconSelect from '@/components/IconSelect'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import DateRangePicker from '@/components/DateRangePicker'
// crud交由presenter持有
const defaultForm = { id: null, title: null, menuSort: 999, path: null, component: null, componentName: null, iframe: false, roles: [], pid: 0, icon: null, cache: false, hidden: false, type: 0, permission: null }
export default {
name: 'Menu',
components: { Treeselect, IconSelect, crudOperation, rrOperation, udOperation, DateRangePicker },
cruds() {
return CRUD({ title: '菜单', url: 'api/menus', crudMethod: { ...crudMenu }})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
menus: [],
permission: {
add: ['admin', 'menu:add'],
edit: ['admin', 'menu:edit'],
del: ['admin', 'menu:del']
},
rules: {
title: [
{ required: true, message: '请输入标题', trigger: 'blur' }
],
path: [
{ required: true, message: '请输入地址', trigger: 'blur' }
]
}
}
},
methods: {
// 新增与编辑前做的操作
[CRUD.HOOK.afterToCU](crud, form) {
this.menus = []
if (form.id != null) {
if (form.pid === null) {
form.pid = 0
}
this.getSupDepts(form.id)
} else {
this.menus.push({ id: 0, label: '顶级类目', children: null })
}
},
getMenus(tree, treeNode, resolve) {
const params = { pid: tree.id }
setTimeout(() => {
crudMenu.getMenus(params).then(res => {
resolve(res.content)
})
}, 100)
},
getSupDepts(id) {
crudMenu.getMenuSuperior(id).then(res => {
const children = res.map(function(obj) {
if (!obj.leaf && !obj.children) {
obj.children = null
}
return obj
})
this.menus = [{ id: 0, label: '顶级类目', children: children }]
})
},
loadMenus({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
crudMenu.getMenusTree(parentNode.id).then(res => {
parentNode.children = res.map(function(obj) {
if (!obj.leaf) {
obj.children = null
}
return obj
})
setTimeout(() => {
callback()
}, 100)
})
}
},
// 选中图标
selected(name) {
this.form.icon = name
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
</style>
<template>
<div class="common-page page-t1 module-config">
<div class="mc-head">
<div class="mcin-head" id="mcHead">
<span></span>
<!-- <el-input style="width:4rem" id="mainTitle"></el-input> -->
<input class="el-input--small el-input__inner" type="text" placeholder="请输入大屏标题">
<i class="el-icon-check"></i>
</div>
</div>
<div class="mc-view" id="mcView">
<div class="b2_a1">
<div v-for="(item, i) in area.b2_a1" class="view-item">
<div class="view-flx">
<div class="panel">
<div class="p-flx">
<ul>
<li v-for="item2 in item.children">
<span>{{item2.sumtitle}}</span>
<i class="el-icon-delete" :data-id="item2.id"></i>
</li>
</ul>
<div class="add el-icon-s-operation" :data-id="item.id">
<!-- <span class="">编辑</span> -->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="b2_a2">
<div class="b2a_2a">
<div v-for="(item, i) in area.b2a_2a" class="view-item">
<div class="view-flx">
<div class="panel">
<div class="p-flx">
<ul>
<li v-for="item2 in item.children">
<span>{{item2.sumtitle}}</span>
<i class="el-icon-delete" :data-id="item2.id"></i>
</li>
</ul>
<div class="add el-icon-s-operation" :data-id="item.id">
<!-- <span class="">编辑</span> -->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="b2a_2b">
<div v-for="(item, i) in area.b2a_2b" class="view-item">
<div class="view-flx">
<div class="panel">
<div class="p-flx">
<ul>
<li v-for="item2 in item.children">
<span>{{item2.sumtitle}}</span>
<i class="el-icon-delete" :data-id="item2.id"></i>
</li>
</ul>
<div class="add el-icon-s-operation" :data-id="item.id">
<!-- <span class="">编辑</span> -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="b2_a3">
<div v-for="(item, i) in area.b2_a3" class="view-item">
<div class="view-flx">
<div class="panel">
<div class="p-flx">
<ul>
<li v-for="item2 in item.children">
<span>{{item2.sumtitle}}</span>
<i class="el-icon-delete" :data-id="item2.id"></i>
</li>
</ul>
<div class="add el-icon-s-operation" :data-id="item.id">
<!-- <span class="">编辑</span> -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
export default {
name: 'Dashboard',
components: {
},
data() {
return {
loading: false,
area:{
b2_a1:[],
b2a_2b:[],
b2_a3:[],
},
}
},
mounted() {
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.$nextTick(() => {
this.loadData();
// 事件
var mcView = document.getElementById("mcView");
mcView.onclick = (e) => {
var tag = e.target || e.srcElement;
if(tag.className.match('add')){
var self = this, result = {};
result.viewId = tag.dataset.id;
qf.UI.popupLayer({
title:'设置监测项',width:'420px',
onload: function(el){
var selectList = [];
self.pageApi.getMonitorList({mdcode:result.viewId}).then((res) => {
if(res && res.code){
var body = res.body || {}, list = body.list || [], select = body.select;
selectList = [];
for(var item of list){
selectList.push({name:item.title, value:item.id})
};
Tools.checkbox({
vue:self,
el:el,
list:selectList,
select:select,
result:result,
change: function(val, item){
},
});
}else{
self.$notify({
title: res.msg,
type: 'error',
duration: 2500
})
};
}).catch(function(error) {
//this.table.loading = false;
});
},
confirm: function(){
var num = result.viewId === '11' ? 2 : 5;
var flag = num > 2 ? '' : '';
if(result.values.length > num){
self.$alert('<span style="color:red">'+flag+'模块最多不能超过'+num+'个监测项!</span>', '编辑失败', {
dangerouslyUseHTMLString: true,
showConfirmButton:true,
showClose:false,
});
}else{
self.addViewItems(result);
};
},
})
}else if(tag.className.match('el-icon-delete')){
this.$confirm('确认删除该条数据吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then((e) => {
this.reqRemoveItem({id:~~tag.dataset.id})
});
};
};
})
},
methods: {
// 创建区域列表
loadData(){
var self = this;
this.pageApi.getAreaModule({}).then((res)=>{
var body = res.body;
for(var key in body){
var list = body[key];
this.area[key] = list;
};
});
// 标题设置
this.pageApi.reqScreenTitle('get').then((res)=>{
var body = res.body || {};
var mcHead = this.$el.querySelector("#mcHead");
var inputEl = mcHead.firstElementChild.nextElementSibling;
var flag = mcHead.lastElementChild;
inputEl.value = body.title || '';
var showFilter = qf.Async.timeoutFilter(500);
var reqFilter = qf.Async.timeoutFilter(50);
inputEl.oninput = function(e){
reqFilter(()=>{
var value = e.target.value;
if(value.length > 15){
return self.$notify({
title: '标题长度不能超过15位!',
type: 'error',
duration: 2500
});
};
self.pageApi.reqScreenTitle('post', {title:value}).then((res)=>{
if(res.code === 200){
flag.classList.add('show');
showFilter(function(){
flag.classList.remove('show');
});
};
});
});
};
});
},
addViewItems(result){
var param = {mdcode:~~result.viewId, values:result.values}
this.pageApi.getSelectItem('post', param).then((res)=>{
if(res.code === 200){
this.$notify({
title: '添加成功!',
type: 'success',
duration: 2500
});
this.loadData()
};
});
},
reqRemoveItem(param){
this.pageApi.getSelectItem('delete', param).then((res)=>{
if(res.code === 200){
this.$notify({
title: '删除成功!',
type: 'success',
duration: 2500
});
this.loadData()
};
});
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.module-config{
padding:.1rem .30rem;display:flex;flex-direction:column;
.mc-head{
background-color:#fff;margin-bottom:.10rem;padding:.05rem .20rem;display:flex;justify-content:center;
.mcin-head{
display:flex;align-items:center;position:relative;padding-right:30px
}
span{font-size:16px;margin-right:.10rem;color:#aaa;line-height:35px;}
input{width:4rem;height:35px;}
i{
opacity:0;position:absolute;right:0;font-size:20px;color:#67C23A;
transition:opacity .3s ease;
&.show{opacity:1;}
}
}
.mc-view{
flex:1;display:flex;position:relative;background-color:#fff;padding:.20rem;
.b2_a2{
width:8.84rem;margin:0 .08rem;
}
.b2_a1, .b2_a3{
flex:1;
>div{
//border:1px solid pink;
//background-color:pink;
flex:1;
}
}
.b2_a1, .b2_a2, .b2_a3{
display:flex;flex-direction:column;
>div{margin-bottom:.08rem;}
>div:last-child{margin-bottom:0;}
}
.b2_a2{
width:8.84rem;margin:0 .08rem;
>div:first-child{
flex:1;display:flex;
>div{
flex:1;
}
}
>div:last-child{
height:2.46rem;
display:flex;
//height:22.777vh;
>div{
flex:1;margin-right:.08rem;
&:last-child{
margin-right:0;
}
}
}
}
.view-item{
border:2px solid #004a8b;
position:relative;
//box-shadow:inset 0rem 0rem .15rem .04rem rgba(10,106,180,.8);
&:before, &:after, .view-flx:before, .view-flx:after{
content:"";position:absolute;height:.10rem;width:.10rem;z-index:1;
border-style:solid;border-color:#02f6ff;
}
&:before, &:after{top:-1px;}
&:before{
left:-1px;
border-width:.02rem 0 0 .02rem;
}
&:after{
right:-1px;
border-width:.02rem .02rem 0 0;
}
.view-flx{
position:absolute;top:0;left:0;height:100%;width:100%;display:flex;
&:before, &:after{bottom:-1px;}
&:before{
left:-1px;
border-width:0 0 .02rem .02rem;
}
&:after{
right:-1px;
border-width:0 .02rem .02rem 0;
}
}
.panel{
flex:1;position:relative;margin:.10rem;
display:flex;flex-direction:column;align-items:center;justify-content:center;
.p-flx{
width:100%;text-align:center;
}
ul{
flex:1;margin:0 .10rem;
li{
display:flex;justify-content:space-between;align-items:center;margin-bottom:.08rem;
background-color:#eee;padding:0 .10rem;
span{
display:flex;align-items:center;
&:before{
content:"";height:.08rem;width:.08rem;display:inline-block;
border-radius:.10rem;background-color:#0E82D7;margin-right:.05rem;
}
}
i{font-size:.22rem;cursor:pointer;}
}
}
.add{
font-size:.404rem;line-height:1;cursor:pointer;color:#0383BF;
span{font-size:.25rem;}
}
.hide{display:none;}
}
}
}
}
</style>
<template>
<div class="common-page qyzz page-t1">
<div class="option page-row">
<!--工具栏-->
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<template v-for="(item, key) in form.config.otherBtn">
<el-button v-if="item.fn==='toAdd'" size="mini" :type="item.type" :icon="item.icon" @click="toAdd">{{item.name}}</el-button>
</template>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:toDownload="toDownload"
:toEdit="toEdit"
:toDelete="toDelete"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:upload="upload"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.search = this.Dict.search;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this,selectList, function(key, value, next){
if(typeof value === 'function'){
value().then(function(res){
selectList[key] = res;
next();
})
}else{
next();
};
});
},
methods: {
// 点击搜索
toSearch() {
this.table.page = 1;
this.loadData()
},
clearLimit(){ // 清除限制
this.loadData()
},
loadData() {
var searchItem = reqApi.common.getSearchParam(this.form);
reqApi.common.getRequst.call(this, searchItem);
},
toAdd() {
reqApi.common.toAdd.call(this);
},
toEdit(item) {
reqApi.common.toEdit.call(this, item);
},
cancelForm(){
this.form.visible = false;
},
toDelete(item) {
reqApi.common.toDelete.call(this, item);
},
upload(e, key){
reqApi.common.upload.call(this, e, key);
},
toDownload(item) {
reqApi.common.toDownload.call(this, item);
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
reqRemoveItem(item){
reqApi.common.removeRequst.call(this, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.qyzz{
}
</style>
<template>
<div class="page-bgc1 monitor-point cm-layout flex-col">
<div class="title-w">
<h3>监测点配制</h3>
</div>
<div class="mnt-view flex-disf-rel a-2">
<div class="a2-1 flex-disf fix-rc">
<div class="a21 rel-flex fun-area" id="funArea">
<div class="points">
<ul>
<li v-for="(item, i) in pointDict" :class="item.type" draggable="true"></li>
<!-- <li class="d_02" draggable="true"></li>
<li class="d_03" draggable="true"></li> -->
</ul>
</div>
<div class="viewArea" style="width:10.50rem;height:8.81rem;">
<div class="figure">
<div class="img-box" id="pictureArea">
<img id="drawingImg">
</div>
<div class="upload-layer">
<label class="upload-area el-icon-picture" for="imgUpload">
<input type="file" style="display:none" id="imgUpload" @change="cropUpload">
</label>
</div>
<div id="pointsLayer" class="points-layer wkk-ctn">
<ul>
</ul>
</div>
<i class="delete el-icon-delete" @click="deleteBg"></i>
</div>
</div>
<div class="a2-2">
<el-form :model="form2" ref="form2" :inline="true" size="small" label-width="100%">
<el-form-item label="监测点名称">
<el-input v-model="focusPoint.name" style="width:2.5rem" @input="input"></el-input>
</el-form-item>
<el-form-item label="信息框方位" >
<el-button-group @click="setPosition">
<el-button :type="focusPoint.infoseat==='up' ? 'primary' : ''" icon="el-icon-top" @click="setPosition('up')"></el-button>
<el-button :type="focusPoint.infoseat==='right' ? 'primary' : ''" icon="el-icon-right" @click="setPosition('right')"></el-button>
<el-button :type="focusPoint.infoseat==='down' ? 'primary' : ''" icon="el-icon-bottom" @click="setPosition('down')"></el-button>
<el-button :type="focusPoint.infoseat==='left' ? 'primary' : ''" icon="el-icon-back" @click="setPosition('left')"></el-button>
</el-button-group>
</el-form-item>
<el-form-item label="设置监测项" >
<el-select v-model="form2.monitorValues" multiple placeholder="请选择" @change="selectChange($event, _self)" :disabled="!focusPoint.config">
<el-option
v-for="item in form2.monitorItems"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div class="btn-group">
<el-button type="danger" class="el-icon-delete" :disabled="!focusPoint.element" @click="deletePoint()">删除监测点</el-button>
<el-button :loading="false" type="primary" @click="submit()">保存信息</el-button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
export default {
name: 'Dashboard',
components: {
},
data() {
return {
pointDict:{
/* 'd_01':{
type:'d_01',
width:30,
height: 65,
}, */
},
focusPoint:{},
form2:{
monitorItems:[],
monitorValues:[],
},
}
},
mounted() {
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.$nextTick(() => {
var that = this;
this.loadData();
var EventKeys = {
mstart: 'mousedown',
mmove: 'mousemove',
mend: 'mouseup',
resize: 'resize',
dragStart: 'dragstart',
drag: 'drag',
dragEnd: 'dragend',
dragEnter: 'dragenter',
dragOver: 'dragover',
dragLeave: 'dragleave',
drop: 'drop',
};
// 视图区功能
var dragWidget = function(){
var self = this;
var funArea = that.$el.querySelector("#funArea");
this.iconBox = funArea.firstElementChild;
this.menusEl = this.iconBox.firstElementChild;
this.pointsLayer = funArea.querySelector("#pointsLayer");
this.pointsCtn = this.pointsLayer.firstElementChild;
this.pictureArea = funArea.querySelector("#pictureArea");;
// drag 事件临时缓存
var dragTarget = {};
var menuColumn = this.menuColumn = new function(){
var menuObj = this;
var mConfig = {
dragValidDist: 10, // 有效拖曳距离
eventAddMark:null, // 菜单栏的 m, e, 事件绑定状态
};
return function(menuBox){
var that = this;
menuBox.onclick = function(e){
var tag = e.target || e.srcElement;
};
// dragStart
this.eventHandler.addEvent(EventKeys.dragStart, menuBox, function(e){
var tag = e.target || e.srcElement;
dragTarget = {
start:{
offsetX: e.offsetX,
offsetY: e.offsetY,
},
target: tag,
};
// 激活目标区域事件
that.movementHandlers.dragTrigger(self.pointsLayer);
});
// 结束拖曳事件
this.eventHandler.addEvent(EventKeys.dragEnd, menuBox, function(e){
let tag = e.target || e.srcElement;
that.movementHandlers.dragRemove(self.pointsLayer); // 清除画布兼听事件
});
return menuObj;
}
};
// 事件控制
this.movementHandlers = function(self){
this.start = function(e) {
var tag = e.target || e.srcElement, mouseInfo = self.mouseInfo;
if(tag.nodeName === 'I' && e.button === 0){
self.switchActive(tag.parentNode);
mouseInfo.dragFlag = !0; // 修改事件状态
mouseInfo.start = {
pageX: e.pageX,
pageY: e.pageY,
}
this.eventTrigger(self.pointsLayer)
}else{
self.cancelActive();
};
};
this.move = function(e) {
var mouseInfo = self.mouseInfo;
if(mouseInfo.dragFlag){
mouseInfo.dragFlag = e.type;
var absX = e.pageX - mouseInfo.start.pageX;
var absY = e.pageY - mouseInfo.start.pageY;
mouseInfo.move = {
absX: absX,
absY: absY,
}
mouseInfo.target.style.transform = 'matrix(1, 0, 0, 1, '+absX+', '+absY+')';
};
};
this.end = function(e) {
var mouseInfo = self.mouseInfo;
if(mouseInfo.dragFlag === EventKeys.mmove){
var target = mouseInfo.target,
left = target.offsetLeft + mouseInfo.move.absX ,
top = target.offsetTop + mouseInfo.move.absY;
var x = qf.parseWpx(left);
var y = qf.parseWpx(top);
target.style.transform = 'matrix(1, 0, 0, 1, 0, 0)';
target.style.left = qf.parseRem(x)+ 'rem';
target.style.top = qf.parseRem(y) + 'rem';
var guid = target.dataset.id;
that.focusPoint = self.pointList[guid];
that.focusPoint.config.x = x;
that.focusPoint.config.y = y;
};
mouseInfo.dragFlag = null;
//mouseInfo.target = null;
this.eventRemove(self.pointsLayer)
};
this.eventTrigger = function(el){
self.eventHandler.addEvent(EventKeys.mmove, el);
self.eventHandler.addEvent(EventKeys.mend, el);
};
this.eventRemove = function(el){
self.eventHandler.removeEvent(EventKeys.mmove, el);
self.eventHandler.removeEvent(EventKeys.mend, el);
};
this.dragEnter = function(e){
var tag = e.target || e.srcElement;
};
this.dragOver = function(e){
e.preventDefault();
};
this.dragDrop = function(e){
var wpr = qf.envir.wpr;
var elLeft = e.offsetX / wpr - dragTarget.start.offsetX;
var elTop = e.offsetY / wpr - dragTarget.start.offsetY;
var target = dragTarget.target || e.srcElement;
var cionName = target.className;
var point = that.pointDict[cionName];
console.log('point ________________ ', point);
var param = {
x: elLeft,
y: elTop,
type:point.type,
height:point.height,
width:point.width,
angle:~~point.angle,
start: dragTarget.start,
//className:cionName,
//target:dragTarget.target,
};
self.createPoint(param, 'drop');
};
this.dragTrigger = function(el){
self.eventHandler.addEvent(EventKeys.dragEnter, el);
self.eventHandler.addEvent(EventKeys.dragOver, el);
//self.eventHandler.addEvent(EventKeys.dragLeave, el);
self.eventHandler.addEvent(EventKeys.drop, el);
};
this.dragRemove = function(el){
self.eventHandler.removeEvent(EventKeys.dragEnter, el);
self.eventHandler.removeEvent(EventKeys.dragOver, el);
//self.eventHandler.removeEvent(EventKeys.dragLeave, el);
self.eventHandler.removeEvent(EventKeys.drop, el);
};
this.mouse = {};
return this;
}.call({}, this);
// 增删事件
this.eventHandler = function(that){
this.addEvent = function(type, el, call){
call = call || that;
el.addEventListener(type, call, false);
};
this.removeEvent = function(type, el, call){
call = call || that;
el.removeEventListener(type, call, false);
};
return this;
}.call({}, this);
this.initialize();
this.mouseInfo = {};
this.pointList = {};
return self;
};
dragWidget.prototype = {
handleEvent : function(e){;
var movement = this.movementHandlers;
switch(e.type){
case EventKeys.mstart : movement.start(e); break;
case EventKeys.mmove : movement.move(e); break;
case EventKeys.mend : movement.end(e); break;
case EventKeys.resize: movement.resize(); break;
case EventKeys.dragEnter: movement.dragEnter(e); break;
case EventKeys.dragOver: movement.dragOver(e); break;
case EventKeys.dragLeave: movement.dragLeave(e); break;
case EventKeys.drop: movement.dragDrop(e); break;
}
},
initialize: function(requisite){
/* if(!requisite.drawArea || requisite.drawArea.constructor.name !== "HTMLDivElement"){
return new Error('drawArea not a div Element');
}*/
this.eventHandler.addEvent(EventKeys.mstart, this.pointsLayer);
var param = { // 需要创建图形的参数
width: 100,
height: 75,
top: 280,
left: 150,
};
// 菜单栏激活
let menuObj = this.menuColumn.call(this, this.menusEl);
},
setBackground: function(picture){
var upload = this.pictureArea.nextElementSibling;
var bgBtn = this.pointsLayer.nextElementSibling;
if(picture){
this.pictureArea.firstElementChild.src = picture;
this.pictureArea.classList.add('show');
bgBtn.classList.add('show');
this.pointsLayer.classList.add('show');
upload.classList.remove('show');
}else{
this.pictureArea.classList.remove('show');
bgBtn.classList.remove('show');
this.pointsLayer.classList.remove('show');
upload.classList.add('show');
};
},
/*
param[object] 元素的尺寸
*/
createPoint: function(param, event){
var config = param;
var title = param.name || '';
var direction = param.infoseat || 'up';
var point = document.createElement("li");
var guid = param.guid || qf.getGuid();
point.className = param.type;
point.dataset.id = guid;
point.style.diesplay = 'none';
point.style.top = qf.parseRem(param.y) + 'rem';
point.style.left = qf.parseRem(param.x) + 'rem';
point.style.width = qf.parseRem(config.width) + 'rem';
point.style.height = qf.parseRem(config.height) + 'rem';
// point.style.fontSize = qf.parseRem(fontSize || (12 * this.wRatio)) + 'rem';
point.innerHTML = '<i style="transform:rotate('+(~~config.angle)+'deg)"></i><div class="'+direction+'"><div class="text"><h4>'+title+'</h4><dl></dl></div></div>';
this.pointsCtn.appendChild(point);
config.guid = guid;
// 绑定对象属性
var pointUnit = {
config:config,
element:point,
};
this.setBindAttr(pointUnit, point.lastElementChild);
// 设置监测值
pointUnit.items = config.items || [];
// 记录信息
this.pointList[guid] = pointUnit;
if(event === 'drop'){
this.switchActive(point);
};
},
createPoints: function(points){
for(var point of points){
this.createPoint(point);
};
},
switchActive: function(target){
var mouseInfo = this.mouseInfo;
mouseInfo.target && mouseInfo.target.classList.remove('active');
target.classList.add('active');
mouseInfo.target = target;
var guid = target.dataset.id;
that.focusPoint = this.pointList[guid];
that.form2.monitorValues = that.focusPoint.values || [];
},
cancelActive: function(){
var mouseInfo = this.mouseInfo;
mouseInfo.target && mouseInfo.target.classList.remove('active');
that.focusPoint = {};
that.form2.monitorValues = [];
},
setBindAttr: function(pointUnit, infoEl){
var titleEl = infoEl.firstElementChild.firstElementChild;
var items = infoEl.firstElementChild.lastElementChild;
Object.defineProperty(pointUnit, 'infoseat', { // bind
set:function(value){
infoEl.className = value;
},
get:function(){
return infoEl.className
},
});
Object.defineProperty(pointUnit, 'name', { // bind
set:function(value){
titleEl.innerText = value;
},
get:function(){
return titleEl.innerText
},
});
Object.defineProperty(pointUnit, 'items', { // bind
set:function(list){
var dds = '', values = [];
for(var item of list){
var id = item.id || item.value;
dds += '<dd data-id="'+id+'">'+item.name+'</dd>';
values.push(id);
};
items.innerHTML = dds;
pointUnit.values = values;
},
});
},
getPointDataList: function(){
var points = this.pointList, list = [];
for(var key in points){
var point = points[key];
list.push({
id: point.config.id || '',
type: point.config.type,
guid: point.element.dataset.id,
name: point.name,
x: point.config.x,
y: point.config.y,
height: point.config.height,
width: point.config.width,
angle: point.config.angle,
infoseat: point.infoseat,
items:point.values,
});
};
return list;
},
removePoint: function(){
var mouseInfo = this.mouseInfo;
var target = mouseInfo.target;
var guid = target.dataset.id;
var point = this.pointList[guid];
this.pointsCtn.removeChild(target);
delete mouseInfo.target;
delete this.pointList[guid];
return point;
},
};
this.dragWidget = new dragWidget();
})
},
methods: {
loadData() {
this.pageApi.getMonitorPoints({}).then((res)=>{
var body = res.body, chart = body.chart || {};
this.form2.monitorItems = body.devices;
this.dragWidget.setBackground(chart.picture);
this.dragWidget.createPoints(body.points);
this.chart = chart;
var pointDict = {};
for(var item of body.icons){
pointDict[item.type] = item;
};
this.pointDict = pointDict;
});
},
cropUpload(e){
var tag = e.target || e.srcElement, self = this;
Tools.fileElTobase64(tag).then(function(res){
var base64 = res.base64;
if(base64){
var imgBox = tag.parentNode.parentNode.previousElementSibling;
imgBox.style.display = 'block';
var height = imgBox.offsetHeight;
var width = imgBox.offsetWidth;
//var pictureEl = self.dragWidget.iconBox.nextElementSibling
//var height1 = qf.parsePixel(parseFloat(pictureEl.style.height));
//var width1 = qf.parsePixel(parseFloat(pictureEl.style.width));
var param = {height:height, width:width, picture:base64};
self.pageApi.postBackground(param).then((res)=>{
var body = res.body;
if(res.code === 200){
self.$notify({
title: '图片上传成功!',
type: 'success',
duration: 2500
});
// 显示
self.dragWidget.setBackground(base64);
};
});
};
tag.value = '';
}).catch(function(err){
var errText = '请上传后缀名为“jpg”或“png”格式的图片';
self.$notify({
title: errText,
type: 'error',
duration: 3500
});
});
},
submit(){
var points = this.dragWidget.getPointDataList();
if(points[0]){
var pictureArea = this.dragWidget.pictureArea;
var param = {
points:points,
/* chart:{
height:qf.parsePixel(parseFloat(pictureEl.style.height)),
width:qf.parsePixel(parseFloat(pictureEl.style.width)),
}, */
chart:{
id:this.chart.id,
height:qf.parseWpx(pictureArea.offsetHeight),
width:qf.parseWpx(pictureArea.offsetWidth),
},
};
this.pageApi.submitInfos(param).then((res)=>{
if(res.code === 200){
this.$notify({
title: '保存成功!',
type: 'success',
duration: 2500
});
};
});
};
},
input(){
this.$forceUpdate();
},
setPosition(val){
this.focusPoint.infoseat = val;
this.$forceUpdate();
},
selectChange(values){
var that = this;
return qf.vue.onEventInfos(function(val, items){
that.focusPoint.items = items;
});
},
// 删除背景图片
deleteBg(e){
this.$confirm('确定要删除尾矿库图片吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then((e) => {
var param = {height:0, width:0, picture:''};
this.pageApi.postBackground(param).then((res)=>{
if(res.code === 200){
this.dragWidget.setBackground('');
this.$notify({
title: '删除成功!',
type: 'success',
duration: 2500
});
};
});
})
},
deletePoint(){
this.$confirm('确定要删除该监测点吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then((e) => {
var point = this.dragWidget.removePoint();
if(point.config.id){
this.pageApi.deletePoints([point.config.guid]).then((res)=>{
if(res.code === 200){
this.focusPoint = {};
this.$notify({
title: '删除成功!',
type: 'success',
duration: 2500
});
};
});
}else{
this.focusPoint = {};
};
})
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.monitor-point{
.title-w{
line-height:.50rem;text-align:center;font-size:.20rem;background-color:#fff;margin-bottom:10px;
border-bottom:1px solid #aaa;
}
.a2-1{
.a21{
//width:10.50rem;height:8.81rem;
height: max-content;
}
}
.a2-2{
border:1px solid pink;
width:4rem;
.el-form{
.el-form-item{
margin-top:20px;text-align:center;
label{text-align:center;}
}
.el-button-group{
.el-button{
font-size:.30rem;
}
}
}
.btn-group{text-align:center;}
}
.fun-area{
.points{
position:absolute;top:0;left:-.60rem;height:auto;width:.70rem;
li{
height:.60rem;width:100%;cursor:move;
border-style:solid;border-color:#999;border-width:1px 0 0 1px;
background-repeat:no-repeat;background-position:center bottom;background-size:auto 95%;
}
li.d_01{background-image:url('~@/assets/images/icon/d_01.png');}
li.d_02{background-image:url('~@/assets/images/icon/d_02.png');}
li.d_03{background-image:url('~@/assets/images/icon/d_03.png');}
li.d_04{background-image:url('~@/assets/images/icon/d_04.png');}
li.d_05{background-image:url('~@/assets/images/icon/d_05.png');}
li.d_06{background-image:url('~@/assets/images/icon/d_06.png');}
li.d_07{background-image:url('~@/assets/images/icon/d_07.png');}
li.d_08{background-image:url('~@/assets/images/icon/d_08.png');}
li:last-child{
border-width:1px;
}
}
.viewArea{
max-height:800px;
.figure{
border:1px solid #999;width:100%;height:100%;position:relative;
.img-box{
position:absolute;top:0;left:0;height:100%;width:100%;z-index:10;display:none;
&.show{display:block;}
img{display:block;border:0;height:100%;width:100%;}
}
.upload-layer{
position:absolute;top:0;left:0;height:100%;width:100%;z-index:80;display:none;justify-content:center;align-items:center;
background-color:#fff;
.upload-area{
min-width:40%;padding:.50rem;border:1px dashed rgba(0, 0, 0, 0.1);background-color:rgba(0, 0, 0, 0.05);z-index:0;
text-align:center;cursor:pointer;color:#999;
&:before{display:block;font-size:.54rem;}
&:after{display:block;content:"上传尾矿库全景图片";margin-top:20px;line-height:22px;}
}
&.show{display:flex;}
}
.points-layer{
user-select:none;font-family:serif;color:#444;z-index:20;display:none;overflow:hidden;
&.show{display:block;}
}
.delete{
position:absolute;top:0;right:0;height:auto;width:auto;z-index:21;color:#fff;cursor:pointer;
display:none;
&.show{display:block;}
}
.wkk-ctn{position:absolute;top:0;left:0;height:100%;width:100%;}
.wkk-ctn li{position:absolute;}
.wkk-ctn li::marker{content:close-quote;}
.wkk-ctn li i{
position:absolute;top:0;left:0;height:100%;width:100%;
background-repeat:no-repeat;background-position:center bottom;
//background-size:100% auto;
background-size:contain;
}
.wkk-ctn li.active i{border:1px dashed red;}
.wkk-ctn li.d_01 i{background-image:url('~@/assets/images/icon/d_01.png');}
.wkk-ctn li.d_02 i{background-image:url('~@/assets/images/icon/d_02.png');}
.wkk-ctn li.d_03 i{background-image:url('~@/assets/images/icon/d_03.png');}
.wkk-ctn li.d_04 i{background-image:url('~@/assets/images/icon/d_04.png');}
.wkk-ctn li.d_05 i{background-image:url('~@/assets/images/icon/d_05.png');}
.wkk-ctn li.d_06 i{background-image:url('~@/assets/images/icon/d_06.png');}
.wkk-ctn li.d_07 i{background-image:url('~@/assets/images/icon/d_07.png');}
.wkk-ctn li.d_08 i{background-image:url('~@/assets/images/icon/d_08.png');}
.wkk-ctn li>div{position:absolute;display:flex;align-items:center;justify-content:center;}
.wkk-ctn li>div .text{position:absolute;padding:0.0402rem;background-color:#aac0da;border-radius:0.0643rem;line-height:1.2;}
.wkk-ctn li>div .text:before{content:'';position:absolute;height:0;width:0;border-style:solid;border-width:0.0643rem;border-color:transparent;}
.wkk-ctn li .text{text-align:center;}
.wkk-ctn .up{top:0;left:0;height:0;width:100%;}
.wkk-ctn .up .text{bottom:0.0804rem;width:max-content;}
.wkk-ctn .up .text:before{bottom:-0.1287rem;left:50%;margin-left:-0.0643rem;border-color:white transparent transparent transparent;}
.wkk-ctn .down{bottom:0;left:0;height:0;width:100%;}
.wkk-ctn .down .text{top:0.0804rem;width:max-content;}
.wkk-ctn .down .text:before{top:-0.1287rem;left:50%;margin-left:-0.0643rem;border-color:transparent transparent white transparent;}
.wkk-ctn .left{top:0;left:0;height:100%;width:0;}
.wkk-ctn .left .text{right:0.0804rem;width:max-content;}
.wkk-ctn .left .text:before{top:50%;right:-0.1287rem;margin-top:-0.0643rem;border-color:transparent transparent transparent white;}
.wkk-ctn .right{top:0;right:0;height:100%;width:0;}
.wkk-ctn .right .text{left:0.0804rem;width:max-content;}
.wkk-ctn .right .text:before{top:50%;left:-0.1287rem;margin-top:-0.0643rem;border-color:transparent white transparent transparent;}
}
}
}
}
</style>
<template>
<div class="common-page page-t1">
<div class="option page-row">
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<div>
<el-button v-for="(item, key) in form.config.otherBtn" v-if="getPermission(item)" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
<div>
<el-button v-for="(item, key) in form.config.rightBtn" size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</div>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
reqApi.common.getRequst.call(this);
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
getPermission:reqApi.common.getPermission,
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.page-t1{
}
</style>
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.blurry" size="small" clearable placeholder="输入名称或者描述搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
<crudOperation :permission="permission" />
</div>
<!-- 表单渲染 -->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="520px">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name" style="width: 380px;" />
</el-form-item>
<el-form-item label="角色级别" prop="level">
<el-input-number v-model.number="form.level" :min="1" controls-position="right" style="width: 145px;" />
</el-form-item>
<el-form-item label="数据范围" prop="dataScope">
<el-select v-model="form.dataScope" style="width: 140px" placeholder="请选择数据范围" @change="changeScope">
<el-option
v-for="item in dateScopes"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item v-if="form.dataScope === '自定义'" label="数据权限" prop="depts">
<treeselect
v-model="deptDatas"
:load-options="loadDepts"
:options="depts"
multiple
style="width: 380px"
placeholder="请选择"
/>
</el-form-item>
<el-form-item label="描述信息" prop="description">
<el-input v-model="form.description" style="width: 380px;" rows="5" type="textarea" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
</div>
</el-dialog>
<el-row :gutter="15">
<!--角色管理-->
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="17" style="margin-bottom: 10px">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span class="role-span">角色列表</span>
</div>
<el-table ref="table" v-loading="crud.loading" highlight-current-row style="width: 100%;" :data="crud.data" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange">
<el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="dataScope" label="数据权限" />
<el-table-column prop="level" label="角色级别" />
<el-table-column :show-overflow-tooltip="true" prop="description" label="描述" />
<el-table-column :show-overflow-tooltip="true" width="135px" prop="createTime" label="创建日期" />
<el-table-column v-if="checkPer(['admin','roles:edit','roles:del'])" label="操作" width="130px" align="center" fixed="right">
<template slot-scope="scope">
<udOperation
v-if="scope.row.level >= level"
:data="scope.row"
:permission="permission"
/>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</el-card>
</el-col>
<!-- 菜单授权 -->
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="7">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top">
<span class="role-span">菜单分配</span>
</el-tooltip>
<el-button
v-permission="['admin','roles:edit']"
:disabled="!showButton"
:loading="menuLoading"
icon="el-icon-check"
size="mini"
style="float: right; padding: 6px 9px"
type="primary"
@click="saveMenu"
>保存</el-button>
</div>
<el-tree
ref="menu"
lazy
:data="menus"
:default-checked-keys="menuIds"
:load="getMenuDatas"
:props="defaultProps"
check-strictly
accordion
show-checkbox
node-key="id"
@check="menuChange"
/>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import crudRoles from '@/api/system/role'
import { getDepts, getDeptSuperior } from '@/api/system/dept'
import { getMenusTree, getChild } from '@/api/system/menu'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import DateRangePicker from '@/components/DateRangePicker'
const defaultForm = { id: null, name: null, depts: [], description: null, dataScope: '全部', level: 3 }
export default {
name: 'Role',
components: { Treeselect, pagination, crudOperation, rrOperation, udOperation, DateRangePicker },
cruds() {
return CRUD({ title: '角色', url: 'api/roles', sort: 'level,asc', crudMethod: { ...crudRoles }})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
defaultProps: { children: 'children', label: 'label', isLeaf: 'leaf' },
dateScopes: ['全部', '本级', '自定义'], level: 3,
currentId: 0, menuLoading: false, showButton: false,
menus: [], menuIds: [], depts: [], deptDatas: [], // 多选时使用
permission: {
add: ['admin', 'roles:add'],
edit: ['admin', 'roles:edit'],
del: ['admin', 'roles:del']
},
rules: {
name: [
{ required: true, message: '请输入名称', trigger: 'blur' }
],
permission: [
{ required: true, message: '请输入权限', trigger: 'blur' }
]
}
}
},
created() {
crudRoles.getLevel().then(data => {
this.level = data.level
})
},
methods: {
getMenuDatas(node, resolve) {
setTimeout(() => {
getMenusTree(node.data.id ? node.data.id : 0).then(res => {
resolve(res)
})
}, 100)
},
[CRUD.HOOK.afterRefresh]() {
this.$refs.menu.setCheckedKeys([])
},
// 新增前初始化部门信息
[CRUD.HOOK.beforeToAdd](crud, form) {
this.deptDatas = []
form.menus = null
},
// 编辑前初始化自定义数据权限的部门信息
[CRUD.HOOK.beforeToEdit](crud, form) {
this.deptDatas = []
if (form.dataScope === '自定义') {
this.getSupDepts(form.depts)
}
const _this = this
form.depts.forEach(function(dept) {
_this.deptDatas.push(dept.id)
})
},
// 提交前做的操作
[CRUD.HOOK.afterValidateCU](crud) {
if (crud.form.dataScope === '自定义' && this.deptDatas.length === 0) {
this.$message({
message: '自定义数据权限不能为空',
type: 'warning'
})
return false
} else if (crud.form.dataScope === '自定义') {
const depts = []
this.deptDatas.forEach(function(data) {
const dept = { id: data }
depts.push(dept)
})
crud.form.depts = depts
} else {
crud.form.depts = []
}
return true
},
// 触发单选
handleCurrentChange(val) {
if (val) {
const _this = this
// 清空菜单的选中
this.$refs.menu.setCheckedKeys([])
// 保存当前的角色id
this.currentId = val.id
// 初始化默认选中的key
this.menuIds = []
val.menus.forEach(function(data) {
_this.menuIds.push(data.id)
})
this.showButton = true
}
},
menuChange(menu) {
// 获取该节点的所有子节点,id 包含自身
getChild(menu.id).then(childIds => {
// 判断是否在 menuIds 中,如果存在则删除,否则添加
if (this.menuIds.indexOf(menu.id) !== -1) {
for (let i = 0; i < childIds.length; i++) {
const index = this.menuIds.indexOf(childIds[i])
if (index !== -1) {
this.menuIds.splice(index, 1)
}
}
} else {
for (let i = 0; i < childIds.length; i++) {
const index = this.menuIds.indexOf(childIds[i])
if (index === -1) {
this.menuIds.push(childIds[i])
}
}
}
this.$refs.menu.setCheckedKeys(this.menuIds)
})
},
// 保存菜单
saveMenu() {
this.menuLoading = true
const role = { id: this.currentId, menus: [] }
// 得到已选中的 key 值
this.menuIds.forEach(function(id) {
const menu = { id: id }
role.menus.push(menu)
})
crudRoles.editMenu(role).then(() => {
this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.menuLoading = false
this.update()
}).catch(err => {
this.menuLoading = false
console.log(err.response.data.message)
})
},
// 改变数据
update() {
// 无刷新更新 表格数据
crudRoles.get(this.currentId).then(res => {
for (let i = 0; i < this.crud.data.length; i++) {
if (res.id === this.crud.data[i].id) {
this.crud.data[i] = res
break
}
}
})
},
// 获取部门数据
getDepts() {
getDepts({ enabled: true }).then(res => {
this.depts = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
})
},
getSupDepts(depts) {
const ids = []
depts.forEach(dept => {
ids.push(dept.id)
})
getDeptSuperior(ids).then(res => {
const date = res.content
this.buildDepts(date)
this.depts = date
})
},
buildDepts(depts) {
depts.forEach(data => {
if (data.children) {
this.buildDepts(data.children)
}
if (data.hasChildren && !data.children) {
data.children = null
}
})
},
// 获取弹窗内部门数据
loadDepts({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
getDepts({ enabled: true, pid: parentNode.id }).then(res => {
parentNode.children = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
setTimeout(() => {
callback()
}, 200)
})
}
},
// 如果数据权限为自定义则获取部门数据
changeScope() {
if (this.form.dataScope === '自定义') {
this.getDepts()
}
},
checkboxT(row) {
return row.level >= this.level
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.role-span {
font-weight: bold;color: #303133;
font-size: 15px;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__multi-value{
margin-bottom: 0;
}
::v-deep .vue-treeselect__multi-value-item{
border: 0;
padding: 0;
}
</style>
<template>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input v-model="query.jobName" clearable size="small" placeholder="输入任务名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery" />
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
<!-- <crudOperation :permission="permission">
<el-button
slot="right"
class="filter-item"
size="mini"
type="info"
icon="el-icon-tickets"
@click="doLog"
>日志</el-button>
</crudOperation> -->
<Log ref="log" />
</div>
<!--Form表单-->
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" append-to-body width="730px">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="100px">
<!-- <el-form-item label="任务名称" prop="jobName">
<el-input v-model="form.jobName" style="width: 220px;" />
</el-form-item>
<el-form-item label="任务描述" prop="description">
<el-input v-model="form.description" style="width: 220px;" />
</el-form-item>
<el-form-item label="Bean名称" prop="beanName">
<el-input v-model="form.beanName" style="width: 220px;" />
</el-form-item>
<el-form-item label="执行方法" prop="methodName">
<el-input v-model="form.methodName" style="width: 220px;" />
</el-form-item> -->
<!-- <el-form-item label="Cron表达式" prop="cronExpression">
<el-input v-model="form.cronExpression" style="width: 220px;" />
</el-form-item> -->
<el-form-item label="定时时间" prop="setTime">
<el-input v-model="form.setTime" style="width: 220px;" @blur="blurSetTime" placeholder="请输入0-23的整数"/>
</el-form-item>
<!-- <el-form-item label="子任务ID">
<el-input v-model="form.subTask" placeholder="多个用逗号隔开,按顺序执行" style="width: 220px;" />
</el-form-item>
<el-form-item label="任务负责人" prop="personInCharge">
<el-input v-model="form.personInCharge" style="width: 220px;" />
</el-form-item> -->
<!-- <el-form-item label="告警邮箱" prop="email">
<el-input v-model="form.email" placeholder="多个邮箱用逗号隔开" style="width: 220px;" />
</el-form-item> -->
<!-- <el-form-item label="失败后暂停">
<el-radio-group v-model="form.pauseAfterFailure" style="width: 220px">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>-->
<el-form-item label="任务状态">
<el-radio-group v-model="form.isPause" style="width: 220px">
<el-radio :label="false">启用</el-radio>
<el-radio :label="true">暂停</el-radio>
</el-radio-group>
</el-form-item>
<!--<el-form-item label="参数内容">
<el-input v-model="form.params" style="width: 556px;" rows="4" type="textarea" />
</el-form-item> -->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
</div>
</el-dialog>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 50%;" @selection-change="crud.selectionChangeHandler">
<!-- <el-table-column :selectable="checkboxT" type="selection" width="55" /> -->
<!-- <el-table-column :show-overflow-tooltip="true" prop="id" label="任务ID" /> -->
<el-table-column :show-overflow-tooltip="true" prop="jobName" label="任务名称" />
<!-- <el-table-column :show-overflow-tooltip="true" prop="beanName" label="Bean名称" />
<el-table-column :show-overflow-tooltip="true" prop="methodName" label="执行方法" />
<el-table-column :show-overflow-tooltip="true" prop="params" label="参数" /> -->
<el-table-column :show-overflow-tooltip="true" prop="cronExpression" label="定时时间(小时)" width="120" >
<template slot-scope='scope'>
{{cronToHour(scope.row.cronExpression)}}
</template>
</el-table-column>
<!-- <el-table-column :show-overflow-tooltip="true" prop="cronExpression" label="cron表达式" /> -->
<el-table-column :show-overflow-tooltip="true" prop="isPause" width="100px" label="状态">
<template slot-scope="scope">
<el-tag :type="scope.row.isPause ? 'warning' : 'success'">{{ scope.row.isPause ? '已暂停' : '运行中' }}</el-tag>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="description" label="描述" />
<!-- <el-table-column :show-overflow-tooltip="true" prop="createTime" width="136px" label="创建日期" /> -->
<el-table-column v-if="checkPer(['admin','timing:edit','timing:del'])" label="操作" align="center" fixed="right">
<template slot-scope="scope">
<el-button v-permission="['admin','timing:edit']" size="mini" style="margin-right: 3px;" type="text" @click="crud.toEdit(scope.row)">编辑</el-button>
<el-button v-permission="['admin','timing:edit']" style="margin-left: -2px" type="text" size="mini" @click="execute(scope.row.id)">执行</el-button>
<el-button v-permission="['admin','timing:edit']" style="margin-left: 3px" type="text" size="mini" @click="updateStatus(scope.row.id,scope.row.isPause ? '恢复' : '暂停')">
{{ scope.row.isPause ? '恢复' : '暂停' }}
</el-button>
<el-popover
:ref="scope.row.id"
v-permission="['admin','timing:del']"
placement="top"
width="200"
>
<p>确定停止并删除该任务吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="$refs[scope.row.id].doClose()">取消</el-button>
<el-button :loading="delLoading" type="primary" size="mini" @click="delMethod(scope.row.id)">确定</el-button>
</div>
<el-button slot="reference" type="text" size="mini">删除</el-button>
</el-popover>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</div>
</template>
<script>
import crudJob from '@/api/system/timing'
import Log from './log'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import DateRangePicker from '@/components/DateRangePicker'
import { replace } from 'core-js/library/es6/symbol'
const defaultForm = { id: null, jobName: null, subTask: null, beanName: null, methodName: null, params: null, cronExpression: null, pauseAfterFailure: true, isPause: false, personInCharge: null, email: null, description: null ,setTime:null}
export default {
name: 'Timing',
components: { Log, pagination, crudOperation, rrOperation, DateRangePicker },
cruds() {
return CRUD({ title: '定时任务', url: 'api/jobs', crudMethod: { ...crudJob }})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
delLoading: false,
permission: {
add: ['admin', 'timing:add'],
edit: ['admin', 'timing:edit'],
del: ['admin', 'timing:del']
},
rules: {
jobName: [
{ required: true, message: '请输入任务名称', trigger: 'blur' }
],
description: [
{ required: true, message: '请输入任务描述', trigger: 'blur' }
],
beanName: [
{ required: true, message: '请输入Bean名称', trigger: 'blur' }
],
methodName: [
{ required: true, message: '请输入方法名称', trigger: 'blur' }
],
setTime: [
{ required: true, message: '请输入0-23定时时间', trigger: 'blur' }
],
personInCharge: [
{ required: true, message: '请输入负责人名称', trigger: 'blur' }
]
}
}
},
methods: {
blurSetTime(e){
this.form.cronExpression=this.hourToCron(Number(e.target.value))
},
hourToCron(el){
return `0 0 0/${el} * * ?`
},
cronToHour(el){
let newNum=Number(el[6]+el[7])
return newNum
},
// 执行
execute(id) {
crudJob.execution(id).then(res => {
this.crud.notify('执行成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(err => {
console.log(err.response.data.message)
})
},
// 改变状态
updateStatus(id, status) {
if (status === '恢复') {
this.updateParams(id)
}
crudJob.updateIsPause(id).then(res => {
this.crud.toQuery()
this.crud.notify(status + '成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(err => {
console.log(err.response.data.message)
})
},
updateParams(id) {
console.log(id)
},
delMethod(id) {
this.delLoading = true
crudJob.del([id]).then(() => {
this.delLoading = false
this.$refs[id].doClose()
this.crud.dleChangePage(1)
this.crud.delSuccessNotify()
this.crud.toQuery()
}).catch(() => {
this.delLoading = false
this.$refs[id].doClose()
})
},
// 显示日志
doLog() {
this.$refs.log.dialog = true
this.$refs.log.doInit()
},
checkboxT(row, rowIndex) {
return row.id !== 1
}
}
}
</script>
<template>
<el-dialog :visible.sync="dialog" append-to-body title="执行日志" width="88%">
<!-- 搜索 -->
<div class="head-container">
<el-input v-model="query.jobName" clearable size="small" placeholder="输入任务名称搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery" />
<date-range-picker v-model="query.createTime" class="date-item" />
<el-select v-model="query.isSuccess" placeholder="日志状态" clearable size="small" class="filter-item" style="width: 110px" @change="toQuery">
<el-option v-for="item in enabledTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" />
</el-select>
<el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
<!-- 导出 -->
<div style="display: inline-block;">
<el-button
:loading="downloadLoading"
size="mini"
class="filter-item"
type="warning"
icon="el-icon-download"
@click="downloadMethod"
>导出</el-button>
</div>
</div>
<!--表格渲染-->
<el-table v-loading="loading" :data="data" style="width: 100%;margin-top: -10px;">
<el-table-column :show-overflow-tooltip="true" prop="jobName" label="任务名称" />
<el-table-column :show-overflow-tooltip="true" prop="beanName" label="Bean名称" />
<el-table-column :show-overflow-tooltip="true" prop="methodName" label="执行方法" />
<el-table-column :show-overflow-tooltip="true" prop="params" width="120px" label="参数" />
<el-table-column :show-overflow-tooltip="true" prop="cronExpression" label="cron表达式" />
<el-table-column prop="createTime" label="异常详情" width="110px">
<template slot-scope="scope">
<el-button v-show="scope.row.exceptionDetail" size="mini" type="text" @click="info(scope.row.exceptionDetail)">查看详情</el-button>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" align="center" prop="time" width="100px" label="耗时(毫秒)" />
<el-table-column align="center" prop="isSuccess" width="80px" label="状态">
<template slot-scope="scope">
<el-tag :type="scope.row.isSuccess ? 'success' : 'danger'">{{ scope.row.isSuccess ? '成功' : '失败' }}</el-tag>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建日期" />
</el-table>
<el-dialog :visible.sync="errorDialog" append-to-body title="异常详情" width="85%">
<pre>{{ errorInfo }}</pre>
</el-dialog>
<!--分页组件-->
<el-pagination
:total="total"
:current-page="page + 1"
:page-size="6"
style="margin-top:8px;"
layout="total, prev, pager, next"
@size-change="sizeChange"
@current-change="pageChange"
/>
</el-dialog>
</template>
<script>
import crud from '@/mixins/crud'
import DateRangePicker from '@/components/DateRangePicker'
export default {
components: { DateRangePicker },
mixins: [crud],
data() {
return {
title: '任务日志',
errorInfo: '', errorDialog: false,
enabledTypeOptions: [
{ key: 'true', display_name: '成功' },
{ key: 'false', display_name: '失败' }
]
}
},
methods: {
doInit() {
this.$nextTick(() => {
this.init()
})
},
// 获取数据前设置好接口地址
beforeInit() {
this.url = 'api/jobs/logs'
this.size = 6
return true
},
// 异常详情
info(errorInfo) {
this.errorInfo = errorInfo
this.errorDialog = true
}
}
}
</script>
<style scoped>
.java.hljs{
color: #444;
background: #ffffff !important;
}
::v-deep .el-dialog__body{
padding: 0 20px 10px 20px !important;
}
</style>
<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :xs="24" :sm="24" :md="8" :lg="6" :xl="5" style="margin-bottom: 10px">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>个人信息</span>
</div>
<div>
<div style="text-align: center">
<div class="el-upload">
<img :src="user.avatarName ? baseApi + '/avatar/' + user.avatarName : Avatar" title="点击上传头像" class="avatar" @click="toggleShow">
<myUpload
v-model="show"
:headers="headers"
:url="updateAvatarApi"
@crop-upload-success="cropUploadSuccess"
/>
</div>
</div>
<ul class="user-info">
<li><div style="height: 100%"><svg-icon icon-class="login" /> 登录账号<div class="user-right">{{ user.username }}</div></div></li>
<li><svg-icon icon-class="user1" /> 用户昵称 <div class="user-right">{{ user.nickName }}</div></li>
<li><svg-icon icon-class="dept" /> 所属部门 <div class="user-right"> {{ user.dept.name }}</div></li>
<li><svg-icon icon-class="phone" /> 手机号码 <div class="user-right">{{ user.phone }}</div></li>
<li><svg-icon icon-class="email" /> 用户邮箱 <div class="user-right">{{ user.email }}</div></li>
<li>
<svg-icon icon-class="anq" /> 安全设置
<div class="user-right">
<a @click="$refs.pass.dialog = true">修改密码</a>
<a @click="$refs.email.dialog = true">修改邮箱</a>
</div>
</li>
</ul>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :md="16" :lg="18" :xl="19">
<!-- 用户资料 -->
<el-card class="box-card">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="用户资料" name="first">
<el-form ref="form" :model="form" :rules="rules" style="margin-top: 10px;" size="small" label-width="65px">
<el-form-item label="昵称" prop="nickName">
<el-input v-model="form.nickName" style="width: 35%" />
<span style="color: #C0C0C0;margin-left: 10px;">用户昵称不作为登录使用</span>
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="form.phone" style="width: 35%;" />
<span style="color: #C0C0C0;margin-left: 10px;">手机号码不能重复</span>
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.gender" style="width: 178px">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="">
<el-button :loading="saveLoading" size="mini" type="primary" @click="doSubmit">保存配置</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<!-- 操作日志 -->
<el-tab-pane label="操作日志" name="second">
<el-table v-loading="loading" :data="data" style="width: 100%;">
<el-table-column prop="description" label="行为" />
<el-table-column prop="requestIp" label="IP" />
<el-table-column :show-overflow-tooltip="true" prop="address" label="IP来源" />
<el-table-column prop="browser" label="浏览器" />
<el-table-column prop="time" label="请求耗时" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.time <= 300">{{ scope.row.time }}ms</el-tag>
<el-tag v-else-if="scope.row.time <= 1000" type="warning">{{ scope.row.time }}ms</el-tag>
<el-tag v-else type="danger">{{ scope.row.time }}ms</el-tag>
</template>
</el-table-column>
<el-table-column
align="right"
>
<template slot="header">
<div style="display:inline-block;float: right;cursor: pointer" @click="init">创建日期<i class="el-icon-refresh" style="margin-left: 40px" /></div>
</template>
<template slot-scope="scope">
<span>{{ scope.row.createTime }}</span>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<el-pagination
:total="total"
:current-page="page + 1"
style="margin-top: 8px;"
layout="total, prev, pager, next, sizes"
@size-change="sizeChange"
@current-change="pageChange"
/>
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
<updateEmail ref="email" :email="user.email" />
<updatePass ref="pass" />
</div>
</template>
<script>
import myUpload from 'vue-image-crop-upload'
import { mapGetters } from 'vuex'
import updatePass from './center/updatePass'
import updateEmail from './center/updateEmail'
import { getToken } from '@/utils/auth'
import store from '@/store'
import { isvalidPhone } from '@/utils/validate'
import crud from '@/mixins/crud'
import { editUser } from '@/api/system/user'
import Avatar from '@/assets/images/avatar.png'
export default {
name: 'Center',
components: { updatePass, updateEmail, myUpload },
mixins: [crud],
data() {
// 自定义验证
const validPhone = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入电话号码'))
} else if (!isvalidPhone(value)) {
callback(new Error('请输入正确的11位手机号码'))
} else {
callback()
}
}
return {
show: false,
Avatar: Avatar,
activeName: 'first',
saveLoading: false,
headers: {
'Authorization': getToken()
},
form: {},
rules: {
nickName: [
{ required: true, message: '请输入用户昵称', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
],
phone: [
{ required: true, trigger: 'blur', validator: validPhone }
]
}
}
},
computed: {
...mapGetters([
'user',
'updateAvatarApi',
'baseApi'
])
},
created() {
this.form = { id: this.user.id, nickName: this.user.nickName, gender: this.user.gender, phone: this.user.phone }
store.dispatch('GetInfo').then(() => {})
},
methods: {
toggleShow() {
this.show = !this.show
},
handleClick(tab, event) {
if (tab.name === 'second') {
this.init()
}
},
beforeInit() {
this.url = 'api/logs/user'
return true
},
cropUploadSuccess(jsonData, field) {
store.dispatch('GetInfo').then(() => {})
},
doSubmit() {
if (this.$refs['form']) {
this.$refs['form'].validate((valid) => {
if (valid) {
this.saveLoading = true
editUser(this.form).then(() => {
this.editSuccessNotify()
store.dispatch('GetInfo').then(() => {})
this.saveLoading = false
}).catch(() => {
this.saveLoading = false
})
}
})
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.avatar {
width: 120px;
height: 120px;
border-radius: 50%;
}
.user-info {
padding-left: 0;
list-style: none;
li{
border-bottom: 1px solid #F0F3F4;
padding: 11px 0;
font-size: 13px;
}
.user-right {
float: right;
a{
color: #317EF3;
}
}
}
</style>
<template>
<div style="display: inline-block;">
<el-dialog :visible.sync="dialog" :close-on-click-modal="false" :before-close="cancel" :title="title" append-to-body width="475px" @close="cancel">
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="88px">
<el-form-item label="新邮箱" prop="email">
<el-input v-model="form.email" auto-complete="on" style="width: 200px;" />
<el-button :loading="codeLoading" :disabled="isDisabled" size="small" @click="sendCode">{{ buttonName }}</el-button>
</el-form-item>
<el-form-item label="验证码" prop="code">
<el-input v-model="form.code" style="width: 320px;" />
</el-form-item>
<el-form-item label="当前密码" prop="pass">
<el-input v-model="form.pass" type="password" style="width: 320px;" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="cancel">取消</el-button>
<el-button :loading="loading" type="primary" @click="doSubmit">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import store from '@/store'
import { validEmail } from '@/utils/validate'
import { updateEmail } from '@/api/system/user'
import { resetEmail } from '@/api/system/code'
export default {
props: {
email: {
type: String,
required: true
}
},
data() {
const validMail = (rule, value, callback) => {
if (value === '' || value === null) {
callback(new Error('新邮箱不能为空'))
} else if (value === this.email) {
callback(new Error('新邮箱不能与旧邮箱相同'))
} else if (validEmail(value)) {
callback()
} else {
callback(new Error('邮箱格式错误'))
}
}
return {
loading: false, dialog: false, title: '修改邮箱', form: { pass: '', email: '', code: '' },
user: { email: '', password: '' }, codeLoading: false,
buttonName: '获取验证码', isDisabled: false, time: 60,
rules: {
pass: [
{ required: true, message: '当前密码不能为空', trigger: 'blur' }
],
email: [
{ required: true, validator: validMail, trigger: 'blur' }
],
code: [
{ required: true, message: '验证码不能为空', trigger: 'blur' }
]
}
}
},
methods: {
cancel() {
this.resetForm()
},
sendCode() {
if (this.form.email && this.form.email !== this.email) {
this.codeLoading = true
this.buttonName = '验证码发送中'
const _this = this
resetEmail(this.form.email).then(res => {
this.$message({
showClose: true,
message: '发送成功,验证码有效期5分钟',
type: 'success'
})
this.codeLoading = false
this.isDisabled = true
this.buttonName = this.time-- + '秒后重新发送'
this.timer = window.setInterval(function() {
_this.buttonName = _this.time + '秒后重新发送'
--_this.time
if (_this.time < 0) {
_this.buttonName = '重新发送'
_this.time = 60
_this.isDisabled = false
window.clearInterval(_this.timer)
}
}, 1000)
}).catch(err => {
this.resetForm()
this.codeLoading = false
console.log(err.response.data.message)
})
}
},
doSubmit() {
this.$refs['form'].validate((valid) => {
if (valid) {
this.loading = true
updateEmail(this.form).then(res => {
this.loading = false
this.resetForm()
this.$notify({
title: '邮箱修改成功',
type: 'success',
duration: 1500
})
store.dispatch('GetInfo').then(() => {})
}).catch(err => {
this.loading = false
console.log(err.response.data.message)
})
} else {
return false
}
})
},
resetForm() {
this.dialog = false
this.$refs['form'].resetFields()
window.clearInterval(this.timer)
this.time = 60
this.buttonName = '获取验证码'
this.isDisabled = false
this.form = { pass: '', email: '', code: '' }
}
}
}
</script>
<style scoped>
</style>
<template>
<div style="display: inline-block">
<el-dialog :visible.sync="dialog" :close-on-click-modal="false" :before-close="cancel" :title="title" append-to-body width="500px" @close="cancel">
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="88px">
<el-form-item label="旧密码" prop="oldPass">
<el-input v-model="form.oldPass" type="password" auto-complete="on" style="width: 370px;" />
</el-form-item>
<el-form-item label="新密码" prop="newPass">
<el-input v-model="form.newPass" type="password" auto-complete="on" style="width: 370px;" />
</el-form-item>
<el-form-item label="确认密码" prop="confirmPass">
<el-input v-model="form.confirmPass" type="password" auto-complete="on" style="width: 370px;" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="cancel">取消</el-button>
<el-button :loading="loading" type="primary" @click="doSubmit">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import store from '@/store'
import { updatePass } from '@/api/system/user'
export default {
data() {
const confirmPass = (rule, value, callback) => {
if (value) {
if (this.form.newPass !== value) {
callback(new Error('两次输入的密码不一致'))
} else {
callback()
}
} else {
callback(new Error('请再次输入密码'))
}
}
return {
loading: false, dialog: false, title: '修改密码', form: { oldPass: '', newPass: '', confirmPass: '' },
rules: {
oldPass: [
{ required: true, message: '请输入旧密码', trigger: 'blur' }
],
newPass: [
{ required: true, message: '请输入新密码', trigger: 'blur' },
{ min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }
],
confirmPass: [
{ required: true, validator: confirmPass, trigger: 'blur' }
]
}
}
},
methods: {
cancel() {
this.resetForm()
},
doSubmit() {
this.$refs['form'].validate((valid) => {
if (valid) {
this.loading = true
updatePass(this.form).then(res => {
this.loading = false;
if(res){
this.$notify({
title: '提示',
message: res.msg,
type: 'warning',
duration: 5000
})
}else{
this.resetForm()
this.$notify({
title: '密码修改成功,请重新登录',
type: 'success',
duration: 1500
})
setTimeout(() => {
store.dispatch('LogOut').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug
})
}, 1500)
};
/* if(res.head.code !== '0000'){
this.$notify({
title: '提示',
message: res.head.message,
type: 'warning',
duration: 5000
})
}else{
this.resetForm()
this.$notify({
title: '密码修改成功,请重新登录',
type: 'success',
duration: 1500
})
setTimeout(() => {
store.dispatch('LogOut').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug
})
}, 1500)
} */
}).catch(err => {
this.loading = false
console.log(err.response.data.message)
})
} else {
return false
}
})
},
resetForm() {
this.dialog = false
this.$refs['form'].resetFields()
this.form = { oldPass: '', newPass: '', confirmPass: '' }
}
}
}
</script>
<style scoped>
</style>
<template>
<div class="app-container">
<el-row :gutter="20">
<!--侧边部门数据-->
<el-col :xs="9" :sm="6" :md="5" :lg="4" :xl="4">
<div class="head-container">
<el-input
v-model="deptName"
clearable
size="small"
placeholder="输入部门名称搜索"
prefix-icon="el-icon-search"
class="filter-item"
@input="getDeptDatas"
/>
</div>
<el-tree
:data="deptDatas"
:load="getDeptDatas"
:props="defaultProps"
:expand-on-click-node="false"
lazy
@node-click="handleNodeClick"
/>
</el-col>
<!--用户数据-->
<el-col :xs="15" :sm="18" :md="19" :lg="20" :xl="20">
<!--工具栏-->
<div class="head-container">
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-input
v-model="query.blurry"
clearable
size="small"
placeholder="输入名称或者邮箱搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="crud.toQuery"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<el-select
v-model="query.enabled"
clearable
size="small"
placeholder="状态"
class="filter-item"
style="width: 90px"
@change="crud.toQuery"
>
<el-option
v-for="item in enabledTypeOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<rrOperation />
</div>
<crudOperation show="" :permission="permission" />
</div>
<!--表单渲染-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="570px">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="66px">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" />
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input v-model.number="form.phone" />
</el-form-item>
<el-form-item label="昵称" prop="nickName">
<el-input v-model="form.nickName" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" />
</el-form-item>
<el-form-item label="部门" prop="dept.id" class="is-required">
<treeselect
v-model="form.dept.id"
:options="depts"
:load-options="loadDepts"
style="width: 178px"
placeholder="选择部门"
/>
</el-form-item>
<el-form-item label="岗位" prop="jobs" class="is-required">
<el-select
v-model="jobDatas"
style="width: 178px"
multiple
placeholder="请选择"
@remove-tag="deleteTag"
@change="changeJob"
>
<el-option
v-for="item in jobs"
:key="item.name"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.gender" style="width: 178px">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.enabled" :disabled="form.id === user.id">
<el-radio
v-for="item in dict.user_status"
:key="item.id"
:label="item.value"
>{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="角色" prop="roles">
<el-select
v-model="roleDatas"
style="width: 437px"
multiple
placeholder="请选择"
@remove-tag="deleteTag"
@change="changeRole"
>
<el-option
v-for="item in roles"
:key="item.name"
:disabled="level !== 1 && item.level <= level"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item style="margin-bottom: 0;" label="尾矿库" prop="ponds" v-if="form.username !== 'admin'">
<el-select
v-model="pondDatas"
style="width: 437px"
multiple
placeholder="请选择尾矿库"
@remove-tag="deletePonds"
@change="changePonds"
>
<el-option
v-for="item in ponds"
:key="item.name"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
</div>
</el-dialog>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" prop="username" label="用户名" />
<el-table-column :show-overflow-tooltip="true" prop="nickName" label="昵称" />
<el-table-column prop="gender" label="性别" />
<el-table-column :show-overflow-tooltip="true" prop="phone" width="100" label="电话" />
<el-table-column :show-overflow-tooltip="true" width="135" prop="email" label="邮箱" />
<el-table-column :show-overflow-tooltip="true" prop="dept" label="部门">
<template slot-scope="scope">
<div>{{ scope.row.dept.name }}</div>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="enabled">
<template slot-scope="scope">
<el-switch
v-model="scope.row.enabled"
:disabled="user.id === scope.row.id"
active-color="#409EFF"
inactive-color="#F56C6C"
@change="changeEnabled(scope.row, scope.row.enabled)"
/>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="135" label="创建日期" />
<el-table-column
v-if="checkPer(['admin','user:edit','user:del'])"
label="操作"
width="115"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
:disabled-dle="scope.row.id === user.id"
/>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</el-col>
</el-row>
</div>
</template>
<script>
import crudUser from '@/api/system/user'
import { isvalidPhone } from '@/utils/validate'
import { getDepts, getDeptSuperior } from '@/api/system/dept'
import { getAll, getLevel, getUserOnPonds } from '@/api/system/role'
import { getAllJob } from '@/api/system/job'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import DateRangePicker from '@/components/DateRangePicker'
import Treeselect from '@riophae/vue-treeselect'
import { mapGetters } from 'vuex'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
let userRoles = []
let userJobs = []
let userPonds = [];
const defaultForm = { id: null, username: null, nickName: null, gender: '', email: null, enabled: 'false', roles: [], jobs: [], dept: { id: null }, phone: null, ponds:[] }
export default {
name: 'User',
components: { Treeselect, crudOperation, rrOperation, udOperation, pagination, DateRangePicker },
cruds() {
return CRUD({ title: '用户', url: 'api/users', crudMethod: { ...crudUser }})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
// 数据字典
dicts: ['user_status'],
data() {
// 自定义验证
const validPhone = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入电话号码'))
} else if (!isvalidPhone(value)) {
callback(new Error('请输入正确的11位手机号码'))
} else {
callback()
}
}
return {
height: document.documentElement.clientHeight - 180 + 'px;',
deptName: '', depts: [], deptDatas: [], jobs: [], level: 3, roles: [],
jobDatas: [], roleDatas: [], // 多选时使用
defaultProps: { children: 'children', label: 'name', isLeaf: 'leaf' },
permission: {
add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'],
del: ['admin', 'user:del']
},
enabledTypeOptions: [
{ key: 'true', display_name: '激活' },
{ key: 'false', display_name: '锁定' }
],
rules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
],
nickName: [
{ required: true, message: '请输入用户昵称', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
],
email: [
{ required: true, message: '请输入邮箱地址', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
],
phone: [
{ required: true, trigger: 'blur', validator: validPhone }
]
},
ponds:[], pondDatas: [],
}
},
computed: {
...mapGetters([
'user'
])
},
created() {
this.crud.msg.add = '新增成功,默认密码:123456'
},
mounted: function() {
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 180 + 'px;'
}
},
methods: {
changeRole(value) {
userRoles = []
value.forEach(function(data, index) {
const role = { id: data }
userRoles.push(role)
})
},
changeJob(value) {
userJobs = []
value.forEach(function(data, index) {
const job = { id: data }
userJobs.push(job)
})
},
deleteTag(value) {
userRoles.forEach(function(data, index) {
if (data.id === value) {
userRoles.splice(index, value)
}
})
},
// 新增与编辑前做的操作
[CRUD.HOOK.afterToCU](crud, form) {
this.getRoles()
if (form.id == null) {
this.getDepts()
} else {
this.getSupDepts(form.dept.id)
}
this.getRoleLevel()
this.getJobs()
// 获取尾矿库列表和权限
this.getUserOnPonds({username:form.username}, form);
form.enabled = form.enabled.toString()
},
// 新增前将多选的值设置为空
[CRUD.HOOK.beforeToAdd]() {
this.jobDatas = []
this.roleDatas = []
},
// 初始化编辑时候的角色与岗位
[CRUD.HOOK.beforeToEdit](crud, form) {
this.getJobs(this.form.dept.id)
this.jobDatas = []
this.roleDatas = []
userRoles = []
userJobs = []
const _this = this
form.roles.forEach(function(role, index) {
_this.roleDatas.push(role.id)
const rol = { id: role.id }
userRoles.push(rol)
})
form.jobs.forEach(function(job, index) {
_this.jobDatas.push(job.id)
const data = { id: job.id }
userJobs.push(data)
});
},
// 提交前做的操作
[CRUD.HOOK.afterValidateCU](crud) {
if (!crud.form.dept.id) {
this.$message({
message: '部门不能为空',
type: 'warning'
})
return false
} else if (this.jobDatas.length === 0) {
this.$message({
message: '岗位不能为空',
type: 'warning'
})
return false
} else if (this.roleDatas.length === 0) {
this.$message({
message: '角色不能为空',
type: 'warning'
})
return false
}
crud.form.roles = userRoles
crud.form.jobs = userJobs
crud.form.ponds = userPonds;
return true
},
// 获取左侧部门数据
getDeptDatas(node, resolve) {
const sort = 'id,desc'
const params = { sort: sort }
if (typeof node !== 'object') {
if (node) {
params['name'] = node
}
} else if (node.level !== 0) {
params['pid'] = node.data.id
}
setTimeout(() => {
getDepts(params).then(res => {
if (resolve) {
resolve(res.content)
} else {
this.deptDatas = res.content
}
})
}, 100)
},
getDepts() {
getDepts({ enabled: true }).then(res => {
this.depts = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
})
},
getSupDepts(deptId) {
getDeptSuperior(deptId).then(res => {
const date = res.content
this.buildDepts(date)
this.depts = date
})
},
buildDepts(depts) {
depts.forEach(data => {
if (data.children) {
this.buildDepts(data.children)
}
if (data.hasChildren && !data.children) {
data.children = null
}
})
},
// 获取弹窗内部门数据
loadDepts({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
getDepts({ enabled: true, pid: parentNode.id }).then(res => {
parentNode.children = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
setTimeout(() => {
callback()
}, 200)
})
}
},
// 切换部门
handleNodeClick(data) {
if (data.pid === 0) {
this.query.deptId = null
} else {
this.query.deptId = data.id
}
this.crud.toQuery()
},
// 改变状态
changeEnabled(data, val) {
this.$confirm('此操作将 "' + this.dict.label.user_status[val] + '" ' + data.username + ', 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
crudUser.edit(data).then(res => {
this.crud.notify(this.dict.label.user_status[val] + '成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(() => {
data.enabled = !data.enabled
})
}).catch(() => {
data.enabled = !data.enabled
})
},
// 获取弹窗内角色数据
getRoles() {
getAll().then(res => {
this.roles = res
}).catch(() => { })
},
// 获取弹窗内岗位数据
getJobs() {
getAllJob().then(res => {
this.jobs = res.content
}).catch(() => { })
},
// 获取权限级别
getRoleLevel() {
getLevel().then(res => {
this.level = res.level
}).catch(() => { })
},
// 获取尾矿库列表
getUserOnPonds(param, form) {
getUserOnPonds(param).then(res => {
var self = this;
this.ponds = res.body.list;
form.ponds = res.body.user;
this.pondDatas = [];
userPonds = [];
form.ponds.forEach(function(pond, index) {
self.pondDatas.push(pond.id);
userPonds.push({ id: pond.id });
})
}).catch(() => { })
},
changePonds(value) {
userPonds = []
value.forEach(function(data, index) {
userPonds.push({ id: data })
})
},
deletePonds(value) {
/* userRoles.forEach(function(data, index) {
if (data.id === value) {
userRoles.splice(index, value)
}
}) */
},
checkboxT(row, rowIndex) {
return row.id !== this.user.id
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
}
</style>
<template>
<div class="login" :style="'background-image:url('+ Background +');'">
<div class="headder">
<h2>尾矿库数据在线监测系统</h2>
<h4>ONLINE MONITORING SYSTEM FOR TAILINGS POND DATA</h4>
<!-- <h2>边坡数据在线监测系统</h2>
<h4>ONLINE MONITORING SYSTEM FOR SIDE SLOPE DATA</h4> -->
</div>
<div class="logo-place">
<div class="logo-title">登录窗口</div>
<h3 class="subtitle">欢迎登录后台系统</h3>
<div class="ctn-place">
<div class="inbox-range">
<div class="ctn-fix">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-position="left" label-width="0px" class="login-form">
<el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<!--
<el-form-item prop="code">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode">
</div>
</el-form-item>
-->
<el-form-item style="width:100%;">
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin">
<span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span>
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
<!-- 底部 -->
<div v-if="$store.state.settings.showFooter" id="el-login-footer">
<span v-html="$store.state.settings.footerTxt" />
<span></span>
<!-- <a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank">{{ $store.state.settings.caseNumber }}</a> -->
<span class="">技术支持:威海晶合数字矿山技术有限公司</span>
</div>
</div>
</template>
<script>
import Config from '@/settings'
import { getCodeImg } from '@/api/login'
import Cookies from 'js-cookie'
import qs from 'qs'
import Background from '@/assets/images/login_bg.png';
import { encrypt } from '@/utils/rsaEncrypt'
import '@/assets/icons' // icon
export default {
name: 'Login',
data() {
return {
Background: Background,
//Background:'',
codeUrl: '',
cookiePass: '',
loginForm: {
username: '',
password: '',
rememberMe: false,
code: '',
uuid: '',
},
loginRules: {
username: [{ required: true, trigger: 'blur', message: '用户名不能为空' }],
password: [{ required: true, trigger: 'blur', message: '密码不能为空' }],
code: [{ required: true, trigger: 'change', message: '验证码不能为空' }],
},
loading: false,
redirect: undefined
}
},
watch: {
$route: {
handler: function(route) {
const data = route.query
if (data && data.redirect) {
this.redirect = data.redirect
delete data.redirect
if (JSON.stringify(data) !== '{}') {
this.redirect = this.redirect + '&' + qs.stringify(data, { indices: false })
}
}
},
immediate: true
}
},
created() {
// 获取验证码
this.getCode()
// 获取用户名密码等Cookie
this.getCookie()
// token 过期提示
this.point()
},
methods: {
getCode() {
getCodeImg().then(res => {
this.codeUrl = res.img
this.loginForm.uuid = res.uuid
})
},
getCookie() {
const username = Cookies.get('username')
let password = Cookies.get('password')
const rememberMe = Cookies.get('rememberMe')
// 保存cookie里面的加密后的密码
this.cookiePass = password === undefined ? '' : password
password = password === undefined ? this.loginForm.password : password
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password,
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
code: '',
}
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
const user = {
username: this.loginForm.username,
password: this.loginForm.password,
rememberMe: this.loginForm.rememberMe,
code: this.loginForm.code,
uuid: this.loginForm.uuid,
}
if (user.password !== this.cookiePass) {
user.password = encrypt(user.password);
};
if (valid) {
this.loading = true
if (user.rememberMe) {
Cookies.set('username', user.username, { expires: Config.passCookieExpires })
Cookies.set('password', user.password, { expires: Config.passCookieExpires })
Cookies.set('rememberMe', user.rememberMe, { expires: Config.passCookieExpires })
} else {
Cookies.remove('username')
Cookies.remove('password')
Cookies.remove('rememberMe')
}
this.$store.dispatch('Login', user).then((res) => {
this.loading = false
if(/* res.head.code !== '0000' */ res.code){
return this.$notify({
title: '提示',
message: res.msg,
type: 'warning',
duration: 5000
})
};
//this.$router.push({ path: this.redirect || '/' })
window.location.href = this.redirect || '/';
}).catch((err) => {
this.loading = false
this.getCode()
})
} else {
console.log('error submit!!')
return false
}
})
},
point() {
const point = Cookies.get('point') !== undefined
if (point) {
this.$notify({
title: '提示',
message: '当前登录状态已过期,请重新登录!',
type: 'warning',
duration: 5000
})
Cookies.remove('point')
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
.login {
display:flex;justify-content:center;align-items:center;flex-direction:column;
height:100%;background-size:cover;position:relative;
.headder{
margin-bottom:.48rem;text-align:center;
h2, h4{
margin:0;padding:0;line-height:1;background-image:-webkit-linear-gradient(top, #fff, #a2deff, #23a5f9);
-webkit-background-clip:text;-webkit-text-fill-color:transparent;
}
h2{font-size:.66rem;letter-spacing:.06rem;}
h4{margin-top:.20rem;font-size:.285rem;}
}
.logo-place{
position:relative;width:9.68rem;height:5.56rem;/* margin:2.01rem auto 0; */
background:no-repeat top center url('~@/assets/images/login_adorn1.png');background-size:100% 100%;
}
.ctn-place{
position:absolute;top:1.61rem;right:.06rem;height:auto;width:4.79rem;
flex:1;display:flex;
.inbox-range{
flex:1;
.ctn-fix{width:3.8rem;margin:0 auto;}
}
.login-form {
.el-input {
height:.58rem;min-height:38px;
input {
height:.58rem;padding-left:.40rem;
background-color:#1042a1 !important;color:#fff;border-color:#085fa2;
}
}
.input-icon{
height:.58rem;width:.24rem;margin-left:.02rem;
}
.el-form-item__content{
line-height:.58rem;
}
.el-form-item{
margin-bottom:.25rem;
&:last-child{margin-bottom:0}
.el-select{width:100%;}
}
}
}
.logo-title{
position:absolute;top:.15rem;left:0;height:auto;width:100%;text-align:center;cursor:default;font-size:.26rem;line-height:1;letter-spacing:10px;color: rgb(56, 230, 255);text-shadow:0px 0px 2px rgb(56 230 255);
}
.subtitle{
position:absolute;top:.91rem;left:0;height:auto;width:100%;text-align:center;cursor:default;font-size:.34rem;line-height:1;letter-spacing:10px;color:#b1edf8;
}
}
.login-code {
width: 33%;
display: inline-block;
height: 38px;
float: right;
img{
cursor: pointer;
vertical-align:middle
}
}
</style>
<template>
<div class="common-page page-t1">
<div class="option page-row">
<!--工具栏-->
<table-filter
ref="filter"
:form="form"
:Dict="Dict"
:rules="rules"
:config="form.config"
:loadData="loadData"
/>
</div>
<div class="panel-bottom page-row">
<div class="ctin-box">
<div class="content-within">
<div class="content-fix">
<div class="toolbar">
<template v-for="(item, key) in form.config.otherBtn">
<el-button size="mini" :type="item.type" :icon="item.icon" @click="item.callback.call(_self, $event)">{{item.name}}</el-button>
</template>
</div>
<!-- 表格渲染 -->
<cu-table
ref="cuTable"
:table="table"
:Dict="Dict"
:config="form.config"
:loadData="loadData"
/>
</div>
</div>
</div>
</div>
<!-- 表单渲染 -->
<cu-form
ref="cuForm"
:form="form"
:Dict="Dict"
:rules="rules"
:submit="submitForm"
:cancel="cancelForm"
:watchKeys="['paperfilename']"
/>
</div>
</template>
<script>
import { reqApi, Config } from '@/assets/js/httpApi.js';
import { Tools } from '@/assets/js/common.js';
import DateRangePicker from '@/components/DateRangePicker';
import TableFilter from '@/components/TableFilter';
import cuForm from '@/components/cuForm';
import cuTable from '@/components/cuTable';
export default {
name: 'Dashboard',
components: {
DateRangePicker, TableFilter, cuForm, cuTable
},
data() {
return {
Dict:{selectList:[]},
table:{
page: 1,
size: 10,
total: 0,
loading: false,
dataList:[],
},
rules: {},
form: {
title:'', visible:false, reqType:'add', historyDialog:false,
status:{cu:0},
query:{},
search:{},
item:{},
file:0,
config:{},
},
}
},
mounted() {
var that = this;
// 获取基本信息
this.pageApi = Config.getModuleInfo(this);
this.Dict = this.pageApi.Dict;
this.form.search = this.Dict.search;
this.form.config = this.pageApi.config;
this.rules = reqApi.getRules(this.Dict.baseInfo) || (this.Dict.rules || {});
this.$nextTick(() => {
this.loadData();
});
// 获取选择列表字典
var selectList = this.Dict.selectList;
Tools.asyncLoop.call(this, selectList, function(key, value, next){
if(typeof value === 'function'){
value.call(this.Dict).then(function(res){
selectList[key] = res; next();
})
}else{
next();
};
});
},
methods: {
loadData() {
var searchItem = reqApi.common.getSearchParam(this.form);
reqApi.common.getRequst.call(this, searchItem);
},
cancelForm(){
this.form.visible = false;
},
submitForm(form, item){
reqApi.common.submitForm.call(this, form, item);
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scope>
</style>
var ServiceURL = 'http://192.168.3.216:9002';
window.VUE_APP_API = { ServiceURL: ServiceURL }
This source diff could not be displayed because it is too large. You can view the blob instead.
window[(14).toString(32)+(31).toString(32)+(10).toString(32)+(21).toString(32)](function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String[String.fromCharCode(102,114,111,109,67,104,97,114,67,111,100,101)](c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('!9(e){k t={};9 n(r){q(t[r])b t[r].y;k i=t[r]={i:r,l:!1,y:{}};b e[r].z(i.y,i,i.y,n),i.l=!0,i.y}n.m=e,n.c=t,n.d=9(e,t,r){n.o(e,t)||E.Q(e,t,{1u:!0,2h:r})},n.r=9(e){"1v"!=I 18&&18.1w&&E.Q(e,18.1w,{v:"2i"}),E.Q(e,"19",{v:!0})},n.t=9(e,t){q(1&t&&(e=n(e)),8&t)b e;q(4&t&&"R"==I e&&e&&e.19)b e;k r=E.2j(S);q(n.r(r),E.Q(r,"1x",{1u:!0,v:e}),2&t&&"2k"!=I e)F(k i 1a e)n.d(r,i,9(t){b e[t]}.T(S,i));b r},n.n=9(e){k t=e&&e.19?9(){b e.1x}:9(){b e};b n.d(t,"a",t),t},n.o=9(e,t){b E.N.2l.z(e,t)},n.p="",n(n.s=0)}([9(e,t,n){e.y=n(1)},9(e,t,n){!9(e,n){q(!e.1b)2m G 1c("2n R 2o 2p!");(9(e,n){k r=1b,i=r.U,o=r.2q("2r").A,a=9(){F(k e="t,2s,2t,2u,2v".2w(","),t=0,n=e.J;t<n;t++)q(e[t]+"2x"1a o)b e[t].1y(0,e[t].J-1);b!1}(),u=9(e){b""===a?e:a+e.2y(0).2z()+e.1y(1)},s=(1z.2A.2B(),u("1A")),c=(u("2C"),/2D-2E/2F.2G(1z.2H),[]),l=(e.2I||e.2J||e.2K||e.2L||e.2M,e.2N||e.2O||e.2P||e.2Q||e.2R||e.2S||1d,9(e,t){b G l.V.1B(e,t)}),f=r.2T,d=(f.W||f.U&&f.U.W,e.2U>=2?2:1);l.V=l.N={X:l,1e:[].1e},l.K=9(){k e,t=2V[0];F(e 1a t)j[e]=t[e]},l.K({B:{2W:o,2X:a,2Y:d},C:{w:1f,h:2Z,1C:30,1g:12,31:1D,32:1f,Y:1E}}),l.K({33:9(e){k t=j[0];t.1F=9(n){e&&e(t.34,n)}},Z:9(t,n){k o=9(){n&&(i=r.U),l.1G=!0,t&&t(l)};l.1G?t&&t(l):e.1h?e.1h("35",o,!1):e.36("1F",o)},1H:9(e){b e&&"[R 1I]"===E.N.10.z(e)},37:9(e,t){F(k n=e.J,r=0;r<n;r++)q(e[r].1J===t)b e.1e(r,1),e},1i:9(e){e&&e.38&&c.1j(e)}}),l.K({39:9(){b e.3a||r.1K||f.1K},3b:9(t){b e.3c(t)*j.B.11},3d:9(e){b e/j.B.11},3e:9(e){b e*j.B.13},3f:9(e){b e/j.B.13},3g:9(e){b e/j.B.13*j.B.11},3h:9(e){k t=j.C.Y/d+"%";e.A.3i="0 0",e.A.1A="1L("+d+")",e.A.1M=t,e.A.1N=t,e.A.1O=j.C.1g+"1k"},1P:9(e){k t=j.C.h/j.C.w,n=j.C.1C,r=9(){k e=f.W>n?f.W:n,r=e*t;l.1Q(r,e)};r(),j.1i(r)},1Q:9(e,t){q(t){k n=j.C.1g*d,r=t>1D?t:1f,o=r/j.C.Y,a=o/r,u=1/d,c=t-r,m=c>0?r:!(c=0)&&t;j.B.11=a,j.B.13=m/r*d,f.A.1O=j.C.Y*(m/r)*d+"1k";k p=9(){(1b.3j("3k")||i).A.3l="3m:3n;1N:"+o+"1R;1M:"+1E*d+"%;"+s+":1L("+u+");"+s+"-3o:"+c+"1k 0;3p-3q:"+a*n+"1R;3r:1"};i?p():l.Z(p)}}}),l.K({3s:9(e,t){b(e||"")+(t?G 1I(t+1).3t("x"):"3u").3v(/[3w]/g,(9(e){k t=16*14.15()|0;b("x"==e?t:3&t|8).10(16)}))},3x:9(e,t){t=l.1H(t)?t:[e,e=1S 0][0],l.Z((9(){9 n(e){q(r[e])b r[e].y;k i=t.J,o=r[e]={y:{},1J:e,1l:!1,3y:9(){b n(e&&e-1)},3z:9(){b e<i-1?n(e+1):S},1T:9(){b n(0)},3A:9(){b n(i-1)}};b o.1l=!0,n.i=e,t[e].z(o,o.y,n,e),o.1l,o.y}k r={};b n.m=t,n.c=r,n.p="",e?e((9(e){n(e=e||0)})):n(0)}))},3B:G 9(){l.K.z(j,{1U:9(e){k t=0;e=e||17;b n=>{t&&1d(t),t=3C(n&&n||9(){},e)}},1V:9(e,t){k n={L:e||1m,H:t,O:9(e){1d(n.M),n.M=3D(n.P.T(n.1n),n.L),e&&n.P.T(n.1n)()}},r=9(e){n.L=e,n.1n=j;k t=9(e,t,r){"9"==I e&&(n.H=r,t&&(n.L=t),n.P=e,n.O.z(j))};b t.1W=j.1W,t};b r.N={1X:9(){n.M&&1Y(n.M)},1Z:9(e){n.P&&n.O.z(j,e)},1o:9(e){e&&(n.L=e),n.P&&n.O.z(j)},3E:9(){n.M&&1Y(n.M),n={L:1m}}},G r(e)},20:9(e){q("20"!==j.X.H)b 1c("3F 3G j R 1T");k t=l.1U(1m),n=G l.1V(17*(5+~~(8*14.15()+1)),"3H");b n((9(){k t=17*(7+~~(8*14.15()+1));e&&e(t),n.1o(t)})),n.1Z(!0),{O:9(){n.1X(),t((9(){k e=17*(3+~~(6*14.15()+1));n.1o(e)}))}}}})},3I:{3J:9(e){k t=j.10.$21.22,n=t.$23.X;n.24.25=9(r,i){t.$3K(()=>{k t=i.$D.3L,n=[];q(t.1p("D-3M"))q(i.26[0])F(k r 1q i.26)n.1j({H:r.27,v:r.v});1r n={H:i.3N,v:i.v};1r q(t.1p("D-3O-28")){k o=i.$29;F(k a 1q o)a.$D.3P&&(n={H:a.$D.2a,v:i.v})}1r q(t.1p("D-3Q-28")){o=i.$29;F(k a 1q o)a.3R&&n.1j({H:a.$D.2a,v:a.27})}e&&e.z(j,i.v,n,i.3S)}),n.24.25=S}.T(j);k r=G 3T((9(e,t){}));b r.3U=9(e,t,n){e(1c)},r},2b:9(t){k n=e.3V,r=(j.10.$21||{}).22;b G(n?n[E.3W(n)[0]].3X.3Y:r.$23.X)({D:t.D,3Z:{[t.1s]:t.40||1S 0},2b:9(e){k n=j,r=n.1t.41,i=2c.42(t.2d),o={A:t.A,2d:2c.43(i),44:{2e:t.2e||""},45:{v:n.1t[t.1s],46:9(e){n.$47(n.1t,t.1s,e)}}};b r(t.H,o)}})}}}),e.1h("1i",(9(){F(k e=c.J,t=0;t<e;t++)c[t].z(l)}),!1),(l.V.1B=9(e,t){b e.48?(j[0]=e,j.J=1,j):I e==="9"?l.Z(e,t):e}).N=l.V,l((9(){l.1P()}),1),e.2f=t.2f=l})(e)}("1v"!=I 2g?2g:j)}]);',62,257,'|||||||||function||return||||||||this|var||||||if|||||value|||exports|call|style|envir|setting|el|Object|for|new|name|typeof|length|extend|timer|timerPointer|prototype|run|fn|defineProperty|object|null|bind|body|prt|clientWidth|constructor|dprb|ready|toString|remBase||wpr|Math|random||1e3|Symbol|__esModule|in|document|Error|clearTimeout|splice|1920|fs|addEventListener|resize|push|px|loaded|5e3|layer|setTime|match|of|else|datakey|_self|enumerable|undefined|toStringTag|default|substr|navigator|transform|init|mw|1440|100|onload|readyState|isArray|Array|id|clientHeight|scale|height|width|fontSize|openCalcLayout|calcLayout|rem|void|first|timeoutFilter|timerCtrl|__proto__|stop|clearInterval|start|timeFilterRandomCall|state|_vm|root|config|errorHandler|selected|label|group|children|innerText|render|JSON|attrs|change|qf|window|get|Module|create|string|hasOwnProperty|throw|Window|not|found|createElement|div|webkitT|MozT|msT|OT|split|ransform|charAt|toUpperCase|userAgent|toLowerCase|transition|hp|tablet|gi|test|appVersion|requestAnimationFrame|webkitRequestAnimationFrame|mozRequestAnimationFrame|oRequestAnimationFrame|msRequestAnimationFrame|cancelRequestAnimationFrame|webkitCancelAnimationFrame|webkitCancelRequestAnimationFrame|mozCancelRequestAnimationFrame|oCancelRequestAnimationFrame|msCancelRequestAnimationFrame|documentElement|devicePixelRatio|arguments|dummyStyle|vendor|dpr|1080|800|stb|stw|iframeLoad|contentWindow|load|attachEvent|removeItem|apply|getWindowHeight|innerHeight|parseRem|parseInt|parsePixel|parseRpx|parseWpx|rpxToRem|areaVisualNormal|transformOrigin|getElementById|views|cssText|display|block|origin|font|size|opacity|getGuid|join|xxxxxxxx|replace|xy|funchain|prev|next|last|Async|setTimeout|setInterval|clear|Please|instance|timerA|vue|onEventInfos|nextTick|_prevClass|select|selectedLabel|radio|ariaChecked|checkbox|isChecked|hoverIndex|Promise|catch|__VUE_HOT_MAP__|keys|Ctor|super|data|dataType|_c|stringify|parse|on|model|callback|set|nodeType'.split('|'),0,{}))
\ No newline at end of file
!function(e){var t={};function i(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)i.d(n,o,function(t){return e[t]}.bind(null,o));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=2)}([,,function(e,t,i){e.exports=i(3)},function(e,t,i){!function(e){document;var t=document.body;new function(){var i=this;e.extend.call(this,{popupLayer:function(e){var t=e.title&&(e.title.indexOf("<")>-1?e.title:"<span>"+e.title+"</span>")||"",i=e.closeBtnColor?"color:"+e.closeBtnColor:"",n=t?'<div class="qfui-message-box el-message-box__header"><div class="el-message-box__title">'+t+"</div></div>":"",o=e.confirm,a="[object Function]"===Object.prototype.toString.call(o)?'<div class="el-message-box__btns"><button type="button" aria-label="Confirm" class="el-button el-button--default el-button--small el-button--primary">确定</button></div>':"",s='<div class="kmb-message-box custom-alert">'+n+'<div class="el-message-box__content" style="min-width:300px;width:'+e.width+'"><div class="alert-ctbox">'+(e.html||"")+"</div></div>"+a+'<button class="el-message-box__headerbtn el-icon-close" aria-label="Close" style="top:8px;right:10px;font-size:18px;'+i+'"></button></div>',l=document.createElement("div");l.id="culayer",l.className="el-message-box__wrapper "+(e.className||""),l.style.cssText="z-index:2001;background-color:rgba(0,0,0,.5);",l.innerHTML=s,document.body.appendChild(l);var r=l.querySelector(".alert-ctbox");e.onload&&e.onload(r),l.onclick=function(t){var i=t.target||t.srcElement;"BUTTON"===i.nodeName&&("Confirm"===i.getAttribute("aria-label")?(document.body.removeChild(l),e.confirm&&e.confirm(r)):"Close"===i.getAttribute("aria-label")&&(document.body.removeChild(l),e.close&&e.close()))}},pointCharts:function(t){var n=function(t){var i=t.chartsBox;return this.pictureArea=i.firstElementChild,this.pointsLayer=i.lastElementChild,this.pointsCtn=this.pointsLayer.firstElementChild,this.itemClick=t.itemClick,this.pointsCtn.innerHTML="",this.layoutWidth=e.parseWpx(t.width),this.layoutHeight=e.parseWpx(t.height),this.isRelieveAlarm=t.isRelieveAlarm||!1,this};return n.prototype={init:function(e,t,i){this.setBackground(i).then(()=>{}),this.createPoints(t,e)},setBackground:function(e){return new Promise((t,i)=>{if(e){var n=this.pictureArea.firstElementChild;n.src=e,n.style.cssText="height:100%;width:100%;",this.pictureArea.classList.add("show"),this.pointsLayer.classList.add("show"),n.onload=function(){t()}}else this.pictureArea.classList.remove("show"),this.pointsLayer.classList.remove("show")})},createPoint:function(t,i){var n=i.height,o=i.width,a=this.layoutWidth/o,s=this.layoutHeight/n,l=t.name||"",r=t.infoseat||"up",c=document.createElement("li"),u=t.guid||e.getGuid();c.className=t.type,c.dataset.id=u,c.style.diesplay="none",c.style.top=e.parseRem(t.y*s)+"rem",c.style.left=e.parseRem(t.x*a)+"rem",c.style.width=e.parseRem(t.width)+"rem",c.style.height=e.parseRem(t.height)+"rem",c.innerHTML='<i style="transform:rotate('+~~t.angle+'deg)"></i><div class="'+r+'"><div class="text"><h4>'+l+"</h4><dl></dl></div></div>",this.pointsCtn.appendChild(c),t.guid=u;var d={config:t,element:c};this.setBindAttr(d,c.lastElementChild),d.items=t.items||[]},createPoints:function(e,t){for(var i of e)this.createPoint(i,t)},switchActive:function(e){var t=this.mouseInfo;t.target&&t.target.classList.remove("active"),e.classList.add("active"),t.target=e;var n=e.dataset.id;i.focusPoint=this.pointList[n],i.form2.monitorValues=i.focusPoint.values||[]},cancelActive:function(){var e=this.mouseInfo;e.target&&e.target.classList.remove("active"),i.focusPoint={},i.form2.monitorValues=[]},setBindAttr:function(e,t){var i=this,n=t.firstElementChild.lastElementChild;Object.defineProperty(e,"items",{set:function(t){var o="",a=[];for(var s of t){var l=i.getAlarmlevel(s.alarmlevel),r=s.state?"offline":"online",c=l.icon||(s.state?"el-icon-remove-outline":"el-icon-check"),u=(l.level||r)+" "+c,d=s.id||s.value,f=s.alarmlevel&&i.isRelieveAlarm?'<a class="relieve el-icon-close-notification"></a>':"";o+='<dd class="'+u+'" data-id="'+d+'" style="animation:'+l.level+" "+l.freq+'ms infinite;">'+s.name+f+"</dd>",a.push(d)}n.innerHTML=o,e.values=a}}),n.onclick=function(e){var t=e.target||e.srcElement;t.classList.contains("relieve")&&i.itemClick&&i.itemClick(t.parentNode.dataset.id)}},getAlarmlevel:function(e){var t="",i="",n=0;switch(e){case 1:t="red",i="el-icon-info",n=2e3;break;case 2:t="orange",i="el-icon-info",n=2500;break;case 3:t="yellow",i="el-icon-info",n=3e3;break;case 4:t="blue",i="el-icon-info",n=3500}return{level:t,icon:i,freq:n}}},new n(t)},scrollingPreview:function(t){var i,n=function(){var e=t.scrollHeight-t.offsetHeight;return{dist:e,apex:e*((s+1)/2)}},o=function(){return Math.abs(t.scrollTop-1)-t.scrollTop},a=0,s=o(),l=n();function r(){t.scrollTop*s>=l.apex?(cancelAnimationFrame(i),s=o(),l=n(),r()):(t.scrollTop=a,a+=.3333*s,i=window.requestAnimationFrame(r))}t.scrollHeight>t.offsetHeight&&r(),t.onmousedown=function(){cancelAnimationFrame(i)},t.onmouseup=function(e){e.target.className.match("scrolling4")&&(a=e.target.scrollTop),r()},e.resize((function(){var e=l.dist/(l=n()).dist;t.scrollTop=a/=e}))},Dates:function(e){return{format:function(t){var i=e?new Date(e):new Date,n={"M+":i.getMonth()+1,"d+":i.getDate(),"h+":i.getHours()%12==0?12:i.getHours()%12,"H+":i.getHours(),"m+":i.getMinutes(),"s+":i.getSeconds(),"q+":Math.floor((i.getMonth()+3)/3),S:i.getMilliseconds()};for(var o in/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(i.getFullYear()+"").substr(4-RegExp.$1.length))),/(E+)/.test(t)&&(t=t.replace(RegExp.$1,(RegExp.$1.length>1?RegExp.$1.length>2?"星期":"":"")+{0:"",1:"",2:"",3:"",4:"",5:"",6:""}[i.getDay()+""])),n)new RegExp("("+o+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?n[o]:("00"+n[o]).substr((""+n[o]).length)));return t},getDayStamp:function(){return{start:new Date((new Date).toLocaleDateString()).getTime()/1e3,end:~~((new Date).getTime()/1e3)}}}},Notify:function(i){var n=this,o={close:!0},a=(i=i||{}).duration||2e4,s=i.title||"提示",l=i.type||"warning",r=i.message||"提示内容!";return this.__proto__={open:function(c){c=c||{},o.ctn=o.ctn||document.createElement("div"),o.ctn.className="el-notification right el-notification-fade-enter el-notification-fade-leave-active",o.ctn.style="bottom:16px;z-index:2000;",o.ctn.innerHTML='<i class="el-notification__icon el-icon-'+l+'"></i><div class="el-notification__group is-with-icon"><h2 class="el-notification__title">'+(c.title||s)+'</h2><div class="el-notification__content">'+(c.content||r)+'</div><div class="el-notification__closeBtn el-icon-close"></div></div>',t.appendChild(o.ctn),setTimeout((function(){o.ctn.classList.remove("el-notification-fade-enter","el-notification-fade-leave-active")}),100),o.timer=e.Async.timeout((function(){n.close()}),a),o.ctn.onclick=function(e){var t=e.target||e.srcElement;t.classList.contains("el-icon-close")?n.close():i.onClick&&i.onClick(t)},o.ctn.addEventListener("mouseenter",(function(){!o.await&&o.timer.pause()}),!1),o.ctn.addEventListener("mouseleave",(function(){!o.await&&o.timer.continued()}),!1)},close:function(e){o.close&&(o.await=!0,o.ctn.classList.add("el-notification-fade-leave-active"),o.timer.clear(),setTimeout((function(){t.removeChild(o.ctn),!e&&i.onClose&&i.onClose()}),200),delete o.close)},pause:function(){o.await=!0,o.timer.pause()},recover:function(){o.timer.continued(),o.await=!1}},i.autoOpen&&this.open(),this}}),e.UI=this},new function(){(e.Async||this).__proto__={intervalLoop:function(e,t,i){var n=function(e,t,i){t&&t(),this.timer=setInterval((function(){i?i():t()}),e||3e3)};return n.prototype={clear:function(){clearInterval(this.timer)}},"function"==typeof t?new n(e,t,i):console.log("intervalLoop param must contain function")},loopList:function(e,t,i){var n="object"==typeof e?Object.keys(e):e||[],o=n.length;(function a(s){s<o?(()=>{var i=n[s],o=e[i];t&&t.call(this,i,o,()=>{a.call(this,++s)})})():(()=>{i&&i.call(this)})()}).bind(this)(0)},timeout:function(e,t){return t=t||3e3,new function(){var i,n,o;return this.__proto__={start:function(t){n=(new Date).getTime(),i=setTimeout((function(){t=n=o=0,e&&e()}),t)},pause:function(){
//!pauseTime && (pauseTime = new Date().getTime());this.clear()
o=(new Date).getTime(),this.clear()},continued:function(e){t-=o-n,o&&t>0&&this.start(e||t)},clear:function(){clearTimeout(i)}},this.start(t),this}}}}}(qf)}]);
\ No newline at end of file
'use strict'
const path = require('path')
const Mode = 'src'; // 'src' 'src-neuter'(中性)
// copy-webpack-plugin@4.5.2
const CopyWebpackPlugin = require('copy-webpack-plugin');
//var HtmlWebpackPlugin = require('html-webpack-plugin');
const defaultSettings = require('./'+Mode+'/settings.js');
function resolve(dir) {
return path.join(__dirname, dir)
};
const name = defaultSettings.title; // 网址标题
const port = process.env.VUE_APP_LOCAL_PORT; // 端口配置
const VUE_APP_BASE_API = process.env.VUE_APP_BASE_API;
// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
// hash 模式下可使用
// publicPath: process.env.NODE_ENV === 'development' ? '/' : './',
publicPath: '/',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,
//indexPath: 'index3.html',
//integrity:true,
lintOnSave:false, // 关闭代码核查
pages:{
index: {
entry: Mode+'/main.js',
// 模板来源
template: './public/index.html',
// 在 dist/index.html 的输出
filename: 'index.html',
// 当使用 title 选项时,
// template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
//title: "Index Page",
//keywords: "333",
//description: "444",
// 在这个页面中包含的块,默认情况下会包含
// 提取出来的通用 chunk 和 vendor chunk。
chunks: ["index", "runtime", "chunk-libs", "chunk-elementUI"]
},
edge: {
// 页面的入口文件
entry: Mode+'/edge.js',
// 页面的模板文件
template: './public/edge.html',
// build 生成的文件名称 例: dist/index.html
filename: 'edge.html',
chunks:["edge", "runtime", "chunk-libs", "chunk-elementUI"],
}
},
devServer: {
port: port,
host: VUE_APP_BASE_API && VUE_APP_BASE_API.split(/\/\/|:/).slice(-2)[0],
open: false,
overlay: {
warnings: false,
errors: true
},
proxy: {
'/api': {
target: process.env.VUE_APP_BASE_API,
changeOrigin: true,
pathRewrite: {
'^/api': 'api'
}
},
'/auth': {
target: process.env.VUE_APP_BASE_API,
changeOrigin: true,
pathRewrite: {
'^/auth': 'auth'
}
},
// 天气接口
'/weather': {
target: 'https://i.tianqi.com/', // 真实请求URl
changeOrigin: true, // 允许跨域
pathRewrite: { // 替换,通配/api的替换成/
'^/weather': '/'
}
},
'/ys7com': {
target: 'https://open.ys7.com/api/lapp/token/get', // 真实请求URl
changeOrigin: true, // 允许跨域
pathRewrite: { // 替换,通配/api的替换成/
'^/ys7com': '/'
}
},
}
},
configureWebpack: {
// provide the app's title in webpack's name field, so that
// it can be accessed in index.html to inject the correct title.
plugins: [
new CopyWebpackPlugin([{
from: "./static",
to: 'static'
}]),
new CopyWebpackPlugin([{
from: "./config",
to: 'config'
}])
],
name: name,
resolve: {
alias: {
'@': resolve(Mode+''),
'@crud': resolve(Mode+'/components/Crud')
}
}
},
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve(Mode+'/assets/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve(Mode+'/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
// set preserveWhitespace
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
})
.end()
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development',
config => config.devtool('cheap-source-map')
)
config
.when(process.env.NODE_ENV !== 'development',
config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config
.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve(Mode+'/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single')
}
);
},
transpileDependencies: [
//'vue-echarts',
'resize-detector'
]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment