mirror of
https://github.com/fatedier/frp.git
synced 2024-12-12 09:41:19 +01:00
revert web code (#2215)
This commit is contained in:
parent
b26080589b
commit
ecb6ed9258
Binary file not shown.
@ -1 +1 @@
|
||||
<!doctype html> <html lang=en> <head> <meta charset=utf-8> <title>frp client admin UI</title> <link rel="shortcut icon" href="favicon.ico"></head> <body> <div id=app></div> <script type="text/javascript" src="manifest.js?d2cd6337d30c7b22e836"></script><script type="text/javascript" src="vendor.js?edb271e1d9c81f857840"></script></body> </html>
|
||||
<!doctype html> <html lang=en> <head> <meta charset=utf-8> <title>frp client admin UI</title> <link rel="shortcut icon" href="favicon.ico"></head> <body> <div id=app></div> <script type="text/javascript" src="manifest.js?f30e0e5ff7dbde4611e0"></script><script type="text/javascript" src="vendor.js?a82aed5fb0b844cbdb29"></script></body> </html>
|
@ -1 +1 @@
|
||||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,u){for(var i,a,f,l=0,s=[];l<t.length;l++)a=t[l],o[a]&&s.push(o[a][0]),o[a]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(r&&r(t,c,u);s.length;)s.shift()();if(u)for(l=0;l<u.length;l++)f=n(n.s=u[l]);return f};var t={},o={1:0};n.e=function(e){function r(){i.onerror=i.onload=null,clearTimeout(a);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var u=document.getElementsByTagName("head")[0],i=document.createElement("script");i.type="text/javascript",i.charset="utf-8",i.async=!0,i.timeout=12e4,n.nc&&i.setAttribute("nonce",n.nc),i.src=n.p+""+e+".js?"+{0:"edb271e1d9c81f857840"}[e];var a=setTimeout(r,12e4);return i.onerror=i.onload=r,u.appendChild(i),c},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
|
||||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,u){for(var i,a,f,l=0,s=[];l<t.length;l++)a=t[l],o[a]&&s.push(o[a][0]),o[a]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(r&&r(t,c,u);s.length;)s.shift()();if(u)for(l=0;l<u.length;l++)f=n(n.s=u[l]);return f};var t={},o={1:0};n.e=function(e){function r(){i.onerror=i.onload=null,clearTimeout(a);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var u=document.getElementsByTagName("head")[0],i=document.createElement("script");i.type="text/javascript",i.charset="utf-8",i.async=!0,i.timeout=12e4,n.nc&&i.setAttribute("nonce",n.nc),i.src=n.p+""+e+".js?"+{0:"a82aed5fb0b844cbdb29"}[e];var a=setTimeout(r,12e4);return i.onerror=i.onload=r,u.appendChild(i),c},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
assets/frps/static/535877f50039c0cb49a6196a5b7517cd.woff
Normal file
BIN
assets/frps/static/535877f50039c0cb49a6196a5b7517cd.woff
Normal file
Binary file not shown.
BIN
assets/frps/static/732389ded34cb9c52dd88271f1345af9.ttf
Normal file
BIN
assets/frps/static/732389ded34cb9c52dd88271f1345af9.ttf
Normal file
Binary file not shown.
@ -1 +0,0 @@
|
||||
.el-form-item span{margin-left:15px}.demo-table-expand{font-size:0}.demo-table-expand label{width:90px;color:#99a9bf}.demo-table-expand .el-form-item{margin-right:0;margin-bottom:0;width:50%}body{background-color:#fafafa;margin:0;font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,sans-serif}header{width:100%;height:60px}.header-color{background:#58b7ff}#content{margin-top:20px;padding-right:40px}.brand{color:#fff;background-color:transparent;margin-left:20px;float:left;line-height:25px;font-size:25px;padding:15px 15px;height:30px;text-decoration:none}.source{border:1px solid #eaeefb;border-radius:4px;transition:.2s;padding:24px}.server_info{margin-left:40px;font-size:0}.server_info label{width:150px;color:#99a9bf}.server_info .el-form-item{margin-right:0;margin-bottom:0;width:100%}
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>frps-dashboard</title><link href="css/app.808290ae.css" rel="preload" as="style"><link href="css/chunk-vendors.84bb20f7.css" rel="preload" as="style"><link href="js/app.bb942a48.js" rel="preload" as="script"><link href="js/chunk-vendors.4421b07d.js" rel="preload" as="script"><link href="css/chunk-vendors.84bb20f7.css" rel="stylesheet"><link href="css/app.808290ae.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but frps-dashboard doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.4421b07d.js"></script><script src="js/app.bb942a48.js"></script></body></html>
|
||||
<!doctype html> <html lang=en> <head> <meta charset=utf-8> <title>frps dashboard</title> <link rel="shortcut icon" href="favicon.ico"></head> <body> <div id=app></div> <script type="text/javascript" src="manifest.js?b8b55d8156200869417b"></script><script type="text/javascript" src="vendor.js?3e078a9d741093b909de"></script></body> </html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
assets/frps/static/manifest.js
Normal file
1
assets/frps/static/manifest.js
Normal file
@ -0,0 +1 @@
|
||||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,u,c){for(var i,a,f,l=0,s=[];l<t.length;l++)a=t[l],o[a]&&s.push(o[a][0]),o[a]=0;for(i in u)Object.prototype.hasOwnProperty.call(u,i)&&(e[i]=u[i]);for(r&&r(t,u,c);s.length;)s.shift()();if(c)for(l=0;l<c.length;l++)f=n(n.s=c[l]);return f};var t={},o={1:0};n.e=function(e){function r(){i.onerror=i.onload=null,clearTimeout(a);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var u=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=u;var c=document.getElementsByTagName("head")[0],i=document.createElement("script");i.type="text/javascript",i.charset="utf-8",i.async=!0,i.timeout=12e4,n.nc&&i.setAttribute("nonce",n.nc),i.src=n.p+""+e+".js?"+{0:"3e078a9d741093b909de"}[e];var a=setTimeout(r,12e4);return i.onerror=i.onload=r,c.appendChild(i),u},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
|
1
assets/frps/static/vendor.js
Normal file
1
assets/frps/static/vendor.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
9334
web/frpc/package-lock.json
generated
9334
web/frpc/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
3454
web/frpc/yarn.lock
3454
web/frpc/yarn.lock
File diff suppressed because it is too large
Load Diff
14
web/frps/.babelrc
Normal file
14
web/frps/.babelrc
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"presets": [
|
||||
["es2015", { "modules": false }]
|
||||
],
|
||||
"plugins": [
|
||||
[
|
||||
"component",
|
||||
{
|
||||
"libraryName": "element-ui",
|
||||
"styleLibraryName": "theme-chalk"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
[*.{js,jsx,ts,tsx,vue}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
@ -1,2 +0,0 @@
|
||||
# just a flag
|
||||
ENV = 'development'
|
@ -1,2 +0,0 @@
|
||||
# just a flag
|
||||
ENV = 'production'
|
@ -1,267 +0,0 @@
|
||||
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']
|
||||
}
|
||||
}
|
27
web/frps/.gitignore
vendored
27
web/frps/.gitignore
vendored
@ -1,25 +1,6 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
node_modules/
|
||||
dist/
|
||||
npm-debug.log
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
package-lock.json
|
||||
.vscode/settings.json
|
||||
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"bracketSpacing": true,
|
||||
"printWidth": 160,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"arrowParens": "avoid"
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
.PHONY: dist build
|
||||
|
||||
build: install
|
||||
build:
|
||||
@npm run build
|
||||
|
||||
dev: install
|
||||
@npm run serve
|
||||
|
||||
install:
|
||||
@npm install
|
||||
@npm run dev
|
||||
|
@ -1,25 +0,0 @@
|
||||
# frps
|
||||
|
||||
## Project setup
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
|
||||
```
|
||||
npm run lint
|
||||
```
|
@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
presets: ['@vue/cli-plugin-babel/preset']
|
||||
}
|
@ -4,43 +4,45 @@
|
||||
"author": "fatedier",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
"dev": "webpack-dev-server -d --inline --hot --env.dev",
|
||||
"build": "rimraf dist && webpack -p --progress --hide-modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.7.0",
|
||||
"echarts": "^4.9.0",
|
||||
"element-ui": "^2.14.1",
|
||||
"bootstrap": "^3.3.7",
|
||||
"echarts": "^3.5.0",
|
||||
"element-ui": "^2.3.8",
|
||||
"humanize-plus": "^1.8.2",
|
||||
"vue": "^2.6.12",
|
||||
"vue-router": "^3.4.9",
|
||||
"vuex": "^3.5.1",
|
||||
"whatwg-fetch": "^3.5.0"
|
||||
"vue": "^2.5.16",
|
||||
"vue-resource": "^1.2.1",
|
||||
"vue-router": "^2.3.0",
|
||||
"whatwg-fetch": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.5.9",
|
||||
"@vue/cli-plugin-eslint": "~4.5.9",
|
||||
"@vue/cli-plugin-router": "~4.5.9",
|
||||
"@vue/cli-plugin-vuex": "~4.5.9",
|
||||
"@vue/cli-service": "~4.5.9",
|
||||
"@vue/eslint-config-standard": "^5.1.2",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^7.14.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.1.0",
|
||||
"eslint-plugin-vue": "^7.1.0",
|
||||
"less": "^3.12.2",
|
||||
"less-loader": "^7.1.0",
|
||||
"node-sass": "^5.0.0",
|
||||
"sass-loader": "^10.1.0",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
]
|
||||
"autoprefixer": "^6.6.0",
|
||||
"babel-core": "^6.21.0",
|
||||
"babel-eslint": "^7.1.1",
|
||||
"babel-loader": "^6.4.0",
|
||||
"babel-plugin-component": "^1.1.1",
|
||||
"babel-preset-es2015": "^6.13.2",
|
||||
"css-loader": "^0.27.0",
|
||||
"eslint": "^3.12.2",
|
||||
"eslint-config-enough": "^0.2.2",
|
||||
"eslint-loader": "^1.6.3",
|
||||
"file-loader": "^0.10.1",
|
||||
"html-loader": "^0.4.5",
|
||||
"html-webpack-plugin": "^2.24.1",
|
||||
"less": "^3.0.4",
|
||||
"less-loader": "^4.1.0",
|
||||
"postcss-loader": "^1.3.3",
|
||||
"rimraf": "^2.5.4",
|
||||
"style-loader": "^0.13.2",
|
||||
"url-loader": "^1.0.1",
|
||||
"vue-loader": "^15.0.10",
|
||||
"vue-template-compiler": "^2.1.8",
|
||||
"webpack": "^2.2.0-rc.4",
|
||||
"webpack-dev-server": "^3.1.4"
|
||||
}
|
||||
}
|
||||
|
5
web/frps/postcss.config.js
Normal file
5
web/frps/postcss.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('autoprefixer')()
|
||||
]
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> 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>
|
@ -8,7 +8,7 @@
|
||||
<section>
|
||||
<el-row>
|
||||
<el-col id="side-nav" :xs="24" :md="4">
|
||||
<el-menu default-active="1" mode="vertical" theme="light" router @select="handleSelect">
|
||||
<el-menu default-active="1" mode="vertical" theme="light" router="false" @select="handleSelect">
|
||||
<el-menu-item index="/">Overview</el-menu-item>
|
||||
<el-submenu index="/proxies">
|
||||
<template slot="title">Proxies</template>
|
||||
@ -24,28 +24,21 @@
|
||||
|
||||
<el-col :xs="24" :md="20">
|
||||
<div id="content">
|
||||
<router-view v-if="serverInfo" />
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</section>
|
||||
<footer></footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
serverInfo() {
|
||||
return this.$store.state.serverInfo
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.$store.dispatch('fetchServerInfo')
|
||||
},
|
||||
methods: {
|
||||
handleSelect(key, path) {
|
||||
if (key === '') {
|
||||
window.open('https://github.com/fatedier/frp')
|
||||
if (key == '') {
|
||||
window.open("https://github.com/fatedier/frp")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -65,7 +58,7 @@ header {
|
||||
}
|
||||
|
||||
.header-color {
|
||||
background: #58b7ff;
|
||||
background: #58B7FF;
|
||||
}
|
||||
|
||||
#content {
|
||||
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
@ -44,8 +44,8 @@
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="12">
|
||||
<div id="traffic" style="width: 400px; height: 250px; margin-bottom: 30px" />
|
||||
<div id="proxies" style="width: 400px; height: 250px" />
|
||||
<div id="traffic" style="width: 400px;height:250px;margin-bottom: 30px;"></div>
|
||||
<div id="proxies" style="width: 400px;height:250px;"></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -70,65 +70,71 @@ export default {
|
||||
proxy_counts: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
serverInfo() {
|
||||
return this.$store.state.serverInfo
|
||||
}
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
watch: {
|
||||
'$route': 'fetchData'
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
console.log(!!this.serverInfo, this.serverInfo)
|
||||
if (!this.serverInfo) return
|
||||
|
||||
this.version = this.serverInfo.version
|
||||
this.bind_port = this.serverInfo.bind_port
|
||||
this.bind_udp_port = this.serverInfo.bind_udp_port
|
||||
if (this.bind_udp_port === 0) {
|
||||
this.bind_udp_port = 'disable'
|
||||
fetchData() {
|
||||
fetch('/api/serverinfo', {credentials: 'include'})
|
||||
.then(res => {
|
||||
return res.json()
|
||||
}).then(json => {
|
||||
this.version = json.version
|
||||
this.bind_port = json.bind_port
|
||||
this.bind_udp_port = json.bind_udp_port
|
||||
if (this.bind_udp_port == 0) {
|
||||
this.bind_udp_port = "disable"
|
||||
}
|
||||
this.vhost_http_port = this.serverInfo.vhost_http_port
|
||||
if (this.vhost_http_port === 0) {
|
||||
this.vhost_http_port = 'disable'
|
||||
this.vhost_http_port = json.vhost_http_port
|
||||
if (this.vhost_http_port == 0) {
|
||||
this.vhost_http_port = "disable"
|
||||
}
|
||||
this.vhost_https_port = this.serverInfo.vhost_https_port
|
||||
if (this.vhost_https_port === 0) {
|
||||
this.vhost_https_port = 'disable'
|
||||
this.vhost_https_port = json.vhost_https_port
|
||||
if (this.vhost_https_port == 0) {
|
||||
this.vhost_https_port = "disable"
|
||||
}
|
||||
this.subdomain_host = this.serverInfo.subdomain_host
|
||||
this.max_pool_count = this.serverInfo.max_pool_count
|
||||
this.max_ports_per_client = this.serverInfo.max_ports_per_client
|
||||
if (this.max_ports_per_client === 0) {
|
||||
this.max_ports_per_client = 'no limit'
|
||||
this.subdomain_host = json.subdomain_host
|
||||
this.max_pool_count = json.max_pool_count
|
||||
this.max_ports_per_client = json.max_ports_per_client
|
||||
if (this.max_ports_per_client == 0) {
|
||||
this.max_ports_per_client = "no limit"
|
||||
}
|
||||
this.heart_beat_timeout = this.serverInfo.heart_beat_timeout
|
||||
this.client_counts = this.serverInfo.client_counts
|
||||
this.cur_conns = this.serverInfo.cur_conns
|
||||
this.heart_beat_timeout = json.heart_beat_timeout
|
||||
this.client_counts = json.client_counts
|
||||
this.cur_conns = json.cur_conns
|
||||
this.proxy_counts = 0
|
||||
if (this.serverInfo.proxy_type_count != null) {
|
||||
if (this.serverInfo.proxy_type_count.tcp != null) {
|
||||
this.proxy_counts += this.serverInfo.proxy_type_count.tcp
|
||||
if (json.proxy_type_count != null) {
|
||||
if (json.proxy_type_count.tcp != null) {
|
||||
this.proxy_counts += json.proxy_type_count.tcp
|
||||
}
|
||||
if (this.serverInfo.proxy_type_count.udp != null) {
|
||||
this.proxy_counts += this.serverInfo.proxy_type_count.udp
|
||||
if (json.proxy_type_count.udp != null) {
|
||||
this.proxy_counts += json.proxy_type_count.udp
|
||||
}
|
||||
if (this.serverInfo.proxy_type_count.http != null) {
|
||||
this.proxy_counts += this.serverInfo.proxy_type_count.http
|
||||
if (json.proxy_type_count.http != null) {
|
||||
this.proxy_counts += json.proxy_type_count.http
|
||||
}
|
||||
if (this.serverInfo.proxy_type_count.https != null) {
|
||||
this.proxy_counts += this.serverInfo.proxy_type_count.https
|
||||
if (json.proxy_type_count.https != null) {
|
||||
this.proxy_counts += json.proxy_type_count.https
|
||||
}
|
||||
if (this.serverInfo.proxy_type_count.stcp != null) {
|
||||
this.proxy_counts += this.serverInfo.proxy_type_count.stcp
|
||||
if (json.proxy_type_count.stcp != null) {
|
||||
this.proxy_counts += json.proxy_type_count.stcp
|
||||
}
|
||||
if (this.serverInfo.proxy_type_count.xtcp != null) {
|
||||
this.proxy_counts += this.serverInfo.proxy_type_count.xtcp
|
||||
if (json.proxy_type_count.xtcp != null) {
|
||||
this.proxy_counts += json.proxy_type_count.xtcp
|
||||
}
|
||||
}
|
||||
DrawTrafficChart('traffic', this.serverInfo.total_traffic_in, this.serverInfo.total_traffic_out)
|
||||
DrawProxyChart('proxies', this.serverInfo)
|
||||
DrawTrafficChart('traffic', json.total_traffic_in, json.total_traffic_out)
|
||||
DrawProxyChart('proxies', json)
|
||||
}).catch( err => {
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: 'Get server info from frps failed!',
|
||||
type: 'warning'
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,7 +144,7 @@ export default {
|
||||
.source {
|
||||
border: 1px solid #eaeefb;
|
||||
border-radius: 4px;
|
||||
transition: 0.2s;
|
||||
transition: .2s;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,13 @@
|
||||
<el-table :data="proxies" :default-sort="{prop: 'name', order: 'ascending'}" style="width: 100%">
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="props">
|
||||
<el-popover ref="popover4" placement="right" width="600" style="margin-left: 0px" trigger="click">
|
||||
<my-traffic-chart :proxy-name="props.row.name" />
|
||||
<el-popover
|
||||
ref="popover4"
|
||||
placement="right"
|
||||
width="600"
|
||||
style="margin-left:0px"
|
||||
trigger="click">
|
||||
<my-traffic-chart :proxy_name="props.row.name"></my-traffic-chart>
|
||||
</el-popover>
|
||||
|
||||
<el-button v-popover:popover4 type="primary" size="small" icon="view" style="margin-bottom:10px">Traffic Statistics</el-button>
|
||||
@ -43,15 +48,40 @@
|
||||
</el-form>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Name" prop="name" sortable />
|
||||
<el-table-column label="Port" prop="port" sortable />
|
||||
<el-table-column label="Connections" prop="conns" sortable />
|
||||
<el-table-column label="Traffic In" prop="traffic_in" :formatter="formatTrafficIn" sortable />
|
||||
<el-table-column label="Traffic Out" prop="traffic_out" :formatter="formatTrafficOut" sortable />
|
||||
<el-table-column label="status" prop="status" sortable>
|
||||
<el-table-column
|
||||
label="Name"
|
||||
prop="name"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Port"
|
||||
prop="port"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Connections"
|
||||
prop="conns"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic In"
|
||||
prop="traffic_in"
|
||||
:formatter="formatTrafficIn"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic Out"
|
||||
prop="traffic_out"
|
||||
:formatter="formatTrafficOut"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="status"
|
||||
prop="status"
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.status === 'online'" type="success">{{ scope.row.status }}</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="success" v-if="scope.row.status === 'online'">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="danger" v-else>{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -59,27 +89,24 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Humanize from 'humanize-plus'
|
||||
import Humanize from 'humanize-plus';
|
||||
import Traffic from './Traffic.vue'
|
||||
import { HttpProxy } from '../utils/proxy.js'
|
||||
import {
|
||||
HttpProxy
|
||||
} from '../utils/proxy.js'
|
||||
export default {
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
proxies: [],
|
||||
vhost_http_port: '',
|
||||
subdomain_host: ''
|
||||
proxies: null,
|
||||
vhost_http_port: "",
|
||||
subdomain_host: ""
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
serverInfo() {
|
||||
return this.$store.state.serverInfo
|
||||
}
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
watch: {
|
||||
'$route': 'fetchData'
|
||||
},
|
||||
methods: {
|
||||
formatTrafficIn(row, column) {
|
||||
@ -88,20 +115,34 @@ export default {
|
||||
formatTrafficOut(row, column) {
|
||||
return Humanize.fileSize(row.traffic_out)
|
||||
},
|
||||
async initData() {
|
||||
if (!this.serverInfo) return
|
||||
this.vhost_http_port = this.serverInfo.vhost_http_port
|
||||
this.subdomain_host = this.serverInfo.subdomain_host
|
||||
if (this.vhost_http_port == null || this.vhost_http_port === 0) return
|
||||
|
||||
const json = await this.$fetch('proxy/http')
|
||||
if (!json) return
|
||||
|
||||
this.proxies = []
|
||||
for (const proxyStats of json.proxies) {
|
||||
fetchData() {
|
||||
fetch('/api/serverinfo', {credentials: 'include'})
|
||||
.then(res => {
|
||||
return res.json()
|
||||
}).then(json => {
|
||||
this.vhost_http_port = json.vhost_http_port
|
||||
this.subdomain_host = json.subdomain_host
|
||||
if (this.vhost_http_port == null || this.vhost_http_port == 0) {
|
||||
return
|
||||
} else {
|
||||
fetch('/api/proxy/http', {credentials: 'include'})
|
||||
.then(res => {
|
||||
return res.json()
|
||||
}).then(json => {
|
||||
this.proxies = new Array()
|
||||
for (let proxyStats of json.proxies) {
|
||||
this.proxies.push(new HttpProxy(proxyStats, this.vhost_http_port, this.subdomain_host))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
@ -3,8 +3,13 @@
|
||||
<el-table :data="proxies" :default-sort="{prop: 'name', order: 'ascending'}" style="width: 100%">
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="props">
|
||||
<el-popover ref="popover4" placement="right" width="600" style="margin-left: 0px" trigger="click">
|
||||
<my-traffic-chart :proxy-name="props.row.name" />
|
||||
<el-popover
|
||||
ref="popover4"
|
||||
placement="right"
|
||||
width="600"
|
||||
style="margin-left:0px"
|
||||
trigger="click">
|
||||
<my-traffic-chart :proxy_name="props.row.name"></my-traffic-chart>
|
||||
</el-popover>
|
||||
|
||||
<el-button v-popover:popover4 type="primary" size="small" icon="view" style="margin-bottom:10px">Traffic Statistics</el-button>
|
||||
@ -37,43 +42,66 @@
|
||||
</el-form>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Name" prop="name" sortable />
|
||||
<el-table-column label="Port" prop="port" sortable />
|
||||
<el-table-column label="Connections" prop="conns" sortable />
|
||||
<el-table-column label="Traffic In" prop="traffic_in" :formatter="formatTrafficIn" sortable />
|
||||
<el-table-column label="Traffic Out" prop="traffic_out" :formatter="formatTrafficOut" sortable />
|
||||
<el-table-column label="status" prop="status" sortable>
|
||||
<el-table-column
|
||||
label="Name"
|
||||
prop="name"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Port"
|
||||
prop="port"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Connections"
|
||||
prop="conns"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic In"
|
||||
prop="traffic_in"
|
||||
:formatter="formatTrafficIn"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic Out"
|
||||
prop="traffic_out"
|
||||
:formatter="formatTrafficOut"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="status"
|
||||
prop="status"
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.status === 'online'" type="success">{{ scope.row.status }}</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="success" v-if="scope.row.status === 'online'">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="danger" v-else>{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Humanize from 'humanize-plus'
|
||||
import Humanize from 'humanize-plus';
|
||||
import Traffic from './Traffic.vue'
|
||||
import { HttpsProxy } from '../utils/proxy.js'
|
||||
import {
|
||||
HttpsProxy
|
||||
} from '../utils/proxy.js'
|
||||
export default {
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
proxies: [],
|
||||
proxies: null,
|
||||
vhost_https_port: '',
|
||||
subdomain_host: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
serverInfo() {
|
||||
return this.$store.state.serverInfo
|
||||
}
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
watch: {
|
||||
'$route': 'fetchData'
|
||||
},
|
||||
methods: {
|
||||
formatTrafficIn(row, column) {
|
||||
@ -82,21 +110,34 @@ export default {
|
||||
formatTrafficOut(row, column) {
|
||||
return Humanize.fileSize(row.traffic_out)
|
||||
},
|
||||
async initData() {
|
||||
if (!this.serverInfo) return
|
||||
|
||||
this.vhost_https_port = this.serverInfo.vhost_https_port
|
||||
this.subdomain_host = this.serverInfo.subdomain_host
|
||||
if (this.vhost_https_port == null || this.vhost_https_port === 0) return
|
||||
|
||||
const json = await this.$fetch('proxy/https')
|
||||
if (!json) return
|
||||
|
||||
this.proxies = []
|
||||
for (const proxyStats of json.proxies) {
|
||||
fetchData() {
|
||||
fetch('/api/serverinfo', {credentials: 'include'})
|
||||
.then(res => {
|
||||
return res.json()
|
||||
}).then(json => {
|
||||
this.vhost_https_port = json.vhost_https_port
|
||||
this.subdomain_host = json.subdomain_host
|
||||
if (this.vhost_https_port == null || this.vhost_https_port == 0) {
|
||||
return
|
||||
} else {
|
||||
fetch('/api/proxy/https', {credentials: 'include'})
|
||||
.then(res => {
|
||||
return res.json()
|
||||
}).then(json => {
|
||||
this.proxies = new Array()
|
||||
for (let proxyStats of json.proxies) {
|
||||
this.proxies.push(new HttpsProxy(proxyStats, this.vhost_https_port, this.subdomain_host))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
@ -3,13 +3,16 @@
|
||||
<el-table :data="proxies" :default-sort="{prop: 'name', order: 'ascending'}" style="width: 100%">
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="props">
|
||||
<el-popover ref="popover4" placement="right" width="600" style="margin-left: 0px" trigger="click">
|
||||
<my-traffic-chart :proxy-name="props.row.name" />
|
||||
<el-popover
|
||||
ref="popover4"
|
||||
placement="right"
|
||||
width="600"
|
||||
style="margin-left:0px"
|
||||
trigger="click">
|
||||
<my-traffic-chart :proxy_name="props.row.name"></my-traffic-chart>
|
||||
</el-popover>
|
||||
|
||||
<el-button v-popover:popover4 type="primary" size="small" icon="view" :name="props.row.name" style="margin-bottom: 10px" @click="fetchData2">
|
||||
Traffic Statistics
|
||||
</el-button>
|
||||
<el-button v-popover:popover4 type="primary" size="small" icon="view" :name="props.row.name" style="margin-bottom:10px" @click="fetchData2">Traffic Statistics</el-button>
|
||||
|
||||
<el-form label-position="left" inline class="demo-table-expand">
|
||||
<el-form-item label="Name">
|
||||
@ -33,14 +36,35 @@
|
||||
</el-form>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Name" prop="name" sortable />
|
||||
<el-table-column label="Connections" prop="conns" sortable />
|
||||
<el-table-column label="Traffic In" prop="traffic_in" :formatter="formatTrafficIn" sortable />
|
||||
<el-table-column label="Traffic Out" prop="traffic_out" :formatter="formatTrafficOut" sortable />
|
||||
<el-table-column label="status" prop="status" sortable>
|
||||
<el-table-column
|
||||
label="Name"
|
||||
prop="name"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Connections"
|
||||
prop="conns"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic In"
|
||||
prop="traffic_in"
|
||||
:formatter="formatTrafficIn"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic Out"
|
||||
prop="traffic_out"
|
||||
:formatter="formatTrafficOut"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="status"
|
||||
prop="status"
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.status === 'online'" type="success">{{ scope.row.status }}</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="success" v-if="scope.row.status === 'online'">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="danger" v-else>{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -52,16 +76,16 @@ import Humanize from 'humanize-plus'
|
||||
import Traffic from './Traffic.vue'
|
||||
import { StcpProxy } from '../utils/proxy.js'
|
||||
export default {
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
proxies: []
|
||||
proxies: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
'$route': 'fetchData'
|
||||
},
|
||||
methods: {
|
||||
formatTrafficIn(row, column) {
|
||||
@ -70,15 +94,20 @@ export default {
|
||||
formatTrafficOut(row, column) {
|
||||
return Humanize.fileSize(row.traffic_out)
|
||||
},
|
||||
async initData() {
|
||||
const json = await this.$fetch('proxy/stcp')
|
||||
if (!json) return
|
||||
|
||||
this.proxies = []
|
||||
for (const proxyStats of json.proxies) {
|
||||
fetchData() {
|
||||
fetch('/api/proxy/stcp', {credentials: 'include'})
|
||||
.then(res => {
|
||||
return res.json()
|
||||
}).then(json => {
|
||||
this.proxies = new Array()
|
||||
for (let proxyStats of json.proxies) {
|
||||
this.proxies.push(new StcpProxy(proxyStats))
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -3,14 +3,17 @@
|
||||
<el-table :data="proxies" :default-sort="{prop: 'name', order: 'ascending'}" style="width: 100%">
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="props">
|
||||
<el-popover placement="right" width="600" style="margin-left: 0px" trigger="click">
|
||||
<my-traffic-chart :proxy-name="props.row.name" />
|
||||
|
||||
<el-button slot="reference" type="primary" size="small" icon="view" :name="props.row.name" style="margin-bottom: 10px">
|
||||
Traffic Statistics
|
||||
</el-button>
|
||||
<el-popover
|
||||
ref="popover4"
|
||||
placement="right"
|
||||
width="600"
|
||||
style="margin-left:0px"
|
||||
trigger="click">
|
||||
<my-traffic-chart :proxy_name="props.row.name"></my-traffic-chart>
|
||||
</el-popover>
|
||||
|
||||
<el-button v-popover:popover4 type="primary" size="small" icon="view" :name="props.row.name" style="margin-bottom:10px" @click="fetchData2">Traffic Statistics</el-button>
|
||||
|
||||
<el-form label-position="left" inline class="demo-table-expand">
|
||||
<el-form-item label="Name">
|
||||
<span>{{ props.row.name }}</span>
|
||||
@ -36,15 +39,40 @@
|
||||
</el-form>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Name" prop="name" sortable />
|
||||
<el-table-column label="Port" prop="port" sortable />
|
||||
<el-table-column label="Connections" prop="conns" sortable />
|
||||
<el-table-column label="Traffic In" prop="traffic_in" :formatter="formatTrafficIn" sortable />
|
||||
<el-table-column label="Traffic Out" prop="traffic_out" :formatter="formatTrafficOut" sortable />
|
||||
<el-table-column label="status" prop="status" sortable>
|
||||
<el-table-column
|
||||
label="Name"
|
||||
prop="name"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Port"
|
||||
prop="port"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Connections"
|
||||
prop="conns"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic In"
|
||||
prop="traffic_in"
|
||||
:formatter="formatTrafficIn"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic Out"
|
||||
prop="traffic_out"
|
||||
:formatter="formatTrafficOut"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="status"
|
||||
prop="status"
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.status === 'online'" type="success">{{ scope.row.status }}</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="success" v-if="scope.row.status === 'online'">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="danger" v-else>{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -56,16 +84,16 @@ import Humanize from 'humanize-plus'
|
||||
import Traffic from './Traffic.vue'
|
||||
import { TcpProxy } from '../utils/proxy.js'
|
||||
export default {
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
proxies: []
|
||||
proxies: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
'$route': 'fetchData'
|
||||
},
|
||||
methods: {
|
||||
formatTrafficIn(row, column) {
|
||||
@ -74,15 +102,20 @@ export default {
|
||||
formatTrafficOut(row, column) {
|
||||
return Humanize.fileSize(row.traffic_out)
|
||||
},
|
||||
async initData() {
|
||||
const json = await this.$fetch('proxy/tcp')
|
||||
if (!json) return
|
||||
|
||||
this.proxies = []
|
||||
for (const proxyStats of json.proxies) {
|
||||
fetchData() {
|
||||
fetch('/api/proxy/tcp', {credentials: 'include'})
|
||||
.then(res => {
|
||||
return res.json()
|
||||
}).then(json => {
|
||||
this.proxies = new Array()
|
||||
for (let proxyStats of json.proxies) {
|
||||
this.proxies.push(new TcpProxy(proxyStats))
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -3,8 +3,13 @@
|
||||
<el-table :data="proxies" :default-sort="{prop: 'name', order: 'ascending'}" style="width: 100%">
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="props">
|
||||
<el-popover ref="popover4" placement="right" width="600" style="margin-left: 0px" trigger="click">
|
||||
<my-traffic-chart :proxy-name="props.row.name" />
|
||||
<el-popover
|
||||
ref="popover4"
|
||||
placement="right"
|
||||
width="600"
|
||||
style="margin-left:0px"
|
||||
trigger="click">
|
||||
<my-traffic-chart :proxy_name="props.row.name"></my-traffic-chart>
|
||||
</el-popover>
|
||||
|
||||
<el-button v-popover:popover4 type="primary" size="small" icon="view" style="margin-bottom:10px">Traffic Statistics</el-button>
|
||||
@ -34,15 +39,40 @@
|
||||
</el-form>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Name" prop="name" sortable />
|
||||
<el-table-column label="Port" prop="port" sortable />
|
||||
<el-table-column label="Connections" prop="conns" sortable />
|
||||
<el-table-column label="Traffic In" prop="traffic_in" :formatter="formatTrafficIn" sortable />
|
||||
<el-table-column label="Traffic Out" prop="traffic_out" :formatter="formatTrafficOut" sortable />
|
||||
<el-table-column label="status" prop="status" sortable>
|
||||
<el-table-column
|
||||
label="Name"
|
||||
prop="name"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Port"
|
||||
prop="port"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Connections"
|
||||
prop="conns"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic In"
|
||||
prop="traffic_in"
|
||||
:formatter="formatTrafficIn"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Traffic Out"
|
||||
prop="traffic_out"
|
||||
:formatter="formatTrafficOut"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="status"
|
||||
prop="status"
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.status === 'online'" type="success">{{ scope.row.status }}</el-tag>
|
||||
<el-tag v-else type="danger">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="success" v-if="scope.row.status === 'online'">{{ scope.row.status }}</el-tag>
|
||||
<el-tag type="danger" v-else>{{ scope.row.status }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -50,20 +80,22 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Humanize from 'humanize-plus'
|
||||
import Humanize from 'humanize-plus';
|
||||
import Traffic from './Traffic.vue'
|
||||
import { UdpProxy } from '../utils/proxy.js'
|
||||
import {
|
||||
UdpProxy
|
||||
} from '../utils/proxy.js'
|
||||
export default {
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
proxies: []
|
||||
proxies: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
'$route': 'fetchData'
|
||||
},
|
||||
methods: {
|
||||
formatTrafficIn(row, column) {
|
||||
@ -72,16 +104,23 @@ export default {
|
||||
formatTrafficOut(row, column) {
|
||||
return Humanize.fileSize(row.traffic_out)
|
||||
},
|
||||
async initData() {
|
||||
const json = await this.$fetch('proxy/udp')
|
||||
if (!json) return
|
||||
|
||||
this.proxies = []
|
||||
for (const proxyStats of json.proxies) {
|
||||
fetchData() {
|
||||
fetch('/api/proxy/udp', {credentials: 'include'})
|
||||
.then(res => {
|
||||
return res.json()
|
||||
}).then(json => {
|
||||
this.proxies = new Array()
|
||||
for (let proxyStats of json.proxies) {
|
||||
this.proxies.push(new UdpProxy(proxyStats))
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'my-traffic-chart': Traffic
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
@ -1,26 +1,36 @@
|
||||
<template>
|
||||
<div :id="proxyName" style="width: 600px; height: 400px" />
|
||||
<div :id="proxy_name" style="width: 600px;height:400px;"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {DrawProxyTrafficChart} from '../utils/chart.js'
|
||||
export default {
|
||||
props: {
|
||||
proxyName: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initData()
|
||||
props: ['proxy_name'],
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
//watch: {
|
||||
//'$route': 'fetchData'
|
||||
//},
|
||||
methods: {
|
||||
async initData() {
|
||||
const json = await this.$fetch(`traffic/${this.proxyName}`)
|
||||
if (!json) return
|
||||
|
||||
DrawProxyTrafficChart(this.proxyName, json.traffic_in, json.traffic_out)
|
||||
fetchData() {
|
||||
let url = '/api/traffic/' + this.proxy_name
|
||||
fetch(url, {credentials: 'include'})
|
||||
.then(res => {
|
||||
return res.json()
|
||||
}).then(json => {
|
||||
DrawProxyTrafficChart(this.proxy_name, json.traffic_in, json.traffic_out)
|
||||
}).catch( err => {
|
||||
this.$message({
|
||||
showClose: true,
|
||||
message: 'Get server info from frps failed!' + err,
|
||||
type: 'warning'
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
15
web/frps/src/index.html
Normal file
15
web/frps/src/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>frps dashboard</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!--<script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>-->
|
||||
<!--<script src="//cdn.bootcss.com/echarts/3.4.0/echarts.min.js"></script>-->
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,6 +1,19 @@
|
||||
import Vue from 'vue'
|
||||
//import ElementUI from 'element-ui'
|
||||
import { Button, Form, FormItem, Row, Col, Table, TableColumn, Popover, Menu, Submenu, MenuItem, Tag, Message } from 'element-ui'
|
||||
import {
|
||||
Button,
|
||||
Form,
|
||||
FormItem,
|
||||
Row,
|
||||
Col,
|
||||
Table,
|
||||
TableColumn,
|
||||
Popover,
|
||||
Menu,
|
||||
Submenu,
|
||||
MenuItem,
|
||||
Tag
|
||||
} from 'element-ui'
|
||||
import lang from 'element-ui/lib/locale/lang/en'
|
||||
import locale from 'element-ui/lib/locale'
|
||||
import 'element-ui/lib/theme-chalk/index.css'
|
||||
@ -8,7 +21,6 @@ import './utils/less/custom.less'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from '@/store'
|
||||
import 'whatwg-fetch'
|
||||
|
||||
locale.use(lang)
|
||||
@ -25,15 +37,12 @@ Vue.use(Menu)
|
||||
Vue.use(Submenu)
|
||||
Vue.use(MenuItem)
|
||||
Vue.use(Tag)
|
||||
Vue.prototype.$message = Message
|
||||
|
||||
import fetch from '@/utils/fetch'
|
||||
Vue.prototype.$fetch = fetch
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
store,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
template: '<App/>',
|
||||
components: { App }
|
||||
})
|
||||
|
@ -10,36 +10,29 @@ import ProxiesStcp from '../components/ProxiesStcp.vue'
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
routes: [
|
||||
{
|
||||
routes: [{
|
||||
path: '/',
|
||||
name: 'Overview',
|
||||
component: Overview
|
||||
},
|
||||
{
|
||||
}, {
|
||||
path: '/proxies/tcp',
|
||||
name: 'ProxiesTcp',
|
||||
component: ProxiesTcp
|
||||
},
|
||||
{
|
||||
}, {
|
||||
path: '/proxies/udp',
|
||||
name: 'ProxiesUdp',
|
||||
component: ProxiesUdp
|
||||
},
|
||||
{
|
||||
}, {
|
||||
path: '/proxies/http',
|
||||
name: 'ProxiesHttp',
|
||||
component: ProxiesHttp
|
||||
},
|
||||
{
|
||||
}, {
|
||||
path: '/proxies/https',
|
||||
name: 'ProxiesHttps',
|
||||
component: ProxiesHttps
|
||||
},
|
||||
{
|
||||
}, {
|
||||
path: '/proxies/stcp',
|
||||
name: 'ProxiesStcp',
|
||||
component: ProxiesStcp
|
||||
}
|
||||
]
|
||||
}]
|
||||
})
|
||||
|
@ -1,24 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import fetch from '@/utils/fetch'
|
||||
Vue.use(Vuex)
|
||||
|
||||
const store = new Vuex.Store({
|
||||
state: {
|
||||
serverInfo: null
|
||||
},
|
||||
mutations: {
|
||||
SET_SERVER_INFO(state, serverInfo) {
|
||||
state.serverInfo = serverInfo
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async fetchServerInfo({ commit }) {
|
||||
const json = await fetch('serverinfo')
|
||||
commit('SET_SERVER_INFO', json || null)
|
||||
return json
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default store
|
@ -1,17 +1,17 @@
|
||||
import Humanize from 'humanize-plus'
|
||||
import echarts from 'echarts/lib/echarts'
|
||||
import Humanize from "humanize-plus"
|
||||
import echarts from "echarts/lib/echarts"
|
||||
|
||||
import 'echarts/theme/macarons'
|
||||
import 'echarts/lib/chart/bar'
|
||||
import 'echarts/lib/chart/pie'
|
||||
import 'echarts/lib/component/tooltip'
|
||||
import 'echarts/lib/component/title'
|
||||
import "echarts/theme/macarons"
|
||||
import "echarts/lib/chart/bar"
|
||||
import "echarts/lib/chart/pie"
|
||||
import "echarts/lib/component/tooltip"
|
||||
import "echarts/lib/component/title"
|
||||
|
||||
function DrawTrafficChart(elementId, trafficIn, trafficOut) {
|
||||
const myChart = echarts.init(document.getElementById(elementId), 'macarons')
|
||||
let myChart = echarts.init(document.getElementById(elementId), 'macarons');
|
||||
myChart.showLoading()
|
||||
|
||||
const option = {
|
||||
let option = {
|
||||
title: {
|
||||
text: 'Network Traffic',
|
||||
subtext: 'today',
|
||||
@ -20,24 +20,20 @@ function DrawTrafficChart(elementId, trafficIn, trafficOut) {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: function(v) {
|
||||
return Humanize.fileSize(v.data.value) + ' (' + v.percent + '%)'
|
||||
return Humanize.fileSize(v.data.value) + " (" + v.percent + "%)"
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
series: [{
|
||||
type: 'pie',
|
||||
radius: '55%',
|
||||
center: ['50%', '60%'],
|
||||
data: [
|
||||
{
|
||||
data: [{
|
||||
value: trafficIn,
|
||||
name: 'Traffic In'
|
||||
},
|
||||
{
|
||||
}, {
|
||||
value: trafficOut,
|
||||
name: 'Traffic Out'
|
||||
}
|
||||
],
|
||||
}, ],
|
||||
itemStyle: {
|
||||
emphasis: {
|
||||
shadowBlur: 10,
|
||||
@ -45,10 +41,9 @@ function DrawTrafficChart(elementId, trafficIn, trafficOut) {
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
myChart.setOption(option)
|
||||
}]
|
||||
};
|
||||
myChart.setOption(option);
|
||||
myChart.hideLoading()
|
||||
}
|
||||
|
||||
@ -71,10 +66,10 @@ function DrawProxyChart(elementId, serverInfo) {
|
||||
if (serverInfo.proxy_type_count.xtcp == null) {
|
||||
serverInfo.proxy_type_count.xtcp = 0
|
||||
}
|
||||
const myChart = echarts.init(document.getElementById(elementId), 'macarons')
|
||||
let myChart = echarts.init(document.getElementById(elementId), 'macarons')
|
||||
myChart.showLoading()
|
||||
|
||||
const option = {
|
||||
let option = {
|
||||
title: {
|
||||
text: 'Proxies',
|
||||
subtext: 'now',
|
||||
@ -86,37 +81,29 @@ function DrawProxyChart(elementId, serverInfo) {
|
||||
return v.data.value
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
series: [{
|
||||
type: 'pie',
|
||||
radius: '55%',
|
||||
center: ['50%', '60%'],
|
||||
data: [
|
||||
{
|
||||
data: [{
|
||||
value: serverInfo.proxy_type_count.tcp,
|
||||
name: 'TCP'
|
||||
},
|
||||
{
|
||||
}, {
|
||||
value: serverInfo.proxy_type_count.udp,
|
||||
name: 'UDP'
|
||||
},
|
||||
{
|
||||
}, {
|
||||
value: serverInfo.proxy_type_count.http,
|
||||
name: 'HTTP'
|
||||
},
|
||||
{
|
||||
}, {
|
||||
value: serverInfo.proxy_type_count.https,
|
||||
name: 'HTTPS'
|
||||
},
|
||||
{
|
||||
}, {
|
||||
value: serverInfo.proxy_type_count.stcp,
|
||||
name: 'STCP'
|
||||
},
|
||||
{
|
||||
}, {
|
||||
value: serverInfo.proxy_type_count.xtcp,
|
||||
name: 'XTCP'
|
||||
}
|
||||
],
|
||||
}],
|
||||
itemStyle: {
|
||||
emphasis: {
|
||||
shadowBlur: 10,
|
||||
@ -124,34 +111,33 @@ function DrawProxyChart(elementId, serverInfo) {
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
myChart.setOption(option)
|
||||
}]
|
||||
};
|
||||
myChart.setOption(option);
|
||||
myChart.hideLoading()
|
||||
}
|
||||
|
||||
// 7 days
|
||||
function DrawProxyTrafficChart(elementId, trafficInArr, trafficOutArr) {
|
||||
const params = {
|
||||
let params = {
|
||||
width: '600px',
|
||||
height: '400px'
|
||||
}
|
||||
|
||||
const myChart = echarts.init(document.getElementById(elementId), 'macarons', params)
|
||||
let myChart = echarts.init(document.getElementById(elementId), 'macarons', params);
|
||||
myChart.showLoading()
|
||||
|
||||
trafficInArr = trafficInArr.reverse()
|
||||
trafficOutArr = trafficOutArr.reverse()
|
||||
let now = new Date()
|
||||
now = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 6)
|
||||
const dates = []
|
||||
let dates = new Array()
|
||||
for (let i = 0; i < 7; i++) {
|
||||
dates.push(now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate())
|
||||
now = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1)
|
||||
}
|
||||
|
||||
const option = {
|
||||
let option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
@ -162,9 +148,9 @@ function DrawProxyTrafficChart(elementId, trafficInArr, trafficOutArr) {
|
||||
if (data.length > 0) {
|
||||
html += data[0].name + '<br/>'
|
||||
}
|
||||
for (const v of data) {
|
||||
const colorEl =
|
||||
'<span style="display:inline-block;margin-right:5px;' + 'border-radius:10px;width:9px;height:9px;background-color:' + v.color + '"></span>'
|
||||
for (let v of data) {
|
||||
let colorEl = '<span style="display:inline-block;margin-right:5px;' +
|
||||
'border-radius:10px;width:9px;height:9px;background-color:' + v.color + '"></span>';
|
||||
html += colorEl + v.seriesName + ': ' + Humanize.fileSize(v.value) + '<br/>'
|
||||
}
|
||||
return html
|
||||
@ -179,37 +165,35 @@ function DrawProxyTrafficChart(elementId, trafficInArr, trafficOutArr) {
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
xAxis: [{
|
||||
type: 'category',
|
||||
data: dates
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: function(value) {
|
||||
return Humanize.fileSize(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
}],
|
||||
series: [{
|
||||
name: 'Traffic In',
|
||||
type: 'bar',
|
||||
data: trafficInArr
|
||||
},
|
||||
{
|
||||
}, {
|
||||
|
||||
name: 'Traffic Out',
|
||||
type: 'bar',
|
||||
data: trafficOutArr
|
||||
}
|
||||
]
|
||||
}
|
||||
myChart.setOption(option)
|
||||
}]
|
||||
};
|
||||
myChart.setOption(option);
|
||||
myChart.hideLoading()
|
||||
}
|
||||
|
||||
export { DrawTrafficChart, DrawProxyChart, DrawProxyTrafficChart }
|
||||
export {
|
||||
DrawTrafficChart,
|
||||
DrawProxyChart,
|
||||
DrawProxyTrafficChart
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
import { Message } from 'element-ui'
|
||||
|
||||
export default function(api, init = {}) {
|
||||
return new Promise(resolve => {
|
||||
fetch(`/api/${api}`, Object.assign({ credentials: 'include' }, init))
|
||||
.then(res => {
|
||||
if (res.status < 200 || res.status >= 300) {
|
||||
Message.warning('Get server info from frps failed!')
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
|
||||
resolve(res ? res.json() : undefined)
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message.error(err.message)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
@ -5,8 +5,8 @@ class BaseProxy {
|
||||
this.encryption = proxyStats.conf.use_encryption
|
||||
this.compression = proxyStats.conf.use_compression
|
||||
} else {
|
||||
this.encryption = ''
|
||||
this.compression = ''
|
||||
this.encryption = ""
|
||||
this.compression = ""
|
||||
}
|
||||
this.conns = proxyStats.cur_conns
|
||||
this.traffic_in = proxyStats.today_traffic_in
|
||||
@ -20,13 +20,13 @@ class BaseProxy {
|
||||
class TcpProxy extends BaseProxy {
|
||||
constructor(proxyStats) {
|
||||
super(proxyStats)
|
||||
this.type = 'tcp'
|
||||
this.type = "tcp"
|
||||
if (proxyStats.conf != null) {
|
||||
this.addr = ':' + proxyStats.conf.remote_port
|
||||
this.addr = ":" + proxyStats.conf.remote_port
|
||||
this.port = proxyStats.conf.remote_port
|
||||
} else {
|
||||
this.addr = ''
|
||||
this.port = ''
|
||||
this.addr = ""
|
||||
this.port = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,13 +34,13 @@ class TcpProxy extends BaseProxy {
|
||||
class UdpProxy extends BaseProxy {
|
||||
constructor(proxyStats) {
|
||||
super(proxyStats)
|
||||
this.type = 'udp'
|
||||
this.type = "udp"
|
||||
if (proxyStats.conf != null) {
|
||||
this.addr = ':' + proxyStats.conf.remote_port
|
||||
this.addr = ":" + proxyStats.conf.remote_port
|
||||
this.port = proxyStats.conf.remote_port
|
||||
} else {
|
||||
this.addr = ''
|
||||
this.port = ''
|
||||
this.addr = ""
|
||||
this.port = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,22 +48,22 @@ class UdpProxy extends BaseProxy {
|
||||
class HttpProxy extends BaseProxy {
|
||||
constructor(proxyStats, port, subdomain_host) {
|
||||
super(proxyStats)
|
||||
this.type = 'http'
|
||||
this.type = "http"
|
||||
this.port = port
|
||||
if (proxyStats.conf != null) {
|
||||
this.custom_domains = proxyStats.conf.custom_domains
|
||||
this.host_header_rewrite = proxyStats.conf.host_header_rewrite
|
||||
this.locations = proxyStats.conf.locations
|
||||
if (proxyStats.conf.sub_domain !== '') {
|
||||
this.subdomain = proxyStats.conf.sub_domain + '.' + subdomain_host
|
||||
if (proxyStats.conf.sub_domain != "") {
|
||||
this.subdomain = proxyStats.conf.sub_domain + "." + subdomain_host
|
||||
} else {
|
||||
this.subdomain = ''
|
||||
this.subdomain = ""
|
||||
}
|
||||
} else {
|
||||
this.custom_domains = ''
|
||||
this.host_header_rewrite = ''
|
||||
this.subdomain = ''
|
||||
this.locations = ''
|
||||
this.custom_domains = ""
|
||||
this.host_header_rewrite = ""
|
||||
this.subdomain = ""
|
||||
this.locations = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,18 +71,18 @@ class HttpProxy extends BaseProxy {
|
||||
class HttpsProxy extends BaseProxy {
|
||||
constructor(proxyStats, port, subdomain_host) {
|
||||
super(proxyStats)
|
||||
this.type = 'https'
|
||||
this.type = "https"
|
||||
this.port = port
|
||||
if (proxyStats.conf != null) {
|
||||
this.custom_domains = proxyStats.conf.custom_domains
|
||||
if (proxyStats.conf.sub_domain !== '') {
|
||||
this.subdomain = proxyStats.conf.sub_domain + '.' + subdomain_host
|
||||
if (proxyStats.conf.sub_domain != "") {
|
||||
this.subdomain = proxyStats.conf.sub_domain + "." + subdomain_host
|
||||
} else {
|
||||
this.subdomain = ''
|
||||
this.subdomain = ""
|
||||
}
|
||||
} else {
|
||||
this.custom_domains = ''
|
||||
this.subdomain = ''
|
||||
this.custom_domains = ""
|
||||
this.subdomain = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,7 +90,7 @@ class HttpsProxy extends BaseProxy {
|
||||
class StcpProxy extends BaseProxy {
|
||||
constructor(proxyStats) {
|
||||
super(proxyStats)
|
||||
this.type = 'stcp'
|
||||
this.type = "stcp"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
module.exports = {
|
||||
publicPath: './',
|
||||
devServer: {
|
||||
host: '127.0.0.1',
|
||||
port: 8010,
|
||||
proxy: {
|
||||
'/api/': {
|
||||
target: 'http://127.0.0.1:8080/api',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/api': ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
107
web/frps/webpack.config.js
Normal file
107
web/frps/webpack.config.js
Normal file
@ -0,0 +1,107 @@
|
||||
const path = require('path')
|
||||
var webpack = require('webpack')
|
||||
var HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
var VueLoaderPlugin = require('vue-loader/lib/plugin')
|
||||
var url = require('url')
|
||||
var publicPath = ''
|
||||
|
||||
module.exports = (options = {}) => ({
|
||||
entry: {
|
||||
vendor: './src/main'
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: options.dev ? '[name].js' : '[name].js?[chunkhash]',
|
||||
chunkFilename: '[id].js?[chunkhash]',
|
||||
publicPath: options.dev ? '/assets/' : publicPath
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js',
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader'
|
||||
}, {
|
||||
test: /\.js$/,
|
||||
use: ['babel-loader'],
|
||||
exclude: /node_modules/
|
||||
}, {
|
||||
test: /\.html$/,
|
||||
use: [{
|
||||
loader: 'html-loader',
|
||||
options: {
|
||||
root: path.resolve(__dirname, 'src'),
|
||||
attrs: ['img:src', 'link:href']
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
test: /\.less$/,
|
||||
loader: 'style-loader!css-loader!postcss-loader!less-loader'
|
||||
}, {
|
||||
test: /\.css$/,
|
||||
use: ['style-loader', 'css-loader', 'postcss-loader']
|
||||
}, {
|
||||
test: /favicon\.png$/,
|
||||
use: [{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]?[hash]'
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,
|
||||
exclude: /favicon\.png$/,
|
||||
use: [{
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000
|
||||
}
|
||||
}]
|
||||
}]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
names: ['vendor', 'manifest']
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
favicon: 'src/assets/favicon.ico',
|
||||
template: 'src/index.html'
|
||||
}),
|
||||
new webpack.NormalModuleReplacementPlugin(/element-ui[\/\\]lib[\/\\]locale[\/\\]lang[\/\\]zh-CN/, 'element-ui/lib/locale/lang/en'),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
sourceMap: false,
|
||||
comments: false,
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
}),
|
||||
new VueLoaderPlugin()
|
||||
],
|
||||
devServer: {
|
||||
host: '127.0.0.1',
|
||||
port: 8010,
|
||||
proxy: {
|
||||
'/api/': {
|
||||
target: 'http://127.0.0.1:8080',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/api': ''
|
||||
}
|
||||
}
|
||||
},
|
||||
historyApiFallback: {
|
||||
index: url.parse(options.dev ? '/assets/' : publicPath).pathname
|
||||
}
|
||||
}//,
|
||||
//devtool: options.dev ? '#eval-source-map' : '#source-map'
|
||||
})
|
15467
web/frps/yarn.lock
15467
web/frps/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user