feat: rename project to V2RayA due to collision; init frontend project

This commit is contained in:
mzz2017 2019-10-20 16:57:39 +08:00
parent 46b7d59ad9
commit 749a4aa31b
41 changed files with 9908 additions and 69 deletions

View File

@ -6,9 +6,9 @@ V2Ray 用户手册https://www.v2ray.com
V2Ray 项目地址https://github.com/v2ray/v2ray-core
# v2rayW
# V2RayA
一个v2ray的web GUI。
V2RayA是一个V2Ray的Web GUI。
尽管v2ray的GUI很多但在Linux上好用的却寥寥无几。[jiangxufeng/v2rayL](https://github.com/jiangxufeng/v2rayL)是目前Linux上较好的一个Linux GUI但暂时无法满足我对用户体验的较高要求因此开此项目仅作个人学习和研究使用。
@ -20,6 +20,10 @@ V2Ray 项目地址https://github.com/v2ray/v2ray-core
[hq450/fancyss](https://github.com/hq450/fancyss)
# similar projects
[v2raywebui/V2RayWebUI](https://github.com/v2raywebui/V2RayWebUI)
# 协议
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

5
go.mod
View File

@ -1,5 +0,0 @@
module github.com/mzz2017/v2rayW
go 1.12
require github.com/gin-gonic/gin v1.4.0 // indirect

38
go.sum
View File

@ -1,38 +0,0 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

2
gui/.browserslistrc Normal file
View File

@ -0,0 +1,2 @@
> 1%
last 2 versions

14
gui/.eslintrc.js Normal file
View File

@ -0,0 +1,14 @@
module.exports = {
root: true,
env: {
node: true
},
extends: ["plugin:vue/essential", "@vue/prettier"],
rules: {
"no-console": process.env.NODE_ENV === "production" ? "error" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
},
parserOptions: {
parser: "babel-eslint"
}
};

21
gui/.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

24
gui/README.md Normal file
View File

@ -0,0 +1,24 @@
# v2rayW-GUI
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
### Lints and fixes files
```
yarn lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

3
gui/babel.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"]
};

35
gui/package.json Normal file
View File

@ -0,0 +1,35 @@
{
"name": "gui",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.19.0",
"buefy": "^0.8.5",
"core-js": "^3.1.2",
"normalize.css": "^8.0.1",
"vue": "^2.6.10",
"vue-router": "^3.0.6",
"vuex": "^3.0.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.0.0",
"@vue/cli-plugin-eslint": "^4.0.0",
"@vue/cli-plugin-router": "^4.0.0",
"@vue/cli-plugin-vuex": "^4.0.0",
"@vue/cli-service": "^4.0.0",
"@vue/eslint-config-prettier": "^5.0.0",
"babel-eslint": "^10.0.1",
"eslint": "^5.16.0",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-vue": "^5.0.0",
"prettier": "^1.18.2",
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"vue-template-compiler": "^2.6.10"
}
}

5
gui/postcss.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
plugins: {
autoprefixer: {}
}
};

BIN
gui/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

17
gui/public/index.html Normal file
View File

@ -0,0 +1,17 @@
<!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>V2RayA</title>
</head>
<body>
<noscript>
<strong>We're sorry but v2rayW-gui 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>

116
gui/src/App.vue Normal file
View File

@ -0,0 +1,116 @@
<template>
<div id="app">
<b-navbar fixed-top shadow type="is-light" ref="navs">
<template slot="brand">
<b-navbar-item href="/">
<img src="./assets/logo.png" alt="V2RayA" class="logo" />
</b-navbar-item>
</template>
<template slot="start">
<b-navbar-item
tag="router-link"
to="/status"
:active="nav === 'status'"
>
<i class="iconfont icon-earth" style="font-size: 1.2em"></i>
状态 </b-navbar-item
><b-navbar-item tag="router-link" to="/node" :active="nav === 'node'">
<i class="iconfont icon-cloud-server" style="font-size: 1.4em"></i>
节点
</b-navbar-item>
<b-navbar-item
tag="router-link"
to="/subscription"
:active="nav === 'subscription'"
>
<i class="iconfont icon-cloud-sync" style="font-size: 1.4em"></i>
订阅
</b-navbar-item>
<b-navbar-item
tag="router-link"
to="/setting"
:active="nav === 'settings'"
>
<i class="iconfont icon-setting" style="font-size: 1.25em"></i>
设置
</b-navbar-item>
<b-navbar-item tag="router-link" to="/about" :active="nav === 'about'">
<i class="iconfont icon-heart" style="font-size: 1.25em"></i>
关于
</b-navbar-item>
</template>
<template slot="end">
<b-dropdown
position="is-bottom-left"
aria-role="menu"
style="margin-right:10px"
>
<a class="navbar-item" slot="trigger" role="button">
<span>mzz2017</span>
<i
class="iconfont icon-caret-down"
style="position: relative; top: 1px; left:2px"
></i>
</a>
<b-dropdown-item custom aria-role="menuitem">
Logged as <b>mzz2017</b>
</b-dropdown-item>
<hr class="dropdown-divider" />
<b-dropdown-item value="logout" aria-role="menuitem">
<i
class="iconfont icon-logout"
style="position: relative;top:1px;"
></i>
Logout
</b-dropdown-item>
</b-dropdown>
</template>
</b-navbar>
<router-view class="container" />
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
data() {
return {};
},
computed: mapState(["nav"]),
watch: {}
};
</script>
<style lang="scss" scoped>
@import "https://at.alicdn.com/t/font_1467288_00gqxequ9vdv7.css";
#app {
margin: 0;
}
.menucontainer {
padding: 20px;
}
.logo {
min-height: 2.5rem;
}
.navbar-item .iconfont {
margin-right: 0.15em;
}
</style>
<style lang="scss">
html {
overflow-scrolling: touch;
-webkit-overflow-scrolling: touch;
}
@media screen and (max-width: 1023px) {
.dropdown.is-mobile-modal .dropdown-menu {
// modal
left: 0 !important;
right: 0 !important;
margin: auto;
transform: unset !important;
}
}
</style>

View File

@ -0,0 +1,539 @@
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
font-family: "iconfont logo";
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* tabs */
.nav-tabs {
position: relative;
}
.nav-tabs .nav-more {
position: absolute;
right: 0;
bottom: 0;
height: 42px;
line-height: 42px;
color: #666;
}
#tabs {
border-bottom: 1px solid #eee;
}
#tabs li {
cursor: pointer;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 16px;
border-bottom: 2px solid transparent;
position: relative;
z-index: 1;
margin-bottom: -1px;
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
}
.tab-container .content {
display: none;
}
/* 页面布局 */
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main .logo {
color: #333;
text-align: left;
margin-bottom: 30px;
line-height: 1;
height: 110px;
margin-top: -50px;
overflow: hidden;
*zoom: 1;
}
.main .logo a {
font-size: 160px;
color: #333;
}
.helps {
margin-top: 40px;
}
.helps pre {
padding: 20px;
margin: 10px 0;
border: solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists {
width: 100% !important;
overflow: hidden;
*zoom: 1;
}
.icon_lists li {
width: 100px;
margin-bottom: 10px;
margin-right: 20px;
text-align: center;
list-style: none !important;
cursor: default;
}
.icon_lists li .code-name {
line-height: 1.2;
}
.icon_lists .icon {
display: block;
height: 100px;
line-height: 100px;
font-size: 42px;
margin: 10px auto;
color: #333;
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
-moz-transition: font-size 0.25s linear, width 0.25s linear;
transition: font-size 0.25s linear, width 0.25s linear;
}
.icon_lists .icon:hover {
font-size: 100px;
}
.icon_lists .svg-icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
.icon_lists li .name,
.icon_lists li .code-name {
color: #666;
}
/* markdown 样式 */
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p {
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul>li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown>br,
.markdown>p>br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
/* 代码高亮 */
/* PrismJS 1.15.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

View File

@ -0,0 +1,331 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>IconFont Demo</title>
<link rel="shortcut icon" href="https://gtms04.alicdn.com/tps/i4/TB1_oz6GVXXXXaFXpXXJDFnIXXX-64-64.ico" type="image/x-icon"/>
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="iconfont.css">
<script src="iconfont.js"></script>
<!-- jQuery -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
<!-- 代码高亮 -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
</head>
<body>
<div class="main">
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">&#xe86b;</a></h1>
<div class="nav-tabs">
<ul id="tabs" class="dib-box">
<li class="dib active"><span>Unicode</span></li>
<li class="dib"><span>Font class</span></li>
<li class="dib"><span>Symbol</span></li>
</ul>
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=1467288" target="_blank" class="nav-more">查看项目</a>
</div>
<div class="tab-container">
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe781;</span>
<div class="name">earth</div>
<div class="code-name">&amp;#xe781;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe78c;</span>
<div class="name">logout</div>
<div class="code-name">&amp;#xe78c;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe78e;</span>
<div class="name">setting</div>
<div class="code-name">&amp;#xe78e;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe7d9;</span>
<div class="name">cloud-server</div>
<div class="code-name">&amp;#xe7d9;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe7da;</span>
<div class="name">cloud-sync</div>
<div class="code-name">&amp;#xe7da;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe7df;</span>
<div class="name">heart</div>
<div class="code-name">&amp;#xe7df;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe7eb;</span>
<div class="name">down</div>
<div class="code-name">&amp;#xe7eb;</div>
</li>
</ul>
<div class="article markdown">
<h2 id="unicode-">Unicode 引用</h2>
<hr>
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
<ul>
<li>兼容性最好,支持 IE6+,及所有现代浏览器。</li>
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
<li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li>
</ul>
<blockquote>
<p>注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用如果有需求建议使用symbol 的引用方式</p>
</blockquote>
<p>Unicode 使用步骤如下:</p>
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.eot');
src: url('iconfont.eot?#iefix') format('embedded-opentype'),
url('iconfont.woff2') format('woff2'),
url('iconfont.woff') format('woff'),
url('iconfont.ttf') format('truetype'),
url('iconfont.svg#iconfont') format('svg');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
<pre><code class="language-css"
>.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
<pre>
<code class="language-html"
>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-earth"></span>
<div class="name">
earth
</div>
<div class="code-name">.icon-earth
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-logout"></span>
<div class="name">
logout
</div>
<div class="code-name">.icon-logout
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-setting"></span>
<div class="name">
setting
</div>
<div class="code-name">.icon-setting
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-cloud-server"></span>
<div class="name">
cloud-server
</div>
<div class="code-name">.icon-cloud-server
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-cloud-sync"></span>
<div class="name">
cloud-sync
</div>
<div class="code-name">.icon-cloud-sync
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-heart"></span>
<div class="name">
heart
</div>
<div class="code-name">.icon-heart
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-down"></span>
<div class="name">
down
</div>
<div class="code-name">.icon-down
</div>
</li>
</ul>
<div class="article markdown">
<h2 id="font-class-">font-class 引用</h2>
<hr>
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
<p>与 Unicode 使用方式相比,具有如下特点:</p>
<ul>
<li>兼容性良好,支持 IE8+,及所有现代浏览器。</li>
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
<li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
</code></pre>
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"
iconfont" 是你项目下的 font-family。可以通过编辑项目查看默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-earth"></use>
</svg>
<div class="name">earth</div>
<div class="code-name">#icon-earth</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-logout"></use>
</svg>
<div class="name">logout</div>
<div class="code-name">#icon-logout</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-setting"></use>
</svg>
<div class="name">setting</div>
<div class="code-name">#icon-setting</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-cloud-server"></use>
</svg>
<div class="name">cloud-server</div>
<div class="code-name">#icon-cloud-server</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-cloud-sync"></use>
</svg>
<div class="name">cloud-sync</div>
<div class="code-name">#icon-cloud-sync</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-heart"></use>
</svg>
<div class="name">heart</div>
<div class="code-name">#icon-heart</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-down"></use>
</svg>
<div class="name">down</div>
<div class="code-name">#icon-down</div>
</li>
</ul>
<div class="article markdown">
<h2 id="symbol-">Symbol 引用</h2>
<hr>
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
<ul>
<li>支持多色图标了,不再受单色限制。</li>
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
</code></pre>
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
<pre><code class="language-html">&lt;style&gt;
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
&lt;/style&gt;
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
&lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
&lt;/svg&gt;
</code></pre>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('.tab-container .content:first').show()
$('#tabs li').click(function (e) {
var tabContent = $('.tab-container .content')
var index = $(this).index()
if ($(this).hasClass('active')) {
return
} else {
$('#tabs li').removeClass('active')
$(this).addClass('active')
tabContent.hide().eq(index).fadeIn()
}
})
})
</script>
</body>
</html>

View File

@ -0,0 +1,45 @@
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1571558189544'); /* IE9 */
src: url('iconfont.eot?t=1571558189544#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
url('iconfont.woff?t=1571558189544') format('woff'),
url('iconfont.ttf?t=1571558189544') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1571558189544#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-earth:before {
content: "\e781";
}
.icon-logout:before {
content: "\e78c";
}
.icon-setting:before {
content: "\e78e";
}
.icon-cloud-server:before {
content: "\e7d9";
}
.icon-cloud-sync:before {
content: "\e7da";
}
.icon-heart:before {
content: "\e7df";
}
.icon-down:before {
content: "\e7eb";
}

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,58 @@
{
"id": "1467288",
"name": "v2rayA",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "4765743",
"name": "earth",
"font_class": "earth",
"unicode": "e781",
"unicode_decimal": 59265
},
{
"icon_id": "4765888",
"name": "logout",
"font_class": "logout",
"unicode": "e78c",
"unicode_decimal": 59276
},
{
"icon_id": "4765891",
"name": "setting",
"font_class": "setting",
"unicode": "e78e",
"unicode_decimal": 59278
},
{
"icon_id": "4766900",
"name": "cloud-server",
"font_class": "cloud-server",
"unicode": "e7d9",
"unicode_decimal": 59353
},
{
"icon_id": "4766904",
"name": "cloud-sync",
"font_class": "cloud-sync",
"unicode": "e7da",
"unicode_decimal": 59354
},
{
"icon_id": "4766951",
"name": "heart",
"font_class": "heart",
"unicode": "e7df",
"unicode_decimal": 59359
},
{
"icon_id": "4767014",
"name": "down",
"font_class": "down",
"unicode": "e7eb",
"unicode_decimal": 59371
}
]
}

View File

@ -0,0 +1,47 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="earth" unicode="&#59265;" d="M854.4 95.1c0.2 0.3 0.5 0.6 0.7 0.9C920.6 173.9 960 274.3 960 384s-39.4 210.1-104.8 288c-0.2 0.3-0.5 0.5-0.7 0.8-1.1 1.3-2.1 2.5-3.2 3.7-0.4 0.5-0.8 0.9-1.2 1.4-1.4 1.6-2.7 3.1-4.1 4.7l-0.1 0.1c-1.5 1.7-3.1 3.4-4.6 5.1l-0.1 0.1c-3.2 3.4-6.4 6.8-9.7 10.1l-0.1 0.1-4.8 4.8-0.3 0.3c-1.5 1.5-3 2.9-4.5 4.3-0.5 0.5-1 1-1.6 1.5-1 1-2 1.9-3 2.8-0.3 0.3-0.7 0.6-1 1C736.4 786.8 629.5 832 512 832s-224.4-45.2-304.3-119.2c-0.3-0.3-0.7-0.6-1-1-1-0.9-2-1.9-3-2.9-0.5-0.5-1-1-1.6-1.5-1.5-1.4-3-2.9-4.5-4.3l-0.3-0.3-4.8-4.8-0.1-0.1c-3.3-3.3-6.5-6.7-9.7-10.1l-0.1-0.1c-1.6-1.7-3.1-3.4-4.6-5.1l-0.1-0.1c-1.4-1.5-2.8-3.1-4.1-4.7-0.4-0.5-0.8-0.9-1.2-1.4-1.1-1.2-2.1-2.5-3.2-3.7-0.2-0.3-0.5-0.5-0.7-0.8C103.4 594.1 64 493.7 64 384s39.4-210.1 104.8-288c0.2-0.3 0.5-0.6 0.7-0.9 1-1.2 2.1-2.5 3.1-3.7 0.4-0.5 0.8-0.9 1.2-1.4 1.4-1.6 2.7-3.1 4.1-4.7 0-0.1 0.1-0.1 0.1-0.2 1.5-1.7 3-3.4 4.6-5l0.1-0.1c3.2-3.4 6.4-6.8 9.6-10.1l0.1-0.1c1.6-1.6 3.1-3.2 4.7-4.7l0.3-0.3c3.3-3.3 6.7-6.5 10.1-9.6 80.1-74 187-119.2 304.5-119.2s224.4 45.2 304.3 119.2c3.4 3.1 6.7 6.3 10 9.6l0.3 0.3c1.6 1.6 3.2 3.1 4.7 4.7l0.1 0.1c3.3 3.3 6.5 6.7 9.6 10.1l0.1 0.1c1.5 1.7 3.1 3.3 4.6 5 0 0.1 0.1 0.1 0.1 0.2 1.4 1.5 2.8 3.1 4.1 4.7 0.4 0.5 0.8 0.9 1.2 1.4 1.2 1.3 2.3 2.5 3.3 3.7z m4.1 142.6c-13.8-32.6-32-62.8-54.2-90.2-24.9 21.5-52.2 40.3-81.5 55.9 11.6 46.9 18.8 98.4 20.7 152.6H887c-3-40.9-12.6-80.6-28.5-118.3zM887 412H743.5c-1.9 54.2-9.1 105.7-20.7 152.6 29.3 15.6 56.6 34.4 81.5 55.9 22.2-27.4 40.4-57.6 54.2-90.2C874.4 492.6 884 452.9 887 412zM658.3 730.5c39.7-16.8 75.8-40 107.6-69.2-18.5-15.8-38.4-29.7-59.4-41.8-15.7 45-35.8 84.1-59.2 115.4 3.7-1.4 7.4-2.9 11-4.4z m-90.6-700.6c-9.2-7.2-18.4-12.7-27.7-16.4V199c39.9-2.8 78.6-11.6 115.7-26.2-8.3-24.6-17.9-47.3-29-67.8-17.4-32.4-37.8-58.3-59-75.1z m59 633.1c11-20.6 20.7-43.3 29-67.8-37.1-14.6-75.8-23.4-115.7-26.2V754.4c9.2-3.7 18.5-9.1 27.7-16.4 21.2-16.7 41.6-42.6 59-75zM540 255.1V356h147.5c-1.6-44.2-7.1-87.1-16.3-127.8l-0.3-1.2c-41.1 15.6-85.1 25.3-130.9 28.1z m0 156.9V512.9c45.8 2.8 89.8 12.5 130.9 28.1l0.3-1.2c9.2-40.7 14.7-83.5 16.3-127.8H540z m-56-56v-100.9c-45.8-2.8-89.8-12.5-130.9-28.1l-0.3 1.2c-9.2 40.7-14.7 83.5-16.3 127.8H484z m-147.5 56c1.6 44.2 7.1 87.1 16.3 127.8l0.3 1.2c41.1-15.6 85-25.3 130.9-28.1V412H336.5zM484 199v-185.4c-9.2 3.7-18.5 9.1-27.7 16.4-21.2 16.7-41.7 42.7-59.1 75.1-11 20.6-20.7 43.3-29 67.8 37.2 14.6 75.9 23.3 115.8 26.1z m0 370c-39.9 2.8-78.6 11.6-115.7 26.2 8.3 24.6 17.9 47.3 29 67.8 17.4 32.4 37.8 58.4 59.1 75.1 9.2 7.2 18.4 12.7 27.7 16.4V569zM365.7 730.5c3.7 1.5 7.3 3 11 4.4-23.4-31.3-43.5-70.4-59.2-115.4-21 12-40.9 26-59.4 41.8 31.8 29.2 67.9 52.4 107.6 69.2zM165.5 530.3c13.8 32.6 32 62.8 54.2 90.2 24.9-21.5 52.2-40.3 81.5-55.9-11.6-46.9-18.8-98.4-20.7-152.6H137c3 40.9 12.6 80.6 28.5 118.3zM137 356h143.5c1.9-54.2 9.1-105.7 20.7-152.6-29.3-15.6-56.6-34.4-81.5-55.9-22.2 27.4-40.4 57.6-54.2 90.2C149.6 275.4 140 315.1 137 356z m228.7-318.5c-39.7 16.8-75.8 40-107.6 69.2 18.5 15.8 38.4 29.7 59.4 41.8 15.7-45 35.8-84.1 59.2-115.4-3.7 1.4-7.4 2.9-11 4.4z m292.6 0c-3.7-1.5-7.3-3-11-4.4 23.4 31.3 43.5 70.4 59.2 115.4 21-12 40.9-26 59.4-41.8-31.8-29.2-67.9-52.4-107.6-69.2z" horiz-adv-x="1024" />
<glyph glyph-name="logout" unicode="&#59276;" d="M868 164h-70.3c-4.8 0-9.3-2.1-12.3-5.8-7-8.5-14.5-16.7-22.4-24.5-32.6-32.5-70.5-58.1-112.7-75.9-43.6-18.4-90-27.8-137.9-27.8-47.9 0-94.3 9.4-137.9 27.8-42.2 17.8-80.1 43.4-112.7 75.9-32.6 32.5-58.1 70.4-76 112.5C167.3 289.8 158 336.1 158 384s9.4 94.2 27.8 137.8c17.8 42.1 43.4 80 76 112.5s70.5 58.1 112.7 75.9c43.6 18.4 90 27.8 137.9 27.8 47.9 0 94.3-9.3 137.9-27.8 42.2-17.8 80.1-43.4 112.7-75.9 7.9-7.9 15.3-16.1 22.4-24.5 3-3.7 7.6-5.8 12.3-5.8H868c6.3 0 10.2 7 6.7 12.3C798 735.5 663.8 814.4 511.3 814 271.7 813.4 79.6 618.9 82 379.6 84.4 144.1 276.2-46 512.4-46c152.1 0 285.7 78.8 362.3 197.7 3.4 5.3-0.4 12.3-6.7 12.3zM956.9 390.3L815 502.3c-5.3 4.2-13 0.4-13-6.3v-76H488c-4.4 0-8-3.6-8-8v-56c0-4.4 3.6-8 8-8h314v-76c0-6.7 7.8-10.5 13-6.3l141.9 112c4.1 3.2 4.1 9.4 0 12.6z" horiz-adv-x="1024" />
<glyph glyph-name="setting" unicode="&#59278;" d="M924.8 270.3l-65.5 56c3.1 19 4.7 38.4 4.7 57.8s-1.6 38.8-4.7 57.8l65.5 56c10.1 8.6 13.8 22.6 9.3 35.2l-0.9 2.6c-18.1 50.5-44.9 96.9-79.7 137.9l-1.8 2.1c-8.6 10.1-22.5 13.9-35.1 9.5l-81.3-28.9c-30 24.6-63.5 44-99.7 57.6l-15.7 85c-2.4 13.1-12.7 23.3-25.8 25.7l-2.7 0.5c-52.1 9.4-106.9 9.4-159 0l-2.7-0.5c-13.1-2.4-23.4-12.6-25.8-25.7l-15.8-85.4c-35.9-13.6-69.2-32.9-99-57.4l-81.9 29.1c-12.5 4.4-26.5 0.7-35.1-9.5l-1.8-2.1c-34.8-41.1-61.6-87.5-79.7-137.9l-0.9-2.6c-4.5-12.5-0.8-26.5 9.3-35.2l66.3-56.6c-3.1-18.8-4.6-38-4.6-57.1 0-19.2 1.5-38.4 4.6-57.1L99 270.5c-10.1-8.6-13.8-22.6-9.3-35.2l0.9-2.6c18.1-50.4 44.9-96.9 79.7-137.9l1.8-2.1c8.6-10.1 22.5-13.9 35.1-9.5l81.9 29.1c29.8-24.5 63.1-43.9 99-57.4l15.8-85.4c2.4-13.1 12.7-23.3 25.8-25.7l2.7-0.5c26.1-4.7 52.8-7.1 79.5-7.1 26.7 0 53.5 2.4 79.5 7.1l2.7 0.5c13.1 2.4 23.4 12.6 25.8 25.7l15.7 85c36.2 13.6 69.7 32.9 99.7 57.6l81.3-28.9c12.5-4.4 26.5-0.7 35.1 9.5l1.8 2.1c34.8 41.1 61.6 87.5 79.7 137.9l0.9 2.6c4.5 12.3 0.8 26.3-9.3 35zM788.3 430.1c2.5-15.1 3.8-30.6 3.8-46.1s-1.3-31-3.8-46.1l-6.6-40.1 74.7-63.9c-11.3-26.1-25.6-50.7-42.6-73.6L721 193.2l-31.4-25.8c-23.9-19.6-50.5-35-79.3-45.8l-38.1-14.3-17.9-97c-28.1-3.2-56.8-3.2-85 0l-17.9 97.2-37.8 14.5c-28.5 10.8-55 26.2-78.7 45.7l-31.4 25.9-93.4-33.2c-17 22.9-31.2 47.6-42.6 73.6l75.5 64.5-6.5 40c-2.4 14.9-3.7 30.3-3.7 45.5 0 15.3 1.2 30.6 3.7 45.5l6.5 40-75.5 64.5c11.3 26.1 25.6 50.7 42.6 73.6l93.4-33.2 31.4 25.9c23.7 19.5 50.2 34.9 78.7 45.7l37.9 14.3 17.9 97.2c28.1 3.2 56.8 3.2 85 0l17.9-97 38.1-14.3c28.7-10.8 55.4-26.2 79.3-45.8l31.4-25.8 92.8 32.9c17-22.9 31.2-47.6 42.6-73.6L781.8 470l6.5-39.9zM512 570c-97.2 0-176-78.8-176-176s78.8-176 176-176 176 78.8 176 176-78.8 176-176 176z m79.2-255.2C570 293.7 541.9 282 512 282c-29.9 0-58 11.7-79.2 32.8C411.7 336 400 364.1 400 394c0 29.9 11.7 58 32.8 79.2C454 494.4 482.1 506 512 506c29.9 0 58-11.6 79.2-32.8C612.3 452 624 423.9 624 394c0-29.9-11.7-58-32.8-79.2z" horiz-adv-x="1024" />
<glyph glyph-name="cloud-server" unicode="&#59353;" d="M704 450H320c-4.4 0-8-3.6-8-8v-402c0-4.4 3.6-8 8-8h384c4.4 0 8 3.6 8 8V442c0 4.4-3.6 8-8 8z m-328-64h272v-117H376V386z m272-290H376V213h272v-117zM456 148m-32 0a32 32 0 1 1 64 0 32 32 0 1 1-64 0ZM456 326m-32 0a32 32 0 1 1 64 0 32 32 0 1 1-64 0ZM811.4 527.1C765.6 648 648.9 734 512.2 734S258.8 648.1 213 527.2C126.9 504.5 63.5 425.8 64 332.4 64.6 228 145.6 143.10000000000002 247.6 134c4.7-0.4 8.7 3.3 8.7 8v60.4c0 4-3 7.4-7 7.9-27 3.4-52.5 15.2-72.1 34.5-24 23.5-37.2 55.1-37.2 88.6 0 28 9.1 54.4 26.2 76.4 16.7 21.4 40.2 36.9 66.1 43.7l37.9 10 13.9 36.7c8.6 22.8 20.6 44.2 35.7 63.5 14.9 19.2 32.6 36 52.4 50 41.1 28.9 89.5 44.2 140 44.2s98.9-15.3 140-44.3c19.9-14 37.5-30.8 52.4-50 15.1-19.3 27.1-40.7 35.7-63.5l13.8-36.6 37.8-10c54.2-14.4 92.1-63.7 92.1-120 0-33.6-13.2-65.1-37.2-88.6-19.5-19.2-44.9-31.1-71.9-34.5-4-0.5-6.9-3.9-6.9-7.9V142c0-4.7 4.1-8.4 8.8-8 101.7 9.2 182.5 94 183.2 198.2 0.6 93.4-62.7 172.1-148.6 194.9z" horiz-adv-x="1024" />
<glyph glyph-name="cloud-sync" unicode="&#59354;" d="M811.4 527.1C765.6 648 648.9 734 512.2 734S258.8 648.1 213 527.2C126.9 504.5 63.5 425.8 64 332.4 64.6 228 145.6 143.10000000000002 247.6 134c4.7-0.4 8.7 3.3 8.7 8v60.4c0 4-3 7.4-7 7.9-27 3.4-52.5 15.2-72.1 34.5-24 23.5-37.2 55.1-37.2 88.6 0 28 9.1 54.4 26.2 76.4 16.7 21.4 40.2 36.9 66.1 43.7l37.9 10 13.9 36.7c8.6 22.8 20.6 44.2 35.7 63.5 14.9 19.2 32.6 36 52.4 50 41.1 28.9 89.5 44.2 140 44.2s98.9-15.3 140-44.3c19.9-14 37.5-30.8 52.4-50 15.1-19.3 27.1-40.7 35.7-63.5l13.8-36.6 37.8-10c54.2-14.4 92.1-63.7 92.1-120 0-33.6-13.2-65.1-37.2-88.6-19.5-19.2-44.9-31.1-71.9-34.5-4-0.5-6.9-3.9-6.9-7.9V142c0-4.7 4.1-8.4 8.8-8 101.7 9.2 182.5 94 183.2 198.2 0.6 93.4-62.7 172.1-148.6 194.9zM376.9 239.60000000000002c1.8 33.5 15.7 64.7 39.5 88.6 25.4 25.5 60 39.8 96 39.8 36.2 0 70.3-14.1 96-39.8 1.4-1.4 2.7-2.8 4.1-4.3l-25-19.6c-5.3-4.1-3.5-12.5 3-14.1l98.2-24c5-1.2 9.9 2.6 9.9 7.7l0.5 101.3c0 6.7-7.6 10.5-12.9 6.3L663 363.29999999999995c-36.6 42-90.4 68.6-150.5 68.6-107.4 0-195-85.1-199.4-191.7-0.2-4.5 3.4-8.3 8-8.3H369c4.2 0.1 7.7 3.4 7.9 7.7zM703 232h-47.9c-4.2 0-7.7-3.3-8-7.6-1.8-33.5-15.7-64.7-39.5-88.6-25.4-25.5-60-39.8-96-39.8-36.2 0-70.3 14.1-96 39.8-1.4 1.4-2.7 2.8-4.1 4.3l25 19.6c5.3 4.1 3.5 12.5-3 14.1l-98.2 24c-5 1.2-9.9-2.6-9.9-7.7l-0.4-101.4c0-6.7 7.6-10.5 12.9-6.3l23.2 18.2c36.6-42 90.4-68.6 150.5-68.6 107.4 0 195 85.1 199.4 191.7 0.2 4.5-3.4 8.3-8 8.3z" horiz-adv-x="1024" />
<glyph glyph-name="heart" unicode="&#59359;" d="M923 612.4c-13.4 31.1-32.6 58.9-56.9 82.8-24.3 23.8-52.5 42.4-84 55.5-32.5 13.5-66.9 20.3-102.4 20.3-49.3 0-97.4-13.5-139.2-39-10-6.1-19.5-12.8-28.5-20.1-9 7.3-18.5 14-28.5 20.1-41.8 25.5-89.9 39-139.2 39-35.5 0-69.9-6.8-102.4-20.3-31.4-13-59.7-31.7-84-55.5-24.4-23.9-43.5-51.7-56.9-82.8-13.9-32.3-21-66.6-21-101.9 0-33.3 6.8-68 20.3-103.3 11.3-29.5 27.5-60.1 48.2-91 32.8-48.9 77.9-99.9 133.9-151.6 92.8-85.7 184.7-144.9 188.6-147.3l23.7-15.2c10.5-6.7 24-6.7 34.5 0l23.7 15.2c3.9 2.5 95.7 61.6 188.6 147.3 56 51.7 101.1 102.7 133.9 151.6 20.7 30.9 37 61.5 48.2 91 13.5 35.3 20.3 70 20.3 103.3 0.1 35.3-7 69.6-20.9 101.9zM512 81.2S156 309.3 156 510.5C156 612.4 240.3 695 344.3 695c73.1 0 136.5-40.8 167.7-100.4C543.2 654.2 606.6 695 679.7 695c104 0 188.3-82.6 188.3-184.5 0-201.2-356-429.3-356-429.3z" horiz-adv-x="1024" />
<glyph glyph-name="down" unicode="&#59371;" d="M884 640h-75c-5.1 0-9.9-2.5-12.9-6.6L512 241.8 227.9 633.4c-3 4.1-7.8 6.6-12.9 6.6h-75c-6.5 0-10.3-7.4-6.5-12.7l352.6-486.1c12.8-17.6 39-17.6 51.7 0l352.6 486.1c3.9 5.3 0.1 12.7-6.4 12.7z" horiz-adv-x="1024" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
gui/src/assets/logo.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

18
gui/src/main.js Normal file
View File

@ -0,0 +1,18 @@
import "@/plugins/buefy";
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import axios from "axios";
import "normalize.css";
import "@/assets/font_1467288_zafhp5y171/iconfont.css";
Vue.prototype.$axios = axios;
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");

5
gui/src/plugins/buefy.js Normal file
View File

@ -0,0 +1,5 @@
import Vue from "vue";
import Buefy from "buefy";
import "buefy/dist/buefy.css";
Vue.use(Buefy);

42
gui/src/router/index.js Normal file
View File

@ -0,0 +1,42 @@
import Vue from "vue";
import VueRouter from "vue-router";
import store from "@/store";
Vue.use(VueRouter);
const routes = [
{
path: "/",
redirect: "/status"
},
{
path: "/status",
component: () => import("@/views/status")
},
{
path: "/about",
name: "about",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue")
}
];
const router = new VueRouter({
mode: "history",
routes
});
const title = "V2RayA";
router.afterEach(to => {
if (to.meta.title) {
document.title = `${to.meta.title} - ${title}`;
} else {
document.title = `${title}`;
}
store.commit("NAV", to.path.split("/")[1]);
});
export default router;

17
gui/src/store/index.js Normal file
View File

@ -0,0 +1,17 @@
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
nav: ""
},
mutations: {
NAV(state, val) {
state.nav = val;
}
},
actions: {},
modules: {}
});

5
gui/src/views/About.vue Normal file
View File

@ -0,0 +1,5 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>

12
gui/src/views/status.vue Normal file
View File

@ -0,0 +1,12 @@
<template>
<div style="color:red">
home
<b-icon icon="home" size="is-small"> </b-icon>
</div>
</template>
<script>
export default {
name: "home"
};
</script>

29
gui/vue.config.js Normal file
View File

@ -0,0 +1,29 @@
var webpack = require("webpack");
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === "production") {
// 为生产环境修改配置...
return {
plugins: [
new webpack.DefinePlugin({
apiRoot: "'http://localhost:8080/api'"
})
]
};
} else {
// 为开发环境修改配置...
return {
plugins: [
new webpack.DefinePlugin({
apiRoot: "'http://service:8080/api'"
})
]
};
}
},
productionSourceMap: false,
devServer: {
port: 8081
}
};

8444
gui/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,4 +4,4 @@ ADD . /service
WORKDIR /service
RUN go build -mod=vendor
EXPOSE 8080
ENTRYPOINT ["v2rayW"]
ENTRYPOINT ["v2rayA"]

View File

@ -1,4 +1,4 @@
module v2rayW
module v2rayA
go 1.12

View File

@ -0,0 +1,45 @@
package handlers
import (
"encoding/json"
"errors"
"github.com/gin-gonic/gin"
"strings"
"v2rayA/models"
"v2rayA/tools"
)
/*
RequestData: {
"url": "vmess://..."
}
RequestData: {
"url": "ss://..."
}
*/
func Resolving(ctx *gin.Context) {
var (
n *models.NodeData
err error
)
u, ok := ctx.GetQuery("url")
if !ok {
tools.ResponseError(ctx, errors.New("参数有误"))
return
}
if strings.HasPrefix(u, "vmess://") {
n, err = tools.ResolveVmessURL(u)
} else if strings.HasPrefix(u, "ss://") {
n, err = tools.ResolveSSURL(u)
} else {
tools.ResponseError(ctx, errors.New("不支持的协议"))
return
}
if err != nil {
tools.ResponseError(ctx, err)
return
}
var m map[string]interface{}
json.Unmarshal([]byte(n.Config), &m)
tools.ResponseSuccess(ctx, gin.H{"config": m})
}

View File

@ -2,7 +2,7 @@ package handlers
import (
"github.com/gin-gonic/gin"
"v2rayW/tools"
"v2rayA/tools"
)
func Version(ctx *gin.Context) {

View File

@ -1,6 +1,6 @@
package main
import "v2rayW/router"
import "v2rayA/router"
func main() {
router.Run()

View File

@ -48,15 +48,15 @@ type Inbound struct {
} `json:"settings"`
StreamSettings interface{} `json:"streamSettings"`
}
type Users struct {
type User struct {
ID string `json:"id"`
AlterID int `json:"alterId"`
Security string `json:"security"`
}
type Vnext struct {
Address string `json:"address"`
Port int `json:"port"`
Users []Users `json:"users"`
Address string `json:"address"`
Port int `json:"port"`
Users []User `json:"users"`
}
type Server struct {
Address string `json:"address"`
@ -160,7 +160,7 @@ func NewTemplate() (tmpl *Template) {
*/
func (t *Template) FillWithVmessInfo(v VmessInfo) error {
var tmplJson TmplJson
// 读入模板json该json是精心准备过的直接unmarshal到tmpljson上
// 读入模板json
raw, err := ioutil.ReadFile("models/template.json")
if err != nil {
log.Fatal(err)
@ -184,7 +184,7 @@ func (t *Template) FillWithVmessInfo(v VmessInfo) error {
{
Address: v.Add,
Port: port,
Users: []Users{
Users: []User{
{
ID: v.ID,
AlterID: aid,

View File

@ -5,8 +5,8 @@ import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"log"
"v2rayW/config"
"v2rayW/handlers"
"v2rayA/config"
"v2rayA/handlers"
)
func Run() {
@ -19,6 +19,7 @@ func Run() {
g := engine.Group("api")
{
g.GET("version", handlers.Version)
g.GET("resolving", handlers.Resolving)
}
log.Fatal(engine.Run(fmt.Sprintf("%v:%v", app.Address, app.Port)))
}

View File

@ -4,7 +4,7 @@ import (
"bytes"
"net/http"
"strings"
"v2rayW/models"
"v2rayA/models"
)
func ResolveSubscription(source string) (infos []*models.NodeData, err error) {

View File

@ -7,7 +7,7 @@ import (
"net/url"
"regexp"
"strings"
"v2rayW/models"
"v2rayA/models"
)
/*
@ -77,13 +77,14 @@ func ResolveSSURL(vmess string) (nodeData *models.NodeData, err error) {
err = errors.New("this address is not begin with ss://")
return
}
// 尝试按ss://method:password@server:port#name格式进行解析
// 该函数尝试对ss://链接进行解析
resolveFormat := func(content string) (subMatch []string, ok bool) {
// 尝试按ss://method:password@server:port#name格式进行解析
re := regexp.MustCompile(`(.+):(.+)@(\d+\.\d+\.\d+\.\d+):(\d+)(#.+)?`)
subMatch = re.FindStringSubmatch(content)
if len(subMatch) == 0 {
// 尝试按ss://BASE64(method:password)@server:port#name格式进行解析
re = regexp.MustCompile(`(.+)()@(\d+\.\d+\.\d+\.\d+):(\d+)(#.+)?`) //留个空组,subMatch长度统一
re = regexp.MustCompile(`(.+)()@(\d+\.\d+\.\d+\.\d+):(\d+)(#.+)?`) //留个空组,保subMatch长度统一
subMatch = re.FindStringSubmatch(content)
if len(subMatch) > 0 {
raw, err := Base64StdDecode(subMatch[1])
@ -104,7 +105,7 @@ func ResolveSSURL(vmess string) (nodeData *models.NodeData, err error) {
subMatch []string
ok bool
)
//如果已满足格式就不需要第一层的base64解码了
// 尝试解析ss://链接失败则先base64解码
if subMatch, ok = resolveFormat(content); !ok {
// 进行base64解码并unmarshal到VmessInfo上
content, err = Base64StdDecode(content)
@ -118,13 +119,14 @@ func ResolveSSURL(vmess string) (nodeData *models.NodeData, err error) {
return
}
log.Println(content, subMatch)
var info models.VmessInfo
info.Protocol = "shadowsocks"
info.Type = subMatch[1]
info.ID = subMatch[2]
info.Add = subMatch[3]
info.Port = subMatch[4]
info.Ps = subMatch[5]
info := models.VmessInfo{
Protocol: "shadowsocks",
Type: subMatch[1],
ID: subMatch[2],
Add: subMatch[3],
Port: subMatch[4],
Ps: subMatch[5],
}
log.Println(info)
// 填充模板并处理结果
tmpl := models.NewTemplate()