Skip to content

Commit

Permalink
0.0.2
Browse files Browse the repository at this point in the history
 - 增加设置总流量功能,流量超出后自动禁用
 - 优化部分 ui 细节
 - 修复监听 ip 不为空导致无法启动 xray 的问题
 - 修复二维码链接没有包含 address 的问题
  • Loading branch information
vaxilu committed Jun 12, 2021
1 parent f6eb413 commit 214b217
Show file tree
Hide file tree
Showing 14 changed files with 149 additions and 36 deletions.
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,38 @@
# x-ui
a web panel based on xray-core
支持多协议多用户 xray 面板

# 功能介绍
- 系统状态监控
- 支持多用户多协议,网页可视化操作
- 支持的协议:vmess、vless、trojan、shadowsocks、dokodemo-door、socks、http
- 支持配置更多传输配置
- 账号流量统计
- 可自定义 xray 配置模板
- 支持 https 访问面板(自备域名 + ssl 证书)
- 更多高级配置项,详见面板

# 安装&升级
## 测试版
```
bash <(curl -Ls https://raw.githubusercontent.com/sprov065/x-ui/master/install.sh) 0.0.1
```

## 建议系统
- CentOS 7+
- Ubuntu 16+
- Debian 8+

# 常见问题
## 与 v2-ui 关系
x-ui 相当于 v2-ui 的加强版,未来会加入更多功能,待 x-ui 功能稳定后,v2-ui 将不再提供更新

x-ui 可与 v2-ui 并存,数据不互通,不影响对方的运行

# Telegram
群组:https://t.me/sprov_blog

频道:https://t.me/sprov_channel

## Stargazers over time

[![Stargazers over time](https://starchart.cc/sprov065/x-ui.svg)](https://starchart.cc/sprov065/x-ui)
Empty file removed a.s
Empty file.
12 changes: 10 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
package config

import (
_ "embed"
"fmt"
"os"
"strings"
)

//go:embed version
var version string

//go:embed name
var name string

type LogLevel string

const (
Expand All @@ -15,11 +23,11 @@ const (
)

func GetVersion() string {
return "0.0.1"
return strings.TrimSpace(version)
}

func GetName() string {
return "x-ui"
return strings.TrimSpace(name)
}

func GetLogLevel() LogLevel {
Expand Down
1 change: 1 addition & 0 deletions config/name
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x-ui
1 change: 1 addition & 0 deletions config/version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.2
12 changes: 9 additions & 3 deletions database/model/model.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package model

import (
"fmt"
"x-ui/util/json_util"
"x-ui/xray"
)
Expand All @@ -25,8 +26,9 @@ type User struct {
type Inbound struct {
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
UserId int `json:"-"`
Up int64 `json:"up"`
Down int64 `json:"down"`
Up int64 `json:"up" form:"up"`
Down int64 `json:"down" form:"down"`
Total int64 `json:"total" form:"total"`
Remark string `json:"remark" form:"remark"`
Enable bool `json:"enable" form:"enable"`
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
Expand All @@ -42,8 +44,12 @@ type Inbound struct {
}

func (i *Inbound) GenXrayInboundConfig() *xray.InboundConfig {
listen := i.Listen
if listen != "" {
listen = fmt.Sprintf("\"%v\"", listen)
}
return &xray.InboundConfig{
Listen: json_util.RawMessage(i.Listen),
Listen: json_util.RawMessage(listen),
Port: i.Port,
Protocol: string(i.Protocol),
Settings: json_util.RawMessage(i.Settings),
Expand Down
7 changes: 2 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ import (
"x-ui/web/service"
)

// this function call global.setWebServer
func setWebServer(server global.WebServer)

func runWebServer() {
log.Printf("%v %v", config.GetName(), config.GetVersion())

Expand All @@ -45,7 +42,7 @@ func runWebServer() {
var server *web.Server

server = web.NewServer()
setWebServer(server)
global.SetWebServer(server)
err = server.Start()
if err != nil {
log.Println(err)
Expand All @@ -60,7 +57,7 @@ func runWebServer() {
if sig == syscall.SIGHUP {
server.Stop()
server = web.NewServer()
setWebServer(server)
global.SetWebServer(server)
err = server.Start()
if err != nil {
log.Println(err)
Expand Down
9 changes: 9 additions & 0 deletions web/assets/js/model/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class DBInbound {
userId = 0;
up = 0;
down = 0;
total = 0;
remark = "";
enable = true;
expiryTime = 0;
Expand All @@ -45,6 +46,14 @@ class DBInbound {
ObjectUtil.cloneProps(this, data);
}

get totalGB() {
return toFixed(this.total / ONE_GB, 2);
}

set totalGB(gb) {
this.total = toFixed(gb * ONE_GB, 0);
}

toInbound() {
let settings = {};
if (!ObjectUtil.isEmpty(this.settings)) {
Expand Down
2 changes: 1 addition & 1 deletion web/assets/js/util/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ class ObjectUtil {
return false;
}
}
return true
return true;
}

}
3 changes: 1 addition & 2 deletions web/global/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ type WebServer interface {
GetCtx() context.Context
}

//go:linkname setWebServer main.setWebServer
func setWebServer(s WebServer) {
func SetWebServer(s WebServer) {
webServer = s
}

Expand Down
12 changes: 12 additions & 0 deletions web/html/xui/form/inbound.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@
<a-form-item label="端口">
<a-input type="number" v-model.number="inbound.port"></a-input>
</a-form-item>
<a-form-item>
<span slot="label">
总流量(GB)
<a-tooltip>
<template slot="title">
0 表示不限制
</template>
<a-icon type="question-circle" theme="filled"></a-icon>
</a-tooltip>
</span>
<a-input-number v-model="dbInbound.totalGB" :min="0"></a-input-number>
</a-form-item>
</a-form>

<!-- vmess settings -->
Expand Down
55 changes: 39 additions & 16 deletions web/html/xui/inbounds.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@
<a-card hoverable style="margin-bottom: 20px;">
<a-row>
<a-col :xs="24" :sm="24" :lg="12">
upload / download
总上传 / 下载
<a-tag color="green">[[ sizeFormat(total.up) ]] / [[ sizeFormat(total.down) ]]</a-tag>
</a-col>
<a-col :xs="24" :sm="24" :lg="12">
total traffic
总用量
<a-tag color="green">[[ sizeFormat(total.up + total.down) ]]</a-tag>
</a-col>
<a-col :xs="24" :sm="24" :lg="12">
number of accounts
入站数量
<a-tag color="green">[[ dbInbounds.length ]]</a-tag>
</a-col>
</a-row>
Expand All @@ -59,6 +59,8 @@
<template slot="traffic" slot-scope="text, dbInbound">
<a-tag color="blue">[[ sizeFormat(dbInbound.up) ]]</a-tag>
<a-tag color="green">[[ sizeFormat(dbInbound.down) ]]</a-tag>
<a-tag v-if="dbInbound.total > 0" color="cyan">[[ sizeFormat(dbInbound.total) ]]</a-tag>
<a-tag v-else color="cyan">无限制</a-tag>
</template>
<template slot="settings" slot-scope="text, dbInbound">
<a-button type="link">查看</a-button>
Expand All @@ -76,6 +78,7 @@
<template slot="action" slot-scope="text, dbInbound">
<a-button v-if="dbInbound.hasLink()" type="primary" icon="qrcode" @click="showQrcode(dbInbound)"></a-button>
<a-button type="primary" icon="edit" @click="openEditInbound(dbInbound)"></a-button>
<a-button icon="retweet" @click="resetTraffic(dbInbound)"></a-button>
<a-button type="danger" icon="delete" @click="delInbound(dbInbound)"></a-button>
</template>
</a-table>
Expand All @@ -94,17 +97,17 @@
dataIndex: "id",
width: 60,
}, {
title: "protocol",
title: "协议",
align: 'center',
width: 60,
scopedSlots: { customRender: 'protocol' },
}, {
title: "port",
title: "端口",
align: 'center',
dataIndex: "port",
width: 60,
}, {
title: "traffic",
title: "流量↑|↓",
align: 'center',
width: 60,
scopedSlots: { customRender: 'traffic' },
Expand All @@ -119,7 +122,7 @@
// width: 60,
// scopedSlots: { customRender: 'streamSettings' },
}, {
title: "enable",
title: "启用",
align: 'center',
width: 60,
scopedSlots: { customRender: 'enable' },
Expand Down Expand Up @@ -172,8 +175,8 @@
},
openAddInbound() {
inModal.show({
title: 'add account',
okText: 'add',
title: '添加入站',
okText: '添加',
confirm: async (inbound, dbInbound) => {
inModal.loading();
await this.addInbound(inbound, dbInbound);
Expand All @@ -184,8 +187,8 @@
openEditInbound(dbInbound) {
const inbound = dbInbound.toInbound();
inModal.show({
title: 'update account',
okText: 'update',
title: '修改入站',
okText: '修改',
inbound: inbound,
dbInbound: dbInbound,
confirm: async (inbound, dbInbound) => {
Expand All @@ -197,6 +200,9 @@
},
async addInbound(inbound, dbInbound) {
const data = {
up: dbInbound.up,
down: dbInbound.down,
total: dbInbound.total,
remark: dbInbound.remark,
enable: dbInbound.enable,

Expand All @@ -211,6 +217,9 @@
},
async updateInbound(inbound, dbInbound) {
const data = {
up: dbInbound.up,
down: dbInbound.down,
total: dbInbound.total,
remark: dbInbound.remark,
enable: dbInbound.enable,

Expand All @@ -223,18 +232,32 @@
};
await this.submit(`/xui/inbound/update/${dbInbound.id}`, data, inModal);
},
resetTraffic(dbInbound) {
this.$confirm({
title: '重置流量',
content: '确定要重置流量吗?',
okText: '重置',
cancelText: '取消',
onOk: () => {
const inbound = dbInbound.toInbound();
dbInbound.up = 0;
dbInbound.down = 0;
this.updateInbound(inbound, dbInbound);
},
});
},
delInbound(dbInbound) {
this.$confirm({
title: 'delete account',
content: 'Cannot be restored after deletion, confirm deletion?',
okText: 'delete',
cancelText: 'cancel',
title: '删除入站',
content: '确定要删除入站吗?',
okText: '删除',
cancelText: '取消',
onOk: () => this.submit('/xui/inbound/del/' + dbInbound.id),
});
},
showQrcode(dbInbound) {
let address = location.hostname;
if (!ObjectUtil.isEmpty(dbInbound.listen) || dbInbound.listen !== "0.0.0.0") {
if (!ObjectUtil.isEmpty(dbInbound.listen) && dbInbound.listen !== "0.0.0.0") {
address = dbInbound.listen;
}
const link = dbInbound.genLink(address);
Expand Down
13 changes: 13 additions & 0 deletions web/service/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) error {
if err != nil {
return err
}
oldInbound.Up = inbound.Up
oldInbound.Down = inbound.Down
oldInbound.Total = inbound.Total
oldInbound.Remark = inbound.Remark
oldInbound.Enable = inbound.Enable
oldInbound.ExpiryTime = inbound.ExpiryTime
Expand Down Expand Up @@ -98,3 +101,13 @@ func (s *InboundService) AddTraffic(traffics []*xray.Traffic) (err error) {
}
return
}

func (s *InboundService) DisableInvalidInbounds() (bool, error) {
db := database.GetDB()
result := db.Model(model.Inbound{}).
Where("up + down >= total and total > 0 and enable = ?", true).
Update("enable", false)
err := result.Error
count := result.RowsAffected
return count > 0, err
}
Loading

0 comments on commit 214b217

Please sign in to comment.