Commit c75c9fea authored by changhai's avatar changhai

同步代码

parents
Pipeline #320 canceled with stages
# http://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
# just a flag
ENV = 'development'
# base api
VUE_APP_BASE_API = '/dev-api'
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
# It only does one thing by converting all import() to require().
# This configuration can significantly increase the speed of hot updates,
# when you have a large number of pages.
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
VUE_CLI_BABEL_TRANSPILE_MODULES = true
# just a flag
ENV = 'production'
# base api
VUE_APP_BASE_API = '/prod-api'
NODE_ENV = production
# just a flag
ENV = 'staging'
# base api
VUE_APP_BASE_API = '/stage-api'
build/*.js
src/assets
public
dist
module.exports = {
root: false,
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']
}
}
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JSCodeStyleSettings version="0">
<option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_GENERATOR_MULT" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
<option name="SPACE_BEFORE_ASYNC_ARROW_LPAREN" value="false" />
</JSCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
</JetCodeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_FOR" value="false" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" />
</settings>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/flowmonitoringsystem_front_link.iml" filepath="$PROJECT_DIR$/.idea/flowmonitoringsystem_front_link.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
language: node_js
node_js: 10
script: npm run test
notifications:
email: false
MIT License
Copyright (c) 2017-present PanJiaChen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# vue-admin-template
> 这是一个极简的 vue admin 管理后台。它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。
[线上地址](http://panjiachen.github.io/vue-admin-template)
[国内访问](https://panjiachen.gitee.io/vue-admin-template)
目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0),它不依赖 `vue-cli`
## Extra
如果你想要根据用户角色来动态生成侧边栏和 router,你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
## 相关项目
- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板,专门针对本项目的文章,算作是一篇文档)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
## Build Setup
```bash
# 克隆项目
git clone https://github.com/PanJiaChen/vue-admin-template.git
# 进入项目目录
cd vue-admin-template
# 安装依赖
npm install
# 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org
# 启动服务
npm run dev
```
浏览器访问 [http://localhost:9528](http://localhost:9528)
## 发布
```bash
# 构建测试环境
npm run build:stage
# 构建生产环境
npm run build:prod
```
## 其它
```bash
# 预览发布环境效果
npm run preview
# 预览发布环境效果 + 静态资源分析
npm run preview -- --report
# 代码格式检查
npm run lint
# 代码格式检查并自动修复
npm run lint -- --fix
```
更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
## Demo
![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
## Browsers support
Modern browsers and Internet Explorer 10+.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
## License
[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
Copyright (c) 2017-present PanJiaChen
# vue-admin-template
English | [简体中文](./README-zh.md)
> A minimal vue admin template with Element UI & axios & iconfont & permission control & lint
**Live demo:** http://panjiachen.github.io/vue-admin-template
**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**
## Build Setup
```bash
# clone the project
git clone https://github.com/PanJiaChen/vue-admin-template.git
# enter the project directory
cd vue-admin-template
# install dependency
npm install
# develop
npm run dev
```
This will automatically open http://localhost:9528
## Build
```bash
# build for test environment
npm run build:stage
# build for production environment
npm run build:prod
```
## Advanced
```bash
# preview the release environment effect
npm run preview
# preview the release environment effect + static resource analysis
npm run preview -- --report
# code format check
npm run lint
# code format check and auto fix
npm run lint -- --fix
```
Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
## Demo
![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
## Extra
If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
## Related Project
- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
## Browsers support
Modern browsers and Internet Explorer 10+.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
## License
[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
Copyright (c) 2017-present PanJiaChen
module.exports = {
presets: [
'@vue/app'
]
}
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
const { run } = require('runjs')
const chalk = require('chalk')
const config = require('../vue.config.js')
const rawArgv = process.argv.slice(2)
const args = rawArgv.join(' ')
if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
const report = rawArgv.includes('--report')
run(`vue-cli-service build ${args}`)
const port = 9526
const publicPath = config.publicPath
var connect = require('connect')
var serveStatic = require('serve-static')
const app = connect()
app.use(
publicPath,
serveStatic('./dist', {
index: ['index.html', '/']
})
)
app.listen(port, function () {
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
if (report) {
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
}
})
} else {
run(`vue-cli-service build ${args}`)
}
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function(_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
publicPath: '../../'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
var webpack = require('webpack')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
// app: './src/main.js'
app: ['babel-polyfill', './src/main.js']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('common.js'),
new webpack.ProvidePlugin({
jQuery: "jquery",
$: "jquery"
})
],
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vendor modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
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/'
}
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"exclude": ["node_modules", "dist"]
}
import Mock from 'mockjs'
import { param2Obj } from '../src/utils'
import user from './user'
import table from './table'
const mocks = [
...user,
...table
]
// for front mock
// please use it cautiously, it will redefine XMLHttpRequest,
// which will cause many of your third-party libraries to be invalidated(like progress event).
export function mockXHR() {
// mock patch
// https://github.com/nuysoft/Mock/issues/300
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
Mock.XHR.prototype.send = function() {
if (this.custom.xhr) {
this.custom.xhr.withCredentials = this.withCredentials || false
if (this.responseType) {
this.custom.xhr.responseType = this.responseType
}
}
this.proxy_send(...arguments)
}
function XHR2ExpressReqWrap(respond) {
return function(options) {
let result = null
if (respond instanceof Function) {
const { body, type, url } = options
// https://expressjs.com/en/4x/api.html#req
result = respond({
method: type,
body: JSON.parse(body),
query: param2Obj(url)
})
} else {
result = respond
}
return Mock.mock(result)
}
}
for (const i of mocks) {
Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
}
}
// for mock server
const responseFake = (url, type, respond) => {
return {
url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
type: type || 'get',
response(req, res) {
console.log('request invoke:' + req.path)
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
}
}
}
export default mocks.map(route => {
return responseFake(route.url, route.type, route.response)
})
const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')
const path = require('path')
const mockDir = path.join(process.cwd(), 'mock')
function registerRoutes(app) {
let mockLastIndex
const { default: mocks } = require('./index.js')
for (const mock of mocks) {
app[mock.type](mock.url, mock.response)
mockLastIndex = app._router.stack.length
}
const mockRoutesLength = Object.keys(mocks).length
return {
mockRoutesLength: mockRoutesLength,
mockStartIndex: mockLastIndex - mockRoutesLength
}
}
function unregisterRoutes() {
Object.keys(require.cache).forEach(i => {
if (i.includes(mockDir)) {
delete require.cache[require.resolve(i)]
}
})
}
module.exports = app => {
// es6 polyfill
require('@babel/register')
// parse app.body
// https://expressjs.com/en/4x/api.html#req.body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
const mockRoutes = registerRoutes(app)
var mockRoutesLength = mockRoutes.mockRoutesLength
var mockStartIndex = mockRoutes.mockStartIndex
// watch files, hot reload mock server
chokidar.watch(mockDir, {
ignored: /mock-server/,
ignoreInitial: true
}).on('all', (event, path) => {
if (event === 'change' || event === 'add') {
try {
// remove mock routes stack
app._router.stack.splice(mockStartIndex, mockRoutesLength)
// clear routes cache
unregisterRoutes()
const mockRoutes = registerRoutes(app)
mockRoutesLength = mockRoutes.mockRoutesLength
mockStartIndex = mockRoutes.mockStartIndex
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
} catch (error) {
console.log(chalk.redBright(error))
}
}
})
}
import Mock from 'mockjs'
const data = Mock.mock({
'items|30': [{
id: '@id',
title: '@sentence(10, 20)',
'status|1': ['published', 'draft', 'deleted'],
author: 'name',
display_time: '@datetime',
pageviews: '@integer(300, 5000)'
}]
})
export default [
{
url: '/vue-admin-template/table/list',
type: 'get',
response: config => {
const items = data.items
return {
code: 20000,
data: {
total: items.length,
items: items
}
}
}
}
]
// const tokens = {
// admin: {
// token: 'admin-token'
// },
// }
//
// const users = {
// 'admin-token': {
// roles: ['admin'],
// introduction: 'I am a super administrator',
// avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
// name: 'admin'
// },
// }
export default [
// user login
{
url: '/vue-admin-template/user/login',
type: 'post',
response: config => {
const { username } = config.body
// const token = tokens['admin']
const token = {
token: username
}
// mock error
if (!token) {
return {
code: 60204,
message: 'Account and password are incorrect.'
}
}
return {
code: 20000,
data: token
}
}
},
// get user info
{
url: '/vue-admin-template/user/info\.*',
type: 'get',
response: config => {
const { token } = config.username
const { role } = config.role
const info = {
roles: role,
name: token
}
// mock error
if (!info) {
return {
code: 50008,
message: 'Login failed, unable to get user details.'
}
}
return {
code: 20000,
data: info
}
}
},
// user logout
{
url: '/vue-admin-template/user/logout',
type: 'post',
response: _ => {
return {
code: 20000,
data: 'success'
}
}
}
]
This diff is collapsed.
{
"name": "vue-admin-template",
"version": "4.2.1",
"description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
"author": "Pan <panfree23@gmail.com>",
"license": "MIT",
"private": true,
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src",
"test:unit": "jest --clearCache && vue-cli-service test:unit",
"test:ci": "npm run lint && npm run test:unit",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
},
"dependencies": {
"@ant-design/icons-vue": "^6.1.0",
"ant-design-vue": "^1.6.5",
"axios": "0.18.1",
"babel-polyfill": "^6.26.0",
"codemirror": "^5.54.0",
"crypto-js": "^4.0.0",
"deasync": "^0.1.21",
"echarts": "^4.9.0",
"element-ui": "^2.15.6",
"fuse.js": "^3.4.4",
"gojs": "^2.1.29",
"jquery": "^2.2.4",
"js-cookie": "2.2.0",
"js-md5": "^0.7.3",
"json2yaml": "^1.1.0",
"moment": "^2.29.1",
"monaco-editor": "^0.20.0",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"ol": "^6.3.1",
"path-to-regexp": "2.4.0",
"relation-graph": "^1.1.0",
"vue-count-to": "^1.0.13",
"vue-router": "3.0.6",
"vuex": "3.1.0",
"webpack-dev-server": "^2.11.5",
"yamljs": "^0.3.0"
},
"devDependencies": {
"@babel/core": "7.0.0",
"@babel/register": "7.0.0",
"@vue/cli-plugin-babel": "3.6.0",
"@vue/cli-plugin-eslint": "^3.9.1",
"@vue/cli-plugin-unit-jest": "3.6.3",
"@vue/cli-service": "3.6.0",
"@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.3",
"chalk": "2.4.2",
"connect": "3.6.6",
"eslint": "5.15.3",
"eslint-plugin-vue": "5.2.2",
"html-webpack-plugin": "3.2.0",
"mockjs": "1.0.1-beta3",
"monaco-editor-webpack-plugin": "^1.9.0",
"node-sass": "^4.14.1",
"runjs": "^4.3.2",
"sass-loader": "^7.1.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.2",
"vue": "^2.6.10",
"vue-resource": "^1.5.1",
"vue-template-compiler": "2.6.12"
},
"engines": {
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
'plugins': {
// to edit target browsers: use "browserslist" field in package.json
'autoprefixer': {}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template >
<div>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'page-index',
data(){
return{
windowWidth: document.documentElement.clientWidth, //实时屏幕宽度
windowHeight: document.documentElement.clientHeight, //实时屏幕高度
}
},
methods: {
},
// <!--watch中监听实时宽高-->
watch: {
windowHeight (val) {
let that = this;
console.log("实时屏幕高度:",val, that.windowHeight );
},
windowWidth (val) {
let that = this;
console.log("实时屏幕宽度:",val, that.windowHeight );
}
},
mounted() {
var that = this;
// <!--window.onresize事件挂在到mounted函数上-->
window.onresize = () => {
return (() => {
window.fullHeight = document.documentElement.clientHeight;
window.fullWidth = document.documentElement.clientWidth;
that.windowHeight = window.fullHeight; // 高
that.windowWidth = window.fullWidth; // 宽
})()
};
},
}
</script>
<style>
html{
overflow-x : hidden ;
width: 100%;
height : 100%;
margin : 0 ;
padding : 0 ;
overflow-y : hidden ;
}
</style>
import request from '@/utils/request'
import baseURL from '@/api/global_variable'
// 业务告警查询
export function selectYwAlarm(data) {
return request({
url: baseURL + '/api/v1/alarm/businessAlarm',
method: 'post',
data: data
})
}
// 链路告警查询
export function selectLinkAlarm(data) {
return request({
url: baseURL + '/api/v1/alarm/linkAlarm',
method: 'post',
data: data
})
}
import request from '@/utils/request'
import baseURL from '@/api/global_variable'
// 点击- 标签-- 认证;
export function click_tab_renzheng(data) {
return request({
url: baseURL + '/api/v1/auth28/tcpFlowLinkUpdateSubgraph',
method: 'get',
params: {
ywlxType: data
}
})
}
// 点击- 标签-- 开通;
export function click_tab_kaitong() {
return request({
url: baseURL + '/api/v1/download28/tcpFlowLinkUpdate',
method: 'get'
})
}
// 点击- 标签-- 二维码;
export function click_tab_ercode() {
return request({
url: baseURL + '/api/v1/qrCodeVerify28/tcpFlowLinkUpdate',
method: 'get'
})
}
// 点击- 标签-- 出入境;
export function click_tab_churujing() {
return request({
url: baseURL + '/api/v1/entryAndExitAuth/tcpFlowLinkUpdate',
method: 'get'
})
}
// 修改 -- 认证
export function update_renzheng_machine_line(data) {
return request({
url: baseURL + '/api/v1/auth28/updateAlarmValue',
method: 'post',
data: data
})
}
// 修改 - 开通
export function update_kaitong_machine_line(data) {
return request({
url: baseURL + '/api/v1/download28/updateAlarmValue',
method: 'post',
data: data
})
}
// 修改 - 二维码
export function update_ercode_machine_line(data) {
return request({
url: baseURL + '/api/v1/qrCodeVerify28/updateAlarmValue',
method: 'post',
data: data
})
}
// 修改 - 出入境
export function update_churujing_machine_line(data) {
return request({
url: baseURL + '/api/v1/entryAndExitAuth/updateAlarmValue',
method: 'post',
data: data
})
}
import request from '@/utils/request'
import baseURL from '@/api/global_variable'
// 根据业务站点查询信息;
export function selectAllModeMsgByYwzd(ywzd) {
return request({
url: baseURL + '/api/v1/auth28/selectAllModeMsgByYwzd',
method: 'get',
params: {
ywzd: ywzd
}
})
}
//ip查询
export function selectIp(ip) {
return request({
url: baseURL + '/api/v1/auth/selectIp',
method: 'get',
params: {
ip: ip
}
})
}
// 查询所有业务站点;
export function selectAllYwzdFromAlarmConfiguration() {
return request({
url: baseURL + '/api/v1/auth28/selectAllYwzdFromAlarmConfiguration',
method: 'get'
})
}
//查询所有Ip
export function selectAuthIpConfig() {
return request({
url: baseURL + '/api/v1/auth/getAuthIpList',
method: 'get'
})
}
//弹框ip详情
export function authselectAuthIpConfig(data) {
return request({
url: baseURL + '/api/v1/auth/selectAuthIpConfig',
method: 'get',
params: {
ip: data
}
})
}
// 修改参数;
export function updateAlarmConfiguration(data) {
return request({
url: baseURL + '/api/v1/auth28/updateAlarmConfiguration',
method: 'post',
data: {
ywzd_id: data.ywzd_id,
mode: data.mode,
amount_alarm_threshold_rate: data.amount_alarm_threshold_rate,
token_alarm_threshold_rate: data.token_alarm_threshold_rate,
request_transport_time_line: data.request_transport_time_line,
response_rtt_line: data.response_rtt_line,
response_transport_time_line: data.response_transport_time_line,
trans_handle_time_line: data.trans_handle_time_line,
amount: data.amount,
tokens: data.tokens
}
})
}
//ip修改
export function updateAuthIpConfig(data) {
return request({
url: baseURL + '/api/v1/auth/updateAuthIpConfig',
method: 'post',
data: {
ip:data.ip,
amount_alarm_threshold_rate: data.amount_alarm_threshold_rate,
token_alarm_threshold_rate: data.token_alarm_threshold_rate,
request_transport_time_line: data.request_transport_time_line,
response_rtt_line: data.response_rtt_line,
response_transport_time_line: data.response_transport_time_line,
trans_handle_time_line: data.trans_handle_time_line,
amount: data.amount,
tokens: data.tokens
}
})
}
const baseURL = 'http://127.0.0.1:8083'
// const baseURL = ''
export default baseURL
import request from '@/utils/request'
import baseURL from '@/api/global_variable'
// 点击线查询数据(折线图) -- 认证;
export function clickLineSelectEcharts_renzheng(data) {
return request({
url: baseURL + '/api/v1/auth28/selectTcpFlowByIpAndTime',
method: 'get',
params: {
serverIpName: data.serverIpName,
clientIpName: data.clientIpName,
startTime: data.startTime,
type: data.type
}
})
}
// 点击线查询数据(折线图) -- 开通;
export function clickLineSelectEcharts_kaitong(data) {
return request({
url: baseURL + '/api/v1/download28/selectTcpFlowByIpAndTime',
method: 'get',
params: {
serverIpName: data.serverIpName,
clientIpName: data.clientIpName,
startTime: data.startTime,
type: data.type
}
})
}
// 点击线查询数据(折线图) -- 二维码;
export function clickLineSelectEcharts_erCode(data) {
return request({
url: baseURL + '/api/v1/qrCodeVerify28/selectTcpFlowByIpAndTime',
method: 'get',
params: {
serverIpName: data.serverIpName,
clientIpName: data.clientIpName,
startTime: data.startTime,
type: data.type
}
})
}
// 点击机器查询; -认证
export function clickNodeSelectEcharts_renzheng(data) {
return request({
url: baseURL + '/api/v1/auth28/selectNodeDataByTimeAndIp',
method: 'get',
params: {
serverIpName: data.serverIpName,
startTime: data.startTime,
type: data.type
}
})
}
// 点击机器查询; -开通
export function clickNodeSelectEcharts_kaitong(data) {
return request({
url: baseURL + '/api/v1/download28/selectNodeDataByTimeAndIp',
method: 'get',
params: {
serverIpName: data.serverIpName,
startTime: data.startTime,
type: data.type
}
})
}
// 点击机器查询; -二维码
export function clickNodeSelectEcharts_erCode(data) {
return request({
url: baseURL + '/api/v1/qrCodeVerify28/selectNodeDataByTimeAndIp',
method: 'get',
params: {
serverIpName: data.serverIpName,
startTime: data.startTime,
type: data.type
}
})
}
//默认警告冲
export function tcpflowAlarm(ywlxType) {
return request({
url: baseURL + '/api/v1/auth28/tcpflowAlarm',
method: 'get',
params: {
ywlxType: ywlxType
}
})
}
//二维码默认告警
export function qrCodeVerify28tcpflowAlarm() {
return request({
url: baseURL + '/api/v1/qrCodeVerify28/tcpflowAlarm',
method: 'get',
})
}
This diff is collapsed.
This diff is collapsed.
import {mapGetters} from "vuex";
import Vue from "vue";
import GLOABL from './global_variable'
import { getToken, setToken, removeToken } from '@/utils/auth'
export default{
computed: {
...mapGetters([
'name',
'role',
'token',
'key',
])
},
install(Vue,options){
Vue.prototype.url= "http://www.baidu.com/" //可以自定义变量
Vue.prototype.myFun = function (ev) { //给自定义方法起个名
ev + 1;
return ev;
}
Vue.http.interceptors.push(function ( request, next ) {
// console.log(request)//附赠一个可以控制页面所有路由开始之前结束之后的方法
// 请求发送前的处理逻辑
// if(request.url !== GLOABL.baseURL+'/nacos/v1/ns/getToken'&& request.url !== GLOABL.baseURL+'/nacos/v1/ns/queryAllHistory' && request.url !== GLOABL.baseURL+'/nacos/v1/ns/getSerStatistics'){
if(request.url !== GLOABL.baseURL+'/nacos/v1/ns/getToken'){
next(function (response) {
// 请求发送后的处理逻辑
// 更具请求的状态, response参数会返回给 successCallback或errorCallback
// if(response.data.sign === 'false'){
// var username;
// var localToken;
// if(this.token!==null){
// if(this.token.username === null){
// username = JSON.parse(this.token).username;
// Vue.http.headers.common['token'] = JSON.parse(this.token).token;
// localToken = JSON.parse(this.token);
// }else{
// username = this.token.username;
// Vue.http.headers.common['token'] = this.token.token;
// localToken = this.token;
// }
// }
//
// var data = {
// username: username
// }
// var json = JSON.stringify(data);
// this.$http.post(this.url+'/nacos/v1/ns/getToken',json,{emulateJSON:true}).then( function(res) {
// if(res.data.sign!=='false'){
// var msg = {
// username:localToken.username,
// password:localToken.password,
// role:localToken.role,
// token:res.data.longToken,
// shrotToken:res.data.shrotToken,
// }
// console.log(msg)
// this.$store.dispatch('user/setNewToken', msg).then(() => {
// Vue.http.headers.common['token'] = res.data.shrotToken;
// this.$http.post(request.url,request.body,{emulateJSON:true}).then( function(res) {
// console.log(res)
// })
// })
//
// }else{
// // console.log("longToken失效更新")
// // this.$message({
// // message: '登录超时,请重新登录',
// // type: 'error',
// // offset:80,
// // });
// // this.$store.dispatch('user/logout')
// // this.$router.push(`/login?redirect=${this.$route.fullPath}`)
// }
//
// })
// }
if(response.data.sign === 'false'){
this.$store.dispatch('user/logout')
this.$router.push('/login')
this.$message({
message: 'token失效,请重新登录',
type: 'error',
offset:80,
});
}
return response
});
}
});
}
}
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
import pathToRegexp from 'path-to-regexp'
export default {
data() {
return {
levelList: null
}
},
watch: {
$route() {
this.getBreadcrumb()
}
},
created() {
this.getBreadcrumb()
},
methods: {
getBreadcrumb() {
// only show routes with meta.title
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
const first = matched[0]
if (!this.isDashboard(first)) {
matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
},
isDashboard(route) {
const name = route && route.name
if (!name) {
return false
}
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
},
pathCompile(path) {
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
const { params } = this.$route
var toPath = pathToRegexp.compile(path)
return toPath(params)
},
handleLink(item) {
const { redirect, path } = item
if (redirect) {
this.$router.push(redirect)
return
}
this.$router.push(this.pathCompile(path))
}
}
}
</script>
<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>
<script>
const serverSrc='www.baidu.com';
const token='12345678';
const hasEnter=false;
const userSite="中国钓鱼岛";
export default
{
userSite,//用户地址
token,//用户token身份
serverSrc,//服务器地址
hasEnter,//用户登录状态
}
</script>
<template>
<div style="padding: 0 15px;" @click="toggleClick">
<!--<svg-->
<!--:class="{'is-active':isActive}"-->
<!--class="hamburger"-->
<!--viewBox="0 0 1024 1024"-->
<!--xmlns="http://www.w3.org/2000/svg"-->
<!--width="64"-->
<!--height="64"-->
<!--&gt;-->
<!--<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />-->
<!--</svg>-->
</div>
</template>
<script>
export default {
name: 'Hamburger',
props: {
isActive: {
type: Boolean,
default: false
}
},
methods: {
toggleClick() {
this.$emit('toggleClick')
}
}
}
</script>
<style scoped>
.hamburger {
display: inline-block;
vertical-align: middle;
width: 20px;
height: 20px;
}
.hamburger.is-active {
transform: rotate(180deg);
}
</style>
<template>
<div style="width:100%;height:100%;z-index:999999;display: flex;justify-content: center;align-items: center">
<div>
<div class="demo1"></div>
<div class="demo1"></div>
<div class="demo1"></div>
<div class="demo1"></div>
<div class="demo1"></div>
</div>
</div>
</template>
<script>
export default {
name: 'customerLoading'
}
</script>
<style scoped>
.demo1 {
width: 10px;
height: 40px;
border-radius: 10px;
background: #68b2ce;
float: left;
margin: 0 10px;
animation: demo1 linear 1s infinite;
-webkit-animation: demo1 linear 1s infinite;
}
.demo1:nth-child(1) {
animation-delay: 0.05s;
}
.demo1:nth-child(2) {
animation-delay: 0.1s;
}
.demo1:nth-child(3) {
animation-delay: 0.2s;
}
.demo1:nth-child(4) {
animation-delay: 0.3s;
}
.demo1:nth-child(5) {
animation-delay: 0.4s;
}
@keyframes demo1 {
0%, 60%, 100% {
transform: scale(1);
}
30% {
transform: scale(2.5);
}
}
@-webkit-keyframes demo1 {
0%, 60%, 100% {
transform: scale(1);
}
30% {
transform: scale(2.5);
}
}
</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>
/*自定义字体*/
/*@font-face {*/
/*font-family: 'yuantixi';*/
/*src: url("./Branding-Light.otf");*/
/*font-weight: normal;*/
/*font-style: normal;*/
/*}*/
@font-face {
font-family: 'yuanticu';
src: url("./Branding-Medium.otf");
}
@font-face {
font-family: "yuantixi";
src: url("./Branding-Light.otf");
}
@font-face {
font-family: "microyahei";
src: url("./微软雅黑Bold.ttf");
font-weight: normal;
}
.ant-upload-list-picture-card-container,
.ant-upload-list-picture-card .ant-upload-list-item {
width: 70%;
height: 70%;
}
.distpicker-address-wrapper select {
width: 30%;
}
.ant-upload.ant-upload-drag {
height: 150px;
}
.border_corner {
position: absolute;
background-color: #7e80b1;
}
/* 右上靠上 */
.border_corner:nth-child(1) {
width: 30px;
height: 3px;
right: -2px;
top: -2px;
}
/* 右上靠右 */
.border_corner:nth-child(2) {
width: 3px;
height: 30px;
right: -2px;
top: -2px;
}
/* 右下靠右 */
.border_corner:nth-child(3) {
width: 3px;
height: 30px;
right: -2px;
bottom: -2px;
}
/* 右下靠下 */
.border_corner:nth-child(4) {
width: 30px;
height: 3px;
right: -2px;
bottom: -2px;
}
/* 左下靠下 */
.border_corner:nth-child(5) {
width: 30px;
height: 3px;
left: -2px;
bottom: -2px;
}
/* 左下靠左 */
.border_corner:nth-child(6) {
width: 3px;
height: 30px;
left: -2px;
bottom: -2px;
}
.radar {
background: -webkit-radial-gradient(center, rgba(32, 255, 77, 0.3) 0%, rgba(32, 255, 77, 0) 75%), -webkit-repeating-radial-gradient(rgba(32, 255, 77, 0) 5.8%, rgba(32, 255, 77, 0) 18%, #20ff4d 18.6%, rgba(32, 255, 77, 0) 18.9%), -webkit-linear-gradient(90deg, rgba(32, 255, 77, 0) 49.5%, #20ff4d 50%, #20ff4d 50%, rgba(32, 255, 77, 0) 50.2%), -webkit-linear-gradient(0deg, rgba(32, 255, 77, 0) 49.5%, #20ff4d 50%, #20ff4d 50%, rgba(32, 255, 77, 0) 50.2%);
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
border: 0.1rem solid #20ff4d;
overflow: hidden;
}
.radar:before {
content: ' ';
display: block;
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
}
.radar:after {
content: ' ';
display: block;
background-image: linear-gradient(44deg, rgba(0, 255, 51, 0) 50%, #00ff33 100%);
width: 50%;
height: 50%;
position: absolute;
top: 0;
left: 0;
animation: radar-beam 4s infinite;
animation-timing-function: linear;
transform-origin: bottom right;
border-radius: 100% 0 0 0;
}
@keyframes radar-beam {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/*表格的自定义属性;全局*/
.ant-table-body {
margin: 0 !important;
background-color: #F3F4F9 !important;
}
/*表格的数据*/
.thCss {
font-weight: normal;
font-size: 14px;
background-color: rgba(176, 255, 93, 0);
}
/*设置查询结果展示表格的数据样式*/
.searchTableRowCss {
background-color: #e4ffff;
}
.theadCssSearch {
background-color: #99FFFF;
font-weight: bolder;
font-size: 13px;
}
/*.ant-form-item label {*/
/*color: white;*/
/*}*/
/*@font-face {*/
/*font-family:'huawen';*/
/*src: url('../font/huawen.ttf');*/
/*font-weight: normal;*/
/*font-style: normal;*/
/*}*/
/* 20ff4d */
/* 二级菜单 */
.secondaryMenu {
background-color: red;
height: 50px;
display: flex;
font-weight: bolder;
background-color: #333840;
align-items: center;
color: #ffffff;
}
/* 二级菜单 - 单个标签 */
.secondaryMenu_single {
height: 30px;
background-color: #41464D;
display: flex;
border-radius: 5px;
justify-content: center;
align-items: center;
padding: 0 5px;
margin: 0 10px;
}
/* 二级菜单 - 选中的蓝色标签 */
.secondaryMenu_single_selected {
width: 5px;
height: 20px;
background-color: #0576FF;
border-radius: 5px;
margin-right: 5px;
}
/* */
.secondaryMenu_single_select {
width: 5px;
height: 20px;
background-color: #41464D;
border-radius: 5px;
margin-right: 5px;
}
.tableHead {
color: white;
background-color: #333840;
font-weight: bolder;
font-size: 20px;
}
.ant-btn:hover, .ant-btn:focus {
color: white;
}
.tableContent {
font-weight: bolder;
font-size: 13px;
background-color: #070836;
color: #ffffff;
}
tr{
color: white;
}
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
background: #e6f7ff42;
}
.ant-table-thead {
}
.inputDivCss {
background-color: rgba(153, 153, 153, 0.19);
height: 60px;
display: flex;
align-items: center;
}
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import Antd from 'ant-design-vue'
import App from './App'
import router from './router/router'
import store from './store'
import 'ant-design-vue/dist/antd.css'
import VueResource from 'vue-resource'
import ElementUI from 'element-ui';
import 'babel-polyfill'
import 'jquery'
import echarts from 'echarts'
import $ from 'jquery'
Vue.prototype.$echarts = echarts
import './css/index.css'
Vue.config.productionTip = false
// Vue.http.options.emulateJSON = false
Vue.use(ElementUI);
Vue.use(Antd)
Vue.use(VueResource)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login'] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
// start progress bar
NProgress.start()
// set page title
document.title = getPageTitle(to.meta.title)
// determine whether the user has logged in
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({ path: '/' })
NProgress.done()
} else {
const hasGetUserInfo = store.getters.name
if (hasGetUserInfo) {
next()
} else {
try {
// get user info
await store.dispatch('user/getInfo')
next()
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
// other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
})
router.afterEach(() => {
// finish progress bar
NProgress.done()
})
import Vue from 'vue'
import Router from 'vue-router'
import login from '@/views/login/login'
import home from '@/views/home/home1'
import globalOverview from '@/views/globalOverview/globalOverview'
import dashboard from '@/views/dashboard/dashboard'
import topology from '@/views/topology/topology'
import topology2 from '@/views/topology2/topology2'
import trace from '@/views/trace/trace'
import performanceAnalysis from '@/views/performanceAnalysis/performanceAnalysis'
import alarm from '@/views/alarm/alarm'
import alarmLink from '@/views/alarm/alarm_link'
import alarmYw from '@/views/alarm/alarm_yw'
import serviceMonitor from '@/views/serviceMonitor/serviceMonitor1'
import configurationManagement from '@/views/configurationManagement/configurationManagement'
import linkAlarmConfig from '@/views/configurationManagement/linkAlarmConfig'
import serviceIP from '@/views/configurationManagement/serviceIP'
import serviceAlarm from '@/views/configurationManagement/serviceAlarm'
import user from '@/views/user/user'
// import store from '@/store'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
redirect: '/globalOverview'
// redirect: '/serviceMonitor'
},
{
path: '/login',
name: 'login',
component: login
},
{
path: '/home',
name: 'home',
component: home,
redirect: '/globalOverview',
children: [
{
path: '/globalOverview',
name: 'globalOverview',
component: globalOverview
},
{
path: '/configurationManagement',
name: 'configurationManagement',
component: configurationManagement,
redirect: '/configurationManagement/serviceAlarm',
children: [
{
path: '/configurationManagement/linkAlarmConfig',
name: 'linkAlarmConfig',
component: linkAlarmConfig
},
{
path: '/configurationManagement/serviceAlarm',
name: 'serviceAlarm',
component: serviceAlarm
},
{
path: '/configurationManagement/serviceIP',
name: 'serviceIP',
component: serviceIP
}
]
},
{
path: '/dashboard',
name: 'dashboard',
component: dashboard
},
{
path: '/topology',
name: 'topology',
component: topology
},
{
path: '/topology2',
name: 'topology2',
component: topology2
},
{
path: '/trace',
name: 'trace',
component: trace
},
{
path: '/performanceAnalysis',
name: 'performanceAnalysis',
component: performanceAnalysis
},
{
path: '/alarm',
name: 'alarm',
component: alarm,
redirect: '/alarm/alarm_yw',
children: [
{
path: '/alarm/alarm_link',
name: 'alarmLink',
component: alarmLink
},
{
path: '/alarm/alarm_yw',
name: 'alarmYw',
component: alarmYw
}
]
},
{
path: '/serviceMonitor',
name: 'serviceMonitor',
component: serviceMonitor
},
{
path: '/user',
name: 'user',
component: user
}
]
}
]
})
export default router
module.exports = {
title: '链路追踪系统',
/**
* @type {boolean} true | false
* @description Whether fix the header
*/
fixedHeader: true,
/**
* @type {boolean} true | false
* @description Whether show the logo in sidebar
*/
sidebarLogo: true
}
const getters = {
sidebar: state => state.app.sidebar,
token: state => state.user.token,
role: state => state.user.role,
sysActiveFlag: state => state.user.sysActiveFlag,
openItem: state => state.user.openItem,
name: state => state.user.name,
userInfoMsg: state => state.user.userInfo,
ReportSerialNumber: state => state.user.ReportSerialNumber,
searchValue: state => state.user.searchValue
}
export default getters
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import app from './modules/app'
import settings from './modules/settings'
import user from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
app,
settings,
user
},
getters
})
export default store
import Cookies from 'js-cookie'
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
device: 'desktop'
}
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
}
}
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
import defaultSettings from '@/settings'
const { showSettings, fixedHeader, sidebarLogo } = defaultSettings
const state = {
showSettings: showSettings,
fixedHeader: fixedHeader,
sidebarLogo: sidebarLogo
}
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
}
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken ,setIsCertification,removeIsCertification} from '@/utils/auth'
const getDefaultState = () => {
return {
token: getToken(),
name: '',
role: 0,
openItem: [],
userInfo: '',
searchValue:'first',
}
}
const state = getDefaultState()
const mutations = {
RESET_STATE: (state) => {
Object.assign(state, getDefaultState())
},
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_ROLE: (state, role) => {
state.role = role
},
SET_OPENITEM: (state, openItem) => {
state.openItem = openItem
},
SET_SEARCHVALUE: (state, searchValue) => {
state.searchValue = searchValue
},
SET_ACTIVEFLAG: (state, sysActiveFlag) => {
state.sysActiveFlag = sysActiveFlag
},
SET_USERINFO: (state, userInfo) => {
state.userInfo = userInfo
}
}
const actions = {
// user login
login({ commit }, userInfo) {
const { username, password, isCertification} = userInfo
return new Promise((resolve, reject) => {
var token ={
username:username,
password:password,
isCertification:isCertification
}
commit('SET_TOKEN', token)
setIsCertification(isCertification)
setToken(token)
resolve()
})
},
active({ commit },data) {
return new Promise((resolve, reject) => {
commit('SET_ACTIVEFLAG', data)
resolve()
})
},
setUserInfo({ commit },data) {
return new Promise((resolve, reject) => {
commit('SET_USERINFO', data)
resolve()
})
},
setOpenList({ commit },data) {
return new Promise((resolve, reject) => {
commit('SET_OPENITEM', data)
resolve()
})
},
setSearchValue({ commit },data) {
return new Promise((resolve, reject) => {
commit('SET_SEARCHVALUE', data)
resolve()
})
},
// user logout
logout({ commit, state }) {
return new Promise((resolve, reject) => {
removeToken() // must remove token first
commit('RESET_STATE')
resolve()
})
},
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
removeToken() // must remove token first
commit('RESET_STATE')
resolve()
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
import Cookies from 'js-cookie'
const TokenKey = 'linktracesystem'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
import defaultSettings from '@/settings'
const title = defaultSettings.title || 'Vue Admin Template'
export default function getPageTitle(pageTitle) {
if (pageTitle) {
return `${pageTitle} - ${title}`
}
return `${title}`
}
/**
* Created by PanJiaChen on 16/11/18.
*/
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string | null}
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
return value.toString().padStart(2, '0')
})
return time_str
}
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function formatDate(date, fmt) {
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
}
const o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
}
for (const k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
const str = o[k] + ''
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str))
}
}
return fmt
}
function padLeftZero(str) {
return ('00' + str).substr(str.length)
}
/**
* @param {string} url
* @returns {Object}
*/
export function param2Obj(url) {
const search = url.split('?')[1]
if (!search) {
return {}
}
return JSON.parse(
'{"' +
decodeURIComponent(search)
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"')
.replace(/\+/g, ' ') +
'"}'
)
}
import axios from 'axios'
import { getToken, removeToken } from "./auth"
// create an axios
const request = axios.create({
baseURL: '', // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 10000 * 3 // request timeout
})
request.interceptors.request.use(config => {
config.headers.token = getToken()
return config
})
request.interceptors.response.use(response => {
if (response.data.code === '510') {
removeToken()
}
return response
})
export default request
export function formatDate(date, fmt) {
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
}
const o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
}
for (const k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
const str = o[k] + ''
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str))
}
}
return fmt
}
function padLeftZero(str) {
return ('00' + str).substr(str.length)
}
/**
* 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
}
<template>
<div :style="[{ minHeight: clientHeight + 'px' },{background: '#070836' },{color: '#ffffff'}]">
<!-- 二级菜单 -->
<a-row class="secondaryMenu">
<!-- 二级菜单的小标签 -->
<router-link to="/alarm/alarm_yw">
<div class="secondaryMenu_single" @click="clickYwAlarm()">
<div :class="alarmYwSelect?'secondaryMenu_single_selected':'secondaryMenu_single_select'"></div>
<span
:style="[{'cursor': alarmYwSelect ? 'default':'pointer'},{'color': alarmYwSelect ? 'white':'#A7AEBB'},{marginRight:'7px'}]">业务告警</span>
</div>
</router-link>
<router-link to="/alarm/alarm_link">
<div class="secondaryMenu_single" @click="clickLinkAlarm()">
<div :class="alarmLinkSelect?'secondaryMenu_single_selected':'secondaryMenu_single_select'"></div>
<span
:style="[{'cursor': alarmLinkSelect ? 'default':'pointer'},{'color': alarmLinkSelect ? 'white':'#A7AEBB'},{marginRight:'7px'}]">链路告警</span>
</div>
</router-link>
</a-row>
<a-layout-content>
<a-config-provider :locale="locale">
<router-view></router-view>
</a-config-provider>
</a-layout-content>
</div>
</template>
<script>
import $ from 'jquery';
import zhCN from "ant-design-vue/lib/locale-provider/zh_CN";
const clientHeight = $(window).height() - 64
export default {
name: 'alarm',
data() {
return {
locale: zhCN,
clientHeight,
alarmYwSelect: true,// 业务告警选中标志
alarmLinkSelect: false,// 链路告警选中标志
}
},
methods:{
// 点击业务告警
clickYwAlarm(){
this.alarmYwSelect = true
this.alarmLinkSelect = false
},
// 点击链路告警
clickLinkAlarm(){
this.alarmYwSelect = false
this.alarmLinkSelect = true
},
},
mounted(){
var routerPath = this.$route.path.split('/');
var currentPage = routerPath[routerPath.length-1];
if(currentPage=='alarm_link'){
this.clickLinkAlarm();
}else{
this.clickYwAlarm();
}
}
}
</script>
<template>
<div>
<!-- 输入框 -->
<a-row class="inputDivCss">
<!--交易汇聚 选中输入框-->
<a-form-model ref="alarmInfo" :model="alarmInfo" style="margin:0 10px;" layout="inline">
<!--告警类型-->
<a-form-model-item>
<span style="color:white!important;">告警类型:</span>
</a-form-model-item>
<a-form-model-item>
<a-select mode="multiple" placeholder="请选择告警类型" :value="selectedItems"
style="min-width: 200px;max-width:600px" @change="alarmTypeChange">
<a-select-option v-for="(item,index) in alarmTypeList" :value="item.descName">
{{ item.descName }}
</a-select-option>
</a-select>
</a-form-model-item>
<!--开始时间-->
<a-form-model-item>
<span style="color:white!important;">时间:</span>
</a-form-model-item>
<a-form-model-item>
<a-range-picker :value="[defaultStartTime,defaultEndTime]" :format="dateFormat" show-time @change="timeChange"/>
</a-form-model-item>
<a-form-model-item>
<a-button type="primary" @click="clickSearchBtn"> 查 询</a-button>
</a-form-model-item>
</a-form-model>
</a-row>
<a-row style="margin-top:20px;">
<a-col :span="22" :offset="1">
<a-spin :spinning="isLoading" :indicator="indicator">
<a-table :locale="locale" :columns="alarmInfoColumns" :data-source="alarmInfoData"
size="large" bordered :pagination="false"
:customHeaderRow="setTableHead" :rowClassName="setTableContent">
</a-table>
</a-spin>
</a-col>
</a-row>
<a-pagination v-show="alarmInfoData.length>1" showQuickJumper v-model="pageParams.currentPage" :pageSizeOptions="pageSizeOptionsPage"
:total="totalData" :show-total="(totalData, range) => `${totalData} 条`" show-size-changer
:page-size="pageParams.pageSize" @change="changePage" @showSizeChange="showSizeChangePage"
style="margin: 20px 0;text-align: center;color:white;">
</a-pagination>
</div>
</template>
<script>
import { selectLinkAlarm } from '@/api/alarm.js'
import { formatDate } from '@/utils/time.js'
import moment from 'moment';
const alarmInfoColumns = [
//编号;
{
title: '编号',
align: 'center',
width: '8%',
customRender: (text, record, index) => `${index + 1}`
},
{
title: '告警名称',
align: 'center',
width: '10%',
dataIndex: 'attribute_name'
},
{
title: '时间',
align: 'center',
width: '10%',
dataIndex: 'timestamp'
},
{
title: '实时数',
align: 'center',
width: '5%',
dataIndex: 'attribute_data'
},
//告警类型;
{
title: '限制数',
align: 'center',
width: '13%',
dataIndex: 'alarm_data'
},
//告警时间;
{
title: '请求发起端IP',
align: 'center',
width: '13%',
dataIndex: 'ip_from'
},
//告警阈值;
{
title: '请求发起端名称',
align: 'center',
width: '13%',
dataIndex: 'server_name'
},
//当前值;
{
title: '请求接收端IP',
align: 'center',
width: '13%',
dataIndex: 'ip_to'
},
{
title: '请求接收端名称',
align: 'center',
width: '13%',
dataIndex: 'client_name'
}
]
const alarmInfoData = []
const alarmTypeList = [
{ businessType: 'auth', alarmType: 0, descName: '认证机器告警' },
{ businessType: 'auth', alarmType: 1, descName: '认证链路告警' },
// { businessType: 'kaitong', alarmType: 0, descName: '开通机器告警' },
// { businessType: 'kaitong', alarmType: 1, descName: '开通链路告警' },
{ businessType: 'qrcode', alarmType: 0, descName: '二维码机器告警' },
{ businessType: 'qrcode', alarmType: 1, descName: '二维码链路告警' },
// { businessType: 'churujing', alarmType: 0, descName: '出入境机器告警' },
// { businessType: 'churujing', alarmType: 1, descName: '出入境链路告警' }
]
const alarmInfo = {
alarmTpyeList: {
auth: [],
kaitong: [],
qrcode: [],
churujing: []
},//
startTime: '',// 开始时间
endTime: '',// 结束时间
currentPage: '1',// 当前页
pageCount: '20'// 每页条数
}
export default {
data() {
return {
indicator: <a-icon type="sync" style="font-size: 50px;color:green" spin />,
defaultStartTime: '',defaultEndTime: '',
locale: {
emptyText: '暂无数据'
},
isLoading: true,
dateFormat: 'YYYY-MM-DD HH:mm',
pageParams: {
currentPage: 1,
pageSize: 10
},
pageSizeOptionsPage: ['10', '20', '30', '40', '50'],
totalData: 0,
alarmInfo,
selectedItems: [],
alarmTypeList,
alarmInfoColumns,
alarmInfoData
}
},
methods: {
moment,
// 告警类型
alarmTypeChange(selectedItems) {
this.alarmInfo.alarmTpyeList.auth = []
this.alarmInfo.alarmTpyeList.kaitong = []
this.alarmInfo.alarmTpyeList.qrcode = []
this.alarmInfo.alarmTpyeList.churujing = []
this.selectedItems = selectedItems
for (var i = 0; i < selectedItems.length; i++) {
for (var j = 0; j < this.alarmTypeList.length; j++) {
if (this.alarmTypeList[j].descName == selectedItems[i]) {
switch (this.alarmTypeList[j].businessType) {
case 'auth':
this.alarmInfo.alarmTpyeList.auth.push(this.alarmTypeList[j].alarmType)
break
case 'kaitong':
this.alarmInfo.alarmTpyeList.kaitong.push(this.alarmTypeList[j].alarmType)
break
case 'qrcode':
this.alarmInfo.alarmTpyeList.qrcode.push(this.alarmTypeList[j].alarmType)
break
case 'churujing':
this.alarmInfo.alarmTpyeList.churujing.push(this.alarmTypeList[j].alarmType)
break
}
}
}
}
},
// 时间选择触发
timeChange(date, dateString) {
this.defaultStartTime = date[0],
this.defaultEndTime = date[1]
this.alarmInfo.startTime = dateString[0]
this.alarmInfo.endTime = dateString[1]
},
// 点击 查询 按钮;
clickSearchBtn() {
this.isLoading = true
if (this.alarmInfo.startTime == '') {
this.$message.error('时间不能是空')
this.isLoading = false
} else {
this.alarmInfo.currentPage = 1
this.pageParams.currentPage=1
this.alarmInfo.pageCount = this.pageParams.pageSize
// 查询
selectLinkAlarm(this.alarmInfo).then((response) => {
this.isLoading = false
this.totalData = response.data.allCount
this.alarmInfoData = response.data.alarmInfo
})
}
},
// 点击 查询 按钮;
checkPage() {
this.isLoading = true
if (this.alarmInfo.startTime == '') {
this.$message.error('时间不能是空')
this.isLoading = false
} else {
this.alarmInfo.currentPage = this.pageParams.currentPage
this.alarmInfo.pageCount = this.pageParams.pageSize
// 查询
selectLinkAlarm(this.alarmInfo).then((response) => {
this.isLoading = false
this.totalData = response.data.allCount
this.alarmInfoData = response.data.alarmInfo
})
}
},
// 分页
// 点击页码
changePage(val) {
this.pageParams.currentPage = val//给页码赋值;
this.checkPage()
},
// 点击每页条数
showSizeChangePage(current, pageSize) {
this.pageParams.currentPage = 1
this.pageParams.pageSize = pageSize
this.checkPage()
},
//设置table的表头;
setTableHead(record) {
return {
style: {
'background-color': '#97a0ab',
'font-weight': 'bolder',
'font-size': '13px',
'color': '#ffffff'
}
}
},
setTableContent(record) {
return 'tableContent'
}
},
mounted() {
//默认时间;
var endTime = formatDate(new Date(),'yyyy-MM-dd hh:mm');
var beginTime = new Date();
beginTime.setMilliseconds(beginTime.getMilliseconds()-1000*60*5)
this.alarmInfo.startTime = formatDate(beginTime,'yyyy-MM-dd hh:mm');
this.alarmInfo.endTime = endTime;
this.defaultStartTime = moment(beginTime, 'YYYY-MM-DD hh:mm')
this.defaultEndTime = moment(endTime, 'YYYY-MM-DD hh:mm')
this.clickSearchBtn()
}
}
</script>
<style scoped>
</style>
This diff is collapsed.
<template>
<div :style="[{ minHeight: clientHeight + 'px' },{background: '#070836' },{color: '#ffffff'}]">
<!-- 二级菜单 -->
<a-row class="secondaryMenu">
<!-- 二级菜单的小标签 -->
<router-link to="/configurationManagement/serviceAlarm">
<div class="secondaryMenu_single" @click="clickYwAlarmConfig()">
<div :class="ywgjConfigSelect?'secondaryMenu_single_selected':'secondaryMenu_single_select'"></div>
<span
:style="[{'cursor': ywgjConfigSelect ? 'default':'pointer'},{'color': ywgjConfigSelect ? 'white':'#A7AEBB'},{marginRight:'7px'}]">业务告警配置</span>
</div>
</router-link>
<router-link to="/configurationManagement/linkAlarmConfig">
<div class="secondaryMenu_single" @click="clickLinkTraceConfig()">
<div :class="linkTraceConfigSelect?'secondaryMenu_single_selected':'secondaryMenu_single_select'"></div>
<span
:style="[{'cursor': linkTraceConfigSelect ? 'default':'pointer'},{'color': linkTraceConfigSelect ? 'white':'#A7AEBB'},{marginRight:'7px'}]">链路告警配置</span>
</div>
</router-link>
<router-link to="/configurationManagement/serviceIP">
<div class="secondaryMenu_single" @click="clickIPConfig()">
<div :class="linkTraceConfigSelectIP?'secondaryMenu_single_selected':'secondaryMenu_single_select'"></div>
<span
:style="[{'cursor': linkTraceConfigSelectIP ? 'default':'pointer'},{'color': linkTraceConfigSelectIP ? 'white':'#A7AEBB'},{marginRight:'7px'}]">IP告警配置</span>
</div>
</router-link>
</a-row>
<a-layout-content>
<router-view></router-view>
</a-layout-content>
</div>
</template>
<script>
import $ from 'jquery';
const clientHeight = $(window).height() - 64
export default {
name: 'configuration-management',
data(){
return {
clientHeight,
ywgjConfigSelect: true,//业务告警配置选中标志
linkTraceConfigSelect: false,//链路告警配置选中标志
linkTraceConfigSelectIP:false,
}
},
methods:{
//点击业务告警配置选中;
clickYwAlarmConfig: function(){
this.ywgjConfigSelect = true;
this.linkTraceConfigSelect = false;
this.linkTraceConfigSelectIP = false
},
//点击链路告警配置选中;
clickLinkTraceConfig: function(){
this.ywgjConfigSelect = false;
this.linkTraceConfigSelect = true;
this.linkTraceConfigSelectIP = false
},
//点击ip;
clickIPConfig: function(){
this.ywgjConfigSelect = false;
this.linkTraceConfigSelect = false;
this.linkTraceConfigSelectIP=true;
}
},
mounted(){
var routerPath = this.$route.path.split('/');
var currentPage = routerPath[routerPath.length-1];
if(currentPage=='linkAlarmConfig'){
this.clickLinkTraceConfig();
}else if(currentPage=='serviceAlarm'){
this.clickYwAlarmConfig();
}else {
this.clickIPConfig();
}
}
}
</script>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<template>
<div>performanceAnalysis 性能剖析</div>
</template>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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