Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHo3ein <ho3ein.sanaei@gmail.com>2023-04-18 20:40:33 +0300
committerGitHub <noreply@github.com>2023-04-18 20:40:33 +0300
commitdc7dbae14a37492ac3a7e3822b3e0b250e248173 (patch)
tree85160488f60dd4995ea4fb3798af9e9c2fb5305a
parentee2089257a504d153cf180e7c8ffc41a46701552 (diff)
parentdd8c763b21f6f4823e7a3ee418b348775bf51b5d (diff)
Merge pull request #266 from hamid-gh98/main
[Support] change settings by different items in panel
-rw-r--r--.github/workflows/release.yml8
-rw-r--r--.gitignore2
-rw-r--r--README.md105
-rw-r--r--media/configs/traffic+block-ads+ipv4-google.json88
-rw-r--r--media/configs/traffic+block-ads+warp.json98
-rw-r--r--media/configs/traffic+block-iran-domains.json (renamed from media/enable-traffic+block-IR-domain.txt)54
-rw-r--r--media/configs/traffic+block-iran-ip.json (renamed from media/enable-traffic+block-IR-IP.txt)56
-rw-r--r--media/configs/traffic.json (renamed from media/enable-traffic.txt)45
-rw-r--r--web/controller/setting.go10
-rw-r--r--web/html/xui/setting.html943
-rw-r--r--web/service/config.json45
-rw-r--r--web/service/setting.go10
-rw-r--r--web/translation/translate.en_US.toml43
-rw-r--r--web/translation/translate.fa_IR.toml47
-rw-r--r--web/translation/translate.zh_Hans.toml43
-rw-r--r--x-ui.sh211
16 files changed, 1225 insertions, 583 deletions
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 083180ff..39bd9aaa 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -14,7 +14,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4.0.0
with:
- go-version: 'stable'
+ go-version: "stable"
- name: build linux amd64 version
run: |
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o xui-release -v main.go
@@ -28,7 +28,7 @@ jobs:
cd bin
wget https://github.com/mhsanaei/Xray-core/releases/latest/download/Xray-linux-64.zip
unzip Xray-linux-64.zip
- rm -f Xray-linux-64.zip geoip.dat geosite.dat
+ rm -f Xray-linux-64.zip geoip.dat geosite.dat iran.dat
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
wget https://github.com/bootmortis/iran-hosted-domains/releases/latest/download/iran.dat
@@ -54,7 +54,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4.0.0
with:
- go-version: 'stable'
+ go-version: "stable"
- name: build linux arm64 version
run: |
sudo apt-get update
@@ -70,7 +70,7 @@ jobs:
cd bin
wget https://github.com/mhsanaei/xray-core/releases/latest/download/Xray-linux-arm64-v8a.zip
unzip Xray-linux-arm64-v8a.zip
- rm -f Xray-linux-arm64-v8a.zip geoip.dat geosite.dat
+ rm -f Xray-linux-arm64-v8a.zip geoip.dat geosite.dat iran.dat
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
wget https://github.com/bootmortis/iran-hosted-domains/releases/latest/download/iran.dat
diff --git a/.gitignore b/.gitignore
index 7136428c..7ba03558 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
.idea
tmp
+backup/
bin/
dist/
x-ui-*.tar.gz
@@ -9,4 +10,5 @@ x-ui-*.tar.gz
main
release/
access.log
+error.log
.cache
diff --git a/README.md b/README.md
index c6fdf66e..8519b64e 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,14 @@
# 3x-ui
+
[![](https://img.shields.io/github/v/release/mhsanaei/3x-ui.svg)](https://github.com/MHSanaei/3x-ui/releases)
[![](https://img.shields.io/github/actions/workflow/status/mhsanaei/3x-ui/release.yml.svg)](#)
[![GO Version](https://img.shields.io/github/go-mod/go-version/mhsanaei/3x-ui.svg)](#)
[![Downloads](https://img.shields.io/github/downloads/mhsanaei/3x-ui/total.svg)](#)
[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0.en.html)
-
> **Disclaimer: This project is only for personal learning and communication, please do not use it for illegal purposes, please do not use it in a production environment**
-**If you think this project is helpful to you, you may wish to give a** :star2:
+**If you think this project is helpful to you, you may wish to give a** :star2:
xray panel supporting multi-protocol, **Multi-lang (English,Farsi,Chinese)**
@@ -17,20 +17,23 @@ xray panel supporting multi-protocol, **Multi-lang (English,Farsi,Chinese)**
```
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
```
+
## Install custom version
+
To install your desired version you can add the version to the end of install command. Example for ver `v1.0.9`:
+
```
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v1.0.9
```
+
# SSL
+
```
apt-get install certbot -y
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
certbot renew --dry-run
```
-
-
# Default settings
- Port: 2053
@@ -38,18 +41,57 @@ certbot renew --dry-run
- database path: /etc/x-ui/x-ui.db
- xray config path: /usr/local/x-ui/bin/config.json
-before you set ssl on settings
-- http:// ip or domain:2053/xui
+Before you set ssl on settings
+
+- http://ip:2053/xui
+- http://domain:2053/xui
+
+After you set ssl on settings
-After you set ssl on settings
- https://yourdomain:2053/xui
-# Enable Traffic For Users:
+# Environment Variables
+
+| Variable | Type | Default |
+| -------------- | :--------------------------------------------: | :------------ |
+| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
+| XUI_DEBUG | `boolean` | `false` |
+| XUI_BIN_FOLDER | `string` | `"bin"` |
+| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
+
+Example:
+
+```sh
+XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
+```
+
+# Xray Configurations:
**copy and paste to xray Configuration :** (you don't need to do this if you have a fresh install)
-- [enable traffic](./media/enable-traffic.txt)
-- [enable traffic+block all IR IP address](./media/enable-traffic+block-IR-IP.txt)
-- [enable traffic+block all IR domain](./media/enable-traffic+block-IR-domain.txt)
+
+- [traffic](./media/configs/traffic.json)
+- [traffic + Block all Iran IP address](./media/configs/traffic+block-iran-ip.json)
+- [traffic + Block all Iran Domains](./media/configs/traffic+block-iran-domains.json)
+- [traffic + Block Ads + Use IPv4 for Google](./media/configs/traffic+block-ads+ipv4-google.json)
+- [traffic + Block Ads + Route Google + Netflix + Spotify + OpenAI (ChatGPT) to WARP](./media/configs/traffic+block-ads+warp.json)
+
+# [WARP Configuration](https://github.com/fscarmen/warp) (Optional)
+
+If you want to use routing to WARP follow steps as below:
+
+1. Install WARP on **socks proxy mode**:
+
+ ```sh
+ curl -fsSL https://gist.githubusercontent.com/hamid-gh98/dc5dd9b0cc5b0412af927b1ccdb294c7/raw/install_warp_proxy.sh | bash
+ ```
+
+2. Turn on the config you need in panel or [Copy and paste this file to Xray Configuration](./media/configs/traffic+block-ads+warp.json)
+
+ Config Features:
+
+ - Block Ads
+ - Route Google + Netflix + Spotify + OpenAI (ChatGPT) to WARP
+ - Fix Google 403 error
# Features
@@ -64,7 +106,8 @@ After you set ssl on settings
- Support https access panel (self-provided domain name + ssl certificate)
- Support one-click SSL certificate application and automatic renewal
- For more advanced configuration items, please refer to the panel
-- fix api routes (user setting will create with api)
+- Fix api routes (user setting will create with api)
+- Support to change configs by different items provided in panel
# Tg robot use
@@ -81,8 +124,8 @@ Set the robot-related parameters in the panel background, including:
Reference syntax:
-- 30 * * * * * //Notify at the 30s of each point
-- 0 */10 * * * * //Notify at the first second of each 10 minutes
+- 30 \* \* \* \* \* //Notify at the 30s of each point
+- 0 \*/10 \* \* \* \* //Notify at the first second of each 10 minutes
- @hourly // hourly notification
- @daily // Daily notification (00:00 in the morning)
- @every 8h // notify every 8 hours
@@ -102,33 +145,34 @@ Reference syntax:
- Check depleted users
- Receive backup by request and in periodic reports
-
## API routes
- `/login` with `PUSH` user data: `{username: '', password: ''}` for login
- `/xui/API/inbounds` base for following actions:
-| Method | Path | Action |
-| ------------- | ------------- | ------------- |
-| GET | "/list" | Get all inbounds |
-| GET | "/get/:id" | Get inbound with inbound.id |
-| POST | "/add" | Add inbound |
-| POST | "/del/:id" | Delete Inbound |
-| POST | "/update/:id" | Update Inbound |
-| POST | "/clientIps/:email" | Client Ip address |
-| POST | "/clearClientIps/:email" | Clear Client Ip address |
-| POST | "/addClient/" | Add Client to inbound |
-| POST | "/delClient/:email" | Delete Client |
-| POST | "/updateClient/:index" | Update Client |
-| POST | "/:id/resetClientTraffic/:email" | Reset Client's Traffic |
-| POST | "/resetAllTraffics" | Reset traffics of all inbounds |
-| POST | "/resetAllClientTraffics/:id" | Reset traffics of all clients in an inbound |
+| Method | Path | Action |
+| :----: | ---------------------------------- | ------------------------------------------- |
+| `GET` | `"/list"` | Get all inbounds |
+| `GET` | `"/get/:id"` | Get inbound with inbound.id |
+| `POST` | `"/add"` | Add inbound |
+| `POST` | `"/del/:id"` | Delete Inbound |
+| `POST` | `"/update/:id"` | Update Inbound |
+| `POST` | `"/clientIps/:email"` | Client Ip address |
+| `POST` | `"/clearClientIps/:email"` | Clear Client Ip address |
+| `POST` | `"/addClient/"` | Add Client to inbound |
+| `POST` | `"/delClient/:email"` | Delete Client |
+| `POST` | `"/updateClient/:index"` | Update Client |
+| `POST` | `"/:id/resetClientTraffic/:email"` | Reset Client's Traffic |
+| `POST` | `"/resetAllTraffics"` | Reset traffics of all inbounds |
+| `POST` | `"/resetAllClientTraffics/:id"` | Reset traffics of all clients in an inbound |
# A Special Thanks To
+
- [alireza0](https://github.com/alireza0/)
- [FranzKafkaYu](https://github.com/FranzKafkaYu)
# Suggestion System
+
- Ubuntu 20.04+
- Debian 10+
- CentOS 8+
@@ -137,6 +181,7 @@ Reference syntax:
# Buy Me a Coffee
[![](https://img.shields.io/badge/Wallet-USDT__TRC20-green.svg)](#)
+
```
TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC
```
diff --git a/media/configs/traffic+block-ads+ipv4-google.json b/media/configs/traffic+block-ads+ipv4-google.json
new file mode 100644
index 00000000..d2ca2d45
--- /dev/null
+++ b/media/configs/traffic+block-ads+ipv4-google.json
@@ -0,0 +1,88 @@
+{
+ "log": {
+ "loglevel": "warning",
+ "access": "./access.log",
+ "error": "./error.log"
+ },
+ "api": {
+ "tag": "api",
+ "services": ["HandlerService", "LoggerService", "StatsService"]
+ },
+ "inbounds": [
+ {
+ "tag": "api",
+ "listen": "127.0.0.1",
+ "port": 62789,
+ "protocol": "dokodemo-door",
+ "settings": {
+ "address": "127.0.0.1"
+ }
+ }
+ ],
+ "outbounds": [
+ {
+ "protocol": "freedom",
+ "settings": {}
+ },
+ {
+ "tag": "blocked",
+ "protocol": "blackhole",
+ "settings": {}
+ },
+ {
+ "tag": "IPv4",
+ "protocol": "freedom",
+ "settings": {
+ "domainStrategy": "UseIPv4"
+ }
+ }
+ ],
+ "policy": {
+ "levels": {
+ "0": {
+ "statsUserDownlink": true,
+ "statsUserUplink": true
+ }
+ },
+ "system": {
+ "statsInboundDownlink": true,
+ "statsInboundUplink": true
+ }
+ },
+ "routing": {
+ "domainStrategy": "IPIfNonMatch",
+ "rules": [
+ {
+ "type": "field",
+ "inboundTag": ["api"],
+ "outboundTag": "api"
+ },
+ {
+ "type": "field",
+ "outboundTag": "blocked",
+ "ip": ["geoip:private"]
+ },
+ {
+ "type": "field",
+ "outboundTag": "blocked",
+ "protocol": ["bittorrent"]
+ },
+ {
+ "type": "field",
+ "outboundTag": "blocked",
+ "domain": [
+ "geosite:category-ads-all",
+ "geosite:category-ads",
+ "geosite:google-ads",
+ "geosite:spotify-ads"
+ ]
+ },
+ {
+ "type": "field",
+ "outboundTag": "IPv4",
+ "domain": ["geosite:google"]
+ }
+ ]
+ },
+ "stats": {}
+}
diff --git a/media/configs/traffic+block-ads+warp.json b/media/configs/traffic+block-ads+warp.json
new file mode 100644
index 00000000..504a8481
--- /dev/null
+++ b/media/configs/traffic+block-ads+warp.json
@@ -0,0 +1,98 @@
+{
+ "log": {
+ "loglevel": "warning",
+ "access": "./access.log",
+ "error": "./error.log"
+ },
+ "api": {
+ "tag": "api",
+ "services": ["HandlerService", "LoggerService", "StatsService"]
+ },
+ "inbounds": [
+ {
+ "tag": "api",
+ "listen": "127.0.0.1",
+ "port": 62789,
+ "protocol": "dokodemo-door",
+ "settings": {
+ "address": "127.0.0.1"
+ }
+ }
+ ],
+ "outbounds": [
+ {
+ "protocol": "freedom",
+ "settings": {}
+ },
+ {
+ "tag": "blocked",
+ "protocol": "blackhole",
+ "settings": {}
+ },
+ {
+ "tag": "WARP",
+ "protocol": "socks",
+ "settings": {
+ "servers": [
+ {
+ "address": "127.0.0.1",
+ "port": 40000
+ }
+ ]
+ }
+ }
+ ],
+ "policy": {
+ "levels": {
+ "0": {
+ "statsUserDownlink": true,
+ "statsUserUplink": true
+ }
+ },
+ "system": {
+ "statsInboundDownlink": true,
+ "statsInboundUplink": true
+ }
+ },
+ "routing": {
+ "domainStrategy": "IPIfNonMatch",
+ "rules": [
+ {
+ "type": "field",
+ "inboundTag": ["api"],
+ "outboundTag": "api"
+ },
+ {
+ "type": "field",
+ "outboundTag": "blocked",
+ "ip": ["geoip:private"]
+ },
+ {
+ "type": "field",
+ "outboundTag": "blocked",
+ "protocol": ["bittorrent"]
+ },
+ {
+ "type": "field",
+ "outboundTag": "blocked",
+ "domain": [
+ "geosite:category-ads-all",
+ "geosite:category-ads",
+ "geosite:google-ads",
+ "geosite:spotify-ads"
+ ]
+ },
+ {
+ "type": "field",
+ "outboundTag": "WARP",
+ "domain": [
+ "geosite:google",
+ "geosite:netflix",
+ "geosite:spotify",
+ "geosite:openai"
+ ]
+ }
+ ]
+ },
+ "stats": {}
+}
diff --git a/media/enable-traffic+block-IR-domain.txt b/media/configs/traffic+block-iran-domains.json
index 4fcf3ee7..b6f05704 100644
--- a/media/enable-traffic+block-IR-domain.txt
+++ b/media/configs/traffic+block-iran-domains.json
@@ -1,25 +1,22 @@
{
"log": {
"loglevel": "warning",
- "access": "./access.log"
+ "access": "./access.log",
+ "error": "./error.log"
},
"api": {
- "services": [
- "HandlerService",
- "LoggerService",
- "StatsService"
- ],
- "tag": "api"
+ "tag": "api",
+ "services": ["HandlerService", "LoggerService", "StatsService"]
},
"inbounds": [
{
+ "tag": "api",
"listen": "127.0.0.1",
"port": 62789,
"protocol": "dokodemo-door",
"settings": {
"address": "127.0.0.1"
- },
- "tag": "api"
+ }
}
],
"outbounds": [
@@ -28,16 +25,16 @@
"settings": {}
},
{
+ "tag": "blocked",
"protocol": "blackhole",
- "settings": {},
- "tag": "blocked"
+ "settings": {}
}
],
"policy": {
"levels": {
"0": {
- "statsUserUplink": true,
- "statsUserDownlink": true
+ "statsUserDownlink": true,
+ "statsUserUplink": true
}
},
"system": {
@@ -49,36 +46,31 @@
"domainStrategy": "IPIfNonMatch",
"rules": [
{
- "inboundTag": [
- "api"
- ],
- "outboundTag": "api",
- "type": "field"
+ "type": "field",
+ "inboundTag": ["api"],
+ "outboundTag": "api"
},
{
- "ip": [
- "geoip:private"
- ],
+ "type": "field",
"outboundTag": "blocked",
- "type": "field"
+ "ip": ["geoip:private"]
},
{
+ "type": "field",
"outboundTag": "blocked",
- "protocol": [
- "bittorrent"
- ],
- "type": "field"
+ "protocol": ["bittorrent"]
},
{
+ "type": "field",
"outboundTag": "blocked",
"domain": [
- "regexp:.+.ir$",
+ "regexp:.*\\.ir$",
"ext:iran.dat:ir",
- "ext:iran.dat:other"
- ],
- "type": "field"
+ "ext:iran.dat:other",
+ "geosite:category-ir"
+ ]
}
]
},
"stats": {}
-} \ No newline at end of file
+}
diff --git a/media/enable-traffic+block-IR-IP.txt b/media/configs/traffic+block-iran-ip.json
index 919bef03..103ca700 100644
--- a/media/enable-traffic+block-IR-IP.txt
+++ b/media/configs/traffic+block-iran-ip.json
@@ -1,25 +1,22 @@
{
"log": {
"loglevel": "warning",
- "access": "./access.log"
+ "access": "./access.log",
+ "error": "./error.log"
},
"api": {
- "services": [
- "HandlerService",
- "LoggerService",
- "StatsService"
- ],
- "tag": "api"
+ "tag": "api",
+ "services": ["HandlerService", "LoggerService", "StatsService"]
},
"inbounds": [
{
+ "tag": "api",
"listen": "127.0.0.1",
"port": 62789,
"protocol": "dokodemo-door",
"settings": {
"address": "127.0.0.1"
- },
- "tag": "api"
+ }
}
],
"outbounds": [
@@ -28,16 +25,16 @@
"settings": {}
},
{
+ "tag": "blocked",
"protocol": "blackhole",
- "settings": {},
- "tag": "blocked"
+ "settings": {}
}
],
"policy": {
"levels": {
"0": {
- "statsUserUplink": true,
- "statsUserDownlink": true
+ "statsUserDownlink": true,
+ "statsUserUplink": true
}
},
"system": {
@@ -49,34 +46,31 @@
"domainStrategy": "IPIfNonMatch",
"rules": [
{
- "inboundTag": [
- "api"
- ],
- "outboundTag": "api",
- "type": "field"
+ "type": "field",
+ "inboundTag": ["api"],
+ "outboundTag": "api"
+ },
+ {
+ "type": "field",
+ "outboundTag": "blocked",
+ "ip": ["geoip:private"]
},
{
+ "type": "field",
"outboundTag": "blocked",
- "protocol": [
- "bittorrent"
- ],
- "type": "field"
+ "protocol": ["bittorrent"]
},
{
+ "type": "field",
"outboundTag": "blocked",
- "ip": [
- "geoip:private"
- ],
- "type": "field"
+ "ip": ["geoip:private"]
},
{
+ "type": "field",
"outboundTag": "blocked",
- "ip": [
- "geoip:ir"
- ],
- "type": "field"
+ "ip": ["geoip:ir"]
}
]
},
"stats": {}
-} \ No newline at end of file
+}
diff --git a/media/enable-traffic.txt b/media/configs/traffic.json
index 34e2038f..9d8d2d9f 100644
--- a/media/enable-traffic.txt
+++ b/media/configs/traffic.json
@@ -1,25 +1,22 @@
{
"log": {
"loglevel": "warning",
- "access": "./access.log"
+ "access": "./access.log",
+ "error": "./error.log"
},
"api": {
- "services": [
- "HandlerService",
- "LoggerService",
- "StatsService"
- ],
- "tag": "api"
+ "tag": "api",
+ "services": ["HandlerService", "LoggerService", "StatsService"]
},
"inbounds": [
{
+ "tag": "api",
"listen": "127.0.0.1",
"port": 62789,
"protocol": "dokodemo-door",
"settings": {
"address": "127.0.0.1"
- },
- "tag": "api"
+ }
}
],
"outbounds": [
@@ -28,16 +25,16 @@
"settings": {}
},
{
+ "tag": "blocked",
"protocol": "blackhole",
- "settings": {},
- "tag": "blocked"
+ "settings": {}
}
],
"policy": {
"levels": {
"0": {
- "statsUserUplink": true,
- "statsUserDownlink": true
+ "statsUserDownlink": true,
+ "statsUserUplink": true
}
},
"system": {
@@ -49,27 +46,21 @@
"domainStrategy": "IPIfNonMatch",
"rules": [
{
- "inboundTag": [
- "api"
- ],
- "outboundTag": "api",
- "type": "field"
+ "type": "field",
+ "inboundTag": ["api"],
+ "outboundTag": "api"
},
{
+ "type": "field",
"outboundTag": "blocked",
- "ip": [
- "geoip:private"
- ],
- "type": "field"
+ "ip": ["geoip:private"]
},
{
+ "type": "field",
"outboundTag": "blocked",
- "protocol": [
- "bittorrent"
- ],
- "type": "field"
+ "protocol": ["bittorrent"]
}
]
},
"stats": {}
-} \ No newline at end of file
+}
diff --git a/web/controller/setting.go b/web/controller/setting.go
index 261eeec8..1de55ab6 100644
--- a/web/controller/setting.go
+++ b/web/controller/setting.go
@@ -37,6 +37,7 @@ func (a *SettingController) initRouter(g *gin.RouterGroup) {
g.POST("/update", a.updateSetting)
g.POST("/updateUser", a.updateUser)
g.POST("/restartPanel", a.restartPanel)
+ g.GET("/getDefaultJsonConfig", a.getDefaultJsonConfig)
}
func (a *SettingController) getAllSetting(c *gin.Context) {
@@ -48,6 +49,15 @@ func (a *SettingController) getAllSetting(c *gin.Context) {
jsonObj(c, allSetting, nil)
}
+func (a *SettingController) getDefaultJsonConfig(c *gin.Context) {
+ defaultJsonConfig, err := a.settingService.GetDefaultJsonConfig()
+ if err != nil {
+ jsonMsg(c, I18n(c, "pages.setting.toasts.getSetting"), err)
+ return
+ }
+ jsonObj(c, defaultJsonConfig, nil)
+}
+
func (a *SettingController) getDefaultSettings(c *gin.Context) {
expireDiff, err := a.settingService.GetExpireDiff()
if err != nil {
diff --git a/web/html/xui/setting.html b/web/html/xui/setting.html
index 0218aea8..e10737e0 100644
--- a/web/html/xui/setting.html
+++ b/web/html/xui/setting.html
@@ -24,356 +24,675 @@
background: white;
}
</style>
+
<body>
-<a-layout id="app" v-cloak>
- {{ template "commonSider" . }}
- <a-layout id="content-layout" :style="siderDrawer.isDarkTheme ? bgDarkStyle : ''">
- <a-layout-content>
- <a-spin :spinning="spinning" :delay="500" tip="loading">
- <a-space direction="vertical">
- <a-space direction="horizontal">
- <a-button type="primary" :disabled="saveBtnDisable" @click="updateAllSetting">{{ i18n "pages.setting.save" }}</a-button>
- <a-button type="danger" :disabled="!saveBtnDisable" @click="restartPanel">{{ i18n "pages.setting.restartPanel" }}</a-button>
- </a-space>
- <a-tabs default-active-key="1" :class="siderDrawer.isDarkTheme ? darkClass : ''">
- <a-tab-pane key="1" tab='{{ i18n "pages.setting.panelConfig"}}'>
+ <a-layout id="app" v-cloak>
+ {{ template "commonSider" . }}
+ <a-layout id="content-layout" :style="siderDrawer.isDarkTheme ? bgDarkStyle : ''">
+ <a-layout-content>
+ <a-spin :spinning="spinning" :delay="500" tip="loading">
+ <a-space direction="vertical">
+ <a-space direction="horizontal">
+ <a-button type="primary" :disabled="saveBtnDisable" @click="updateAllSetting">{{ i18n "pages.setting.save" }}</a-button>
+ <a-button type="danger" :disabled="!saveBtnDisable" @click="restartPanel">{{ i18n "pages.setting.restartPanel" }}</a-button>
+ </a-space>
- <a-list item-layout="horizontal" :style="siderDrawer.isDarkTheme ? 'color: hsla(0,0%,100%,.65);': 'background: white;'">
- <setting-list-item type="text" title='{{ i18n "pages.setting.panelListeningIP"}}' desc='{{ i18n "pages.setting.panelListeningIPDesc"}}' v-model="allSetting.webListen"></setting-list-item>
- <setting-list-item type="number" title='{{ i18n "pages.setting.panelPort"}}' desc='{{ i18n "pages.setting.panelPortDesc"}}' v-model.number="allSetting.webPort"></setting-list-item>
- <setting-list-item type="text" title='{{ i18n "pages.setting.publicKeyPath"}}' desc='{{ i18n "pages.setting.publicKeyPathDesc"}}' v-model="allSetting.webCertFile"></setting-list-item>
- <setting-list-item type="text" title='{{ i18n "pages.setting.privateKeyPath"}}' desc='{{ i18n "pages.setting.privateKeyPathDesc"}}' v-model="allSetting.webKeyFile"></setting-list-item>
- <setting-list-item type="text" title='{{ i18n "pages.setting.panelUrlPath"}}' desc='{{ i18n "pages.setting.panelUrlPathDesc"}}' v-model="allSetting.webBasePath"></setting-list-item>
- <setting-list-item type="number" title='{{ i18n "pages.setting.expireTimeDiff" }}' desc='{{ i18n "pages.setting.expireTimeDiffDesc" }}' v-model="allSetting.expireDiff" :min="0"></setting-list-item>
- <setting-list-item type="number" title='{{ i18n "pages.setting.trafficDiff" }}' desc='{{ i18n "pages.setting.trafficDiffDesc" }}' v-model="allSetting.trafficDiff" :min="0"></setting-list-item>
- <a-list-item>
- <a-row style="padding: 20px">
- <a-col :lg="24" :xl="12">
- <a-list-item-meta title="Language"/>
- </a-col>
- <a-col :lg="24" :xl="12">
- <template>
- <a-select
+ <a-tabs default-active-key="1" :class="siderDrawer.isDarkTheme ? darkClass : ''">
+ <a-tab-pane key="1" tab='{{ i18n "pages.setting.panelConfig"}}'>
+ <a-list item-layout="horizontal" :style="siderDrawer.isDarkTheme ? 'color: hsla(0,0%,100%,.65);': 'background: white;'">
+ <setting-list-item type="text" title='{{ i18n "pages.setting.panelListeningIP"}}' desc='{{ i18n "pages.setting.panelListeningIPDesc"}}' v-model="allSetting.webListen"></setting-list-item>
+ <setting-list-item type="number" title='{{ i18n "pages.setting.panelPort"}}' desc='{{ i18n "pages.setting.panelPortDesc"}}' v-model.number="allSetting.webPort"></setting-list-item>
+ <setting-list-item type="text" title='{{ i18n "pages.setting.publicKeyPath"}}' desc='{{ i18n "pages.setting.publicKeyPathDesc"}}' v-model="allSetting.webCertFile"></setting-list-item>
+ <setting-list-item type="text" title='{{ i18n "pages.setting.privateKeyPath"}}' desc='{{ i18n "pages.setting.privateKeyPathDesc"}}' v-model="allSetting.webKeyFile"></setting-list-item>
+ <setting-list-item type="text" title='{{ i18n "pages.setting.panelUrlPath"}}' desc='{{ i18n "pages.setting.panelUrlPathDesc"}}' v-model="allSetting.webBasePath"></setting-list-item>
+ <setting-list-item type="number" title='{{ i18n "pages.setting.expireTimeDiff" }}' desc='{{ i18n "pages.setting.expireTimeDiffDesc" }}' v-model="allSetting.expireDiff" :min="0"></setting-list-item>
+ <setting-list-item type="number" title='{{ i18n "pages.setting.trafficDiff" }}' desc='{{ i18n "pages.setting.trafficDiffDesc" }}' v-model="allSetting.trafficDiff" :min="0"></setting-list-item>
+ <a-list-item>
+ <a-row style="padding: 20px">
+ <a-col :lg="24" :xl="12">
+ <a-list-item-meta title="Language" />
+ </a-col>
+
+ <a-col :lg="24" :xl="12">
+ <template>
+ <a-select
ref="selectLang"
v-model="lang"
@change="setLang(lang)"
:dropdown-class-name="siderDrawer.isDarkTheme ? 'ant-card-dark' : ''"
style="width: 100%"
- >
- <a-select-option :value="l.value" :label="l.value" v-for="l in supportLangs">
- <span role="img" aria-label="l.name" v-text="l.icon"></span>
- &nbsp;&nbsp;<span v-text="l.name"></span>
- </a-select-option>
- </a-select>
- </template>
- </a-col>
- </a-row>
- </a-list-item>
- </a-list>
- </a-tab-pane>
- <a-tab-pane key="2" tab='{{ i18n "pages.setting.userSetting"}}'>
- <a-form :style="siderDrawer.isDarkTheme ? 'color: hsla(0,0%,100%,.65); padding: 20px;': 'background: white; padding: 20px;'">
- <a-form-item label='