0xJacky 3 年之前
父節點
當前提交
278b143360
共有 66 個文件被更改,包括 119 次插入172 次删除
  1. 0 16
      Dockerfile
  2. 63 38
      README.md
  3. 0 12
      build.sh
  4. 0 0
      frontend/dist/index.html
  5. 0 0
      frontend/dist/js/chunk-006e4cbc-legacy.ce4defda.js
  6. 0 0
      frontend/dist/js/chunk-006e4cbc.ce4defda.js
  7. 0 0
      frontend/dist/js/chunk-17d07320-legacy.c9527253.js
  8. 0 0
      frontend/dist/js/chunk-17d07320.c9527253.js
  9. 0 0
      frontend/dist/js/chunk-1e5147a5-legacy.3620bb79.js
  10. 0 0
      frontend/dist/js/chunk-1e5147a5.3620bb79.js
  11. 0 0
      frontend/dist/js/chunk-228c37e8-legacy.f45481a4.js
  12. 0 0
      frontend/dist/js/chunk-228c37e8.f45481a4.js
  13. 0 0
      frontend/dist/js/chunk-2b94df79-legacy.09b591ef.js
  14. 0 0
      frontend/dist/js/chunk-2b94df79-legacy.8dc71139.js
  15. 0 0
      frontend/dist/js/chunk-2b94df79.09b591ef.js
  16. 0 0
      frontend/dist/js/chunk-2b94df79.8dc71139.js
  17. 1 1
      frontend/dist/js/chunk-32df5a7d-legacy.cdbdd8b4.js
  18. 1 1
      frontend/dist/js/chunk-32df5a7d.cdbdd8b4.js
  19. 0 0
      frontend/dist/js/chunk-480a0d56-legacy.ad16eb68.js
  20. 0 0
      frontend/dist/js/chunk-480a0d56.ad16eb68.js
  21. 0 0
      frontend/dist/js/chunk-532b3473-legacy.ccea521d.js
  22. 0 0
      frontend/dist/js/chunk-532b3473.ccea521d.js
  23. 0 0
      frontend/dist/js/chunk-56341220-legacy.34a9fceb.js
  24. 0 0
      frontend/dist/js/chunk-56341220.34a9fceb.js
  25. 0 0
      frontend/dist/js/chunk-59b694c3-legacy.ef41aa76.js
  26. 0 0
      frontend/dist/js/chunk-59b694c3.ef41aa76.js
  27. 1 0
      frontend/dist/js/chunk-680936db-legacy.547a4157.js
  28. 1 0
      frontend/dist/js/chunk-680936db.547a4157.js
  29. 0 0
      frontend/dist/js/chunk-7723cf62-legacy.c3f452ca.js
  30. 0 0
      frontend/dist/js/chunk-7723cf62.c3f452ca.js
  31. 1 1
      frontend/dist/js/chunk-96068e84-legacy.f88847b7.js
  32. 1 1
      frontend/dist/js/chunk-96068e84.f88847b7.js
  33. 0 1
      frontend/dist/js/chunk-d4ac245c-legacy.d0d1ca92.js
  34. 0 1
      frontend/dist/js/chunk-d4ac245c.d0d1ca92.js
  35. 0 0
      frontend/dist/js/chunk-ddbf168e-legacy.82ea029a.js
  36. 0 0
      frontend/dist/js/chunk-ddbf168e.82ea029a.js
  37. 0 0
      frontend/dist/js/chunk-e71b472c-legacy.e8ed19fc.js
  38. 0 0
      frontend/dist/js/chunk-e71b472c.e8ed19fc.js
  39. 0 0
      frontend/dist/js/chunk-vendors-legacy.aa67daf5.js
  40. 0 0
      frontend/dist/js/chunk-vendors.aa67daf5.js
  41. 0 0
      frontend/dist/js/index-legacy.008a35ba.js
  42. 0 0
      frontend/dist/js/index-legacy.b992baa1.js
  43. 0 0
      frontend/dist/js/index.204ef68a.js
  44. 0 0
      frontend/dist/js/index.b951e46d.js
  45. 1 1
      frontend/dist/version.json
  46. 2 2
      frontend/src/components/StdDataDisplay/StdTable.vue
  47. 2 2
      frontend/src/views/Config.vue
  48. 15 13
      frontend/src/views/ConfigEdit.vue
  49. 0 1
      frontend/src/views/DashBoard.vue
  50. 2 2
      frontend/src/views/Domain.vue
  51. 1 1
      frontend/src/views/Login.vue
  52. 26 24
      frontend/src/views/domain_edit/DomainEdit.vue
  53. 1 1
      frontend/version.json
  54. 0 1
      frontend/vue.config.js
  55. 0 20
      install.sh
  56. 0 24
      nginx.conf
  57. 二進制
      screenshots/config-edit.png
  58. 二進制
      screenshots/config-list.png
  59. 二進制
      screenshots/dashboard.png
  60. 二進制
      screenshots/domain-edit.png
  61. 二進制
      screenshots/domain-list.png
  62. 二進制
      screenshots/user-list.png
  63. 二進制
      server/main
  64. 二進制
      server/nginx-ui@linux-amd64
  65. 0 4
      sources.list
  66. 0 4
      start.sh

+ 0 - 16
Dockerfile

@@ -1,16 +0,0 @@
-FROM debian:latest
-
-WORKDIR /app
-
-COPY ./sources.list /etc/apt/sources.list
-RUN echo "installing nginx"
-RUN apt-get update -y && apt install nginx -y
-
-COPY ./start.sh /app/start.sh
-RUN chmod a+x start.sh
-COPY ./server /app/server
-COPY ./html /app/html
-COPY ./nginx.conf /etc/nginx/sites-available/default
-EXPOSE 9180
-
-CMD ["./start.sh"]

+ 63 - 38
README.md

@@ -1,68 +1,93 @@
 # Nginx UI
 Yet another Nginx Web UI
 
-Version: 0.1.1
+Version: 1.0.0
 
 ## 项目特色
 
-1. 可在线查看服务器 CPU、内存、load avarage 等指标
+1. 可在线查看服务器 CPU、内存、load average、磁盘使用率等指标
 2. 可一键申请 Let's encrypt 证书
 3. 在线编辑网站配置文件
 
+## 项目预览
+
+### 登录
+![](screenshots/login.png)
+
+### 仪表盘
+![](screenshots/dashboard.png)
+
+### 用户列表
+![](screenshots/user-list.png)
+
+### 域名列表
+![](screenshots/domain-list.png)
+
+### 域名编辑
+![](screenshots/domain-edit.png)
+
+### 配置列表
+![](screenshots/config-list.png)
+
+### 配置编辑
+![](screenshots/config-edit.png)
+
 ## 使用前注意
 
-Nginx UI 遵循 Nginx 的标准,创建的网站配置文件位于 Nginx 配置目录(自动检测)下的 sites-available 目录,
-启用后的网站的配置文件将会创建一份软连接到 sites-enabled 目录中。因此,您可能需要调整配置文件的组织方式。
+Nginx UI 遵循 Nginx 的标准,创建的网站配置文件位于 Nginx 配置目录(自动检测)下的 `sites-available` 目录,
+启用后的网站的配置文件将会创建一份软连接到 `sites-enabled` 目录中。因此,您可能需要调整配置文件的组织方式。
 
 ## 安装
 1. 克隆项目
-2. 运行 install.sh
-3. 添加配置文件到 nginx
+```
+git clone https://github.com/0xJacky/nginx-ui
+```
+2. 编译后端
+```
+cd server
+go build -o nginx-ui-server main.go
+```
+3. 启动后端
+    1. 前台启动 `./nginx-ui-server`
+    2. 后台启动 `nohup ./nginx-ui-server &`
+
+4. 添加配置文件到 nginx
 ```
 server {
-	listen	80;
-	listen	[::]:80;
+    listen	80;
+    listen	[::]:80;
 
-	server_name	<Your server name>;
+    server_name	<your_server_name>;
     rewrite ^(.*)$  https://$host$1 permanent;
 }
 
 server {
-	listen	443 ssl http2;
-	listen	[::]:443 ssl http2;
+    listen	443 ssl http2;
+    listen	[::]:443 ssl http2;
 
-	server_name	<Your server name>;
+    server_name	<your_server_name>;
 
-	ssl_certificate	/path/to/ssl_cert;
+    ssl_certificate	/path/to/ssl_cert;
     ssl_certificate_key	/path/to/ssl_cert_key;
 
-	root	/path/to/nginx-ui-frontend/dist;
-	
-	index	index.html;
-
-	location /api {
-		    rewrite /api/(.+) /$1 break;
-		    proxy_pass http://127.0.0.1:9000;
-	}
-
-	location /ws/ {
-	      proxy_set_header Host $host;
-          proxy_set_header X-Real_IP $remote_addr;
-          proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
-          proxy_http_version 1.1;
-          proxy_set_header Upgrade $http_upgrade;
-          proxy_set_header Connection upgrade;
-	      proxy_pass http://127.0.0.1:9000/;
-	}
+    root	/path/to/nginx-ui-frontend/dist;
+
+    index	index.html;
+
+    location /api/ {
+        proxy_set_header Host $host;
+        proxy_set_header X-Real_IP $remote_addr;
+        proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection upgrade;
+        proxy_pass http://127.0.0.1:9000/;
+    }
 }
 ```
-4. 添加用户
-  编辑 server/database.db (sqlite3)
 
-  手动计算密码的 md5
+4. 初始化系统
 
-```
-md5 -s <text>
-```
+在浏览器中访问 `https://<your_server_name>/install`
 
-进入 auths 表,添加一行数据 name: 用户名,password: <md5 加密后的明文>
+输入用户名和密码创建初始账户。

+ 0 - 12
build.sh

@@ -1,12 +0,0 @@
-echo "buil frontend"
-cd frontend || exit 1
-yarn build
-cd .. || exit 1
-
-echo "build server"
-cd server || exit 1
-GOOS=linux GOARCH=amd64 go build -o nginx-ui@linux-amd64 main.go
-cd .. || exit 1
-
-echo "build docker"
-docker build -t nginx-ui .

File diff suppressed because it is too large
+ 0 - 0
frontend/dist/index.html


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-006e4cbc-legacy.ce4defda.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-006e4cbc.ce4defda.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-17d07320-legacy.c9527253.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-17d07320.c9527253.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-1e5147a5-legacy.3620bb79.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-1e5147a5.3620bb79.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-228c37e8-legacy.f45481a4.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-228c37e8.f45481a4.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-2b94df79-legacy.09b591ef.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-2b94df79-legacy.8dc71139.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-2b94df79.09b591ef.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-2b94df79.8dc71139.js


File diff suppressed because it is too large
+ 1 - 1
frontend/dist/js/chunk-32df5a7d-legacy.cdbdd8b4.js


File diff suppressed because it is too large
+ 1 - 1
frontend/dist/js/chunk-32df5a7d.cdbdd8b4.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-480a0d56-legacy.ad16eb68.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-480a0d56.ad16eb68.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-532b3473-legacy.ccea521d.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-532b3473.ccea521d.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-56341220-legacy.34a9fceb.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-56341220.34a9fceb.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-59b694c3-legacy.ef41aa76.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-59b694c3.ef41aa76.js


+ 1 - 0
frontend/dist/js/chunk-680936db-legacy.547a4157.js

@@ -0,0 +1 @@
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-680936db"],{"37d1":function(t,n,e){"use strict";e("939c")},"939c":function(t,n,e){var a=e("e78d");a.__esModule&&(a=a.default),"string"===typeof a&&(a=[[t.i,a,""]]),a.locals&&(t.exports=a.locals);var o=e("499e").default;o("29ba208a",a,!0,{sourceMap:!1,shadowMode:!1})},e33d:function(t,n,e){"use strict";e.r(n);var a=function(){var t=this,n=t.$createElement,e=t._self._c||n;return e("a-card",{attrs:{title:"配置文件编辑"}},[e("vue-itextarea",{model:{value:t.configText,callback:function(n){t.configText=n},expression:"configText"}}),e("footer-tool-bar",[e("a-space",[e("a-button",{on:{click:function(n){return t.$router.go(-1)}}},[t._v("返回")]),e("a-button",{attrs:{type:"primary"},on:{click:t.save}},[t._v("保存")])],1)],1)],1)},o=[],i=(e("b0c0"),e("9c70")),c=e("a002"),s={name:"DomainEdit",components:{FooterToolBar:i["a"],VueItextarea:c["a"]},data:function(){return{name:this.$route.params.name,configText:""}},watch:{$route:function(){this.init()},config:{handler:function(){this.unparse()},deep:!0}},created:function(){this.init()},methods:{init:function(){var t=this;this.name?this.$api.config.get(this.name).then((function(n){t.configText=n.config})).catch((function(n){console.log(n),t.$message.error("服务器错误")})):this.configText=""},save:function(){var t=this;this.$api.config.save(this.name?this.name:this.config.name,{content:this.configText}).then((function(n){t.configText=n.config,t.$message.success("保存成功")})).catch((function(n){console.log(n),t.$message.error("保存错误")}))}}},r=s,u=(e("37d1"),e("2877")),f=Object(u["a"])(r,a,o,!1,null,"4076690a",null);n["default"]=f.exports},e78d:function(t,n,e){var a=e("24fb");n=a(!1),n.push([t.i,".ant-card[data-v-4076690a]{margin:10px}@media (max-width:512px){.ant-card[data-v-4076690a]{margin:10px 0}}",""]),t.exports=n}}]);

+ 1 - 0
frontend/dist/js/chunk-680936db.547a4157.js

@@ -0,0 +1 @@
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-680936db"],{"37d1":function(t,n,e){"use strict";e("939c")},"939c":function(t,n,e){var a=e("e78d");a.__esModule&&(a=a.default),"string"===typeof a&&(a=[[t.i,a,""]]),a.locals&&(t.exports=a.locals);var o=e("499e").default;o("29ba208a",a,!0,{sourceMap:!1,shadowMode:!1})},e33d:function(t,n,e){"use strict";e.r(n);var a=function(){var t=this,n=t.$createElement,e=t._self._c||n;return e("a-card",{attrs:{title:"配置文件编辑"}},[e("vue-itextarea",{model:{value:t.configText,callback:function(n){t.configText=n},expression:"configText"}}),e("footer-tool-bar",[e("a-space",[e("a-button",{on:{click:function(n){return t.$router.go(-1)}}},[t._v("返回")]),e("a-button",{attrs:{type:"primary"},on:{click:t.save}},[t._v("保存")])],1)],1)],1)},o=[],i=(e("b0c0"),e("9c70")),c=e("a002"),s={name:"DomainEdit",components:{FooterToolBar:i["a"],VueItextarea:c["a"]},data:function(){return{name:this.$route.params.name,configText:""}},watch:{$route:function(){this.init()},config:{handler:function(){this.unparse()},deep:!0}},created:function(){this.init()},methods:{init:function(){var t=this;this.name?this.$api.config.get(this.name).then((function(n){t.configText=n.config})).catch((function(n){console.log(n),t.$message.error("服务器错误")})):this.configText=""},save:function(){var t=this;this.$api.config.save(this.name?this.name:this.config.name,{content:this.configText}).then((function(n){t.configText=n.config,t.$message.success("保存成功")})).catch((function(n){console.log(n),t.$message.error("保存错误")}))}}},r=s,u=(e("37d1"),e("2877")),f=Object(u["a"])(r,a,o,!1,null,"4076690a",null);n["default"]=f.exports},e78d:function(t,n,e){var a=e("24fb");n=a(!1),n.push([t.i,".ant-card[data-v-4076690a]{margin:10px}@media (max-width:512px){.ant-card[data-v-4076690a]{margin:10px 0}}",""]),t.exports=n}}]);

File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-7723cf62-legacy.c3f452ca.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-7723cf62.c3f452ca.js


+ 1 - 1
frontend/dist/js/chunk-96068e84-legacy.5cf4468c.js → frontend/dist/js/chunk-96068e84-legacy.f88847b7.js

@@ -1 +1 @@
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-96068e84"],{"0d92":function(e,t,a){"use strict";a("e6a6")},"7c22":function(e,t,a){var n=a("24fb");t=n(!1),t.push([e.i,".egg[data-v-0db462a3]{padding:10px 0}.ant-btn[data-v-0db462a3]{margin:10px 10px 0 0}",""]),e.exports=t},e6a6:function(e,t,a){var n=a("7c22");n.__esModule&&(n=n.default),"string"===typeof n&&(n=[[e.i,n,""]]),n.locals&&(e.exports=n.locals);var r=a("499e").default;r("1fb1813a",n,!0,{sourceMap:!1,shadowMode:!1})},f820:function(e,t,a){"use strict";a.r(t);var n=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("a-card",[a("h2",[e._v("Nginx UI")]),a("p",[e._v("Yet another WebUI for Nginx")]),a("p",[e._v("Version: "+e._s(e.version)+" ("+e._s(e.build_id)+")")]),a("h3",[e._v("项目组")]),a("p",[e._v("Designer:"),a("a",{attrs:{href:"https://jackyu.cn/"}},[e._v("@0xJacky")])]),a("h3",[e._v("技术栈")]),a("p",[e._v("Go")]),a("p",[e._v("Gin")]),a("p",[e._v("Vue")]),a("p",[e._v("Websocket")]),a("h3",[e._v("开源协议")]),a("p",[e._v("GNU General Public License v2.0")]),a("p",[e._v("Copyright © 2020 - "+e._s(e.this_year)+" 0xJacky ")])])},r=[],s=a("1da1"),i=(a("96cf"),{name:"About",data:function(){var e,t=new Date;return{this_year:t.getFullYear(),version:"1.0.0",build_id:null!==(e="8")&&void 0!==e?e:"开发模式",api_root:"/api"}},methods:{changeUserPower:function(e){var t=this;return Object(s["a"])(regeneratorRuntime.mark((function a(){return regeneratorRuntime.wrap((function(a){while(1)switch(a.prev=a.next){case 0:return a.next=2,t.$store.dispatch("update_mock_user",{power:e});case 2:return a.next=4,t.$api.user.info();case 4:return a.next=6,t.$message.success("修改成功");case 6:case"end":return a.stop()}}),a)})))()}}}),o=i,c=(a("0d92"),a("2877")),u=Object(c["a"])(o,n,r,!1,null,"0db462a3",null);t["default"]=u.exports}}]);
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-96068e84"],{"0d92":function(e,t,a){"use strict";a("e6a6")},"7c22":function(e,t,a){var n=a("24fb");t=n(!1),t.push([e.i,".egg[data-v-0db462a3]{padding:10px 0}.ant-btn[data-v-0db462a3]{margin:10px 10px 0 0}",""]),e.exports=t},e6a6:function(e,t,a){var n=a("7c22");n.__esModule&&(n=n.default),"string"===typeof n&&(n=[[e.i,n,""]]),n.locals&&(e.exports=n.locals);var r=a("499e").default;r("1fb1813a",n,!0,{sourceMap:!1,shadowMode:!1})},f820:function(e,t,a){"use strict";a.r(t);var n=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("a-card",[a("h2",[e._v("Nginx UI")]),a("p",[e._v("Yet another WebUI for Nginx")]),a("p",[e._v("Version: "+e._s(e.version)+" ("+e._s(e.build_id)+")")]),a("h3",[e._v("项目组")]),a("p",[e._v("Designer:"),a("a",{attrs:{href:"https://jackyu.cn/"}},[e._v("@0xJacky")])]),a("h3",[e._v("技术栈")]),a("p",[e._v("Go")]),a("p",[e._v("Gin")]),a("p",[e._v("Vue")]),a("p",[e._v("Websocket")]),a("h3",[e._v("开源协议")]),a("p",[e._v("GNU General Public License v2.0")]),a("p",[e._v("Copyright © 2020 - "+e._s(e.this_year)+" 0xJacky ")])])},r=[],s=a("1da1"),i=(a("96cf"),{name:"About",data:function(){var e,t=new Date;return{this_year:t.getFullYear(),version:"1.0.0",build_id:null!==(e="14")&&void 0!==e?e:"开发模式",api_root:"/api"}},methods:{changeUserPower:function(e){var t=this;return Object(s["a"])(regeneratorRuntime.mark((function a(){return regeneratorRuntime.wrap((function(a){while(1)switch(a.prev=a.next){case 0:return a.next=2,t.$store.dispatch("update_mock_user",{power:e});case 2:return a.next=4,t.$api.user.info();case 4:return a.next=6,t.$message.success("修改成功");case 6:case"end":return a.stop()}}),a)})))()}}}),o=i,c=(a("0d92"),a("2877")),u=Object(c["a"])(o,n,r,!1,null,"0db462a3",null);t["default"]=u.exports}}]);

+ 1 - 1
frontend/dist/js/chunk-96068e84.5cf4468c.js → frontend/dist/js/chunk-96068e84.f88847b7.js

@@ -1 +1 @@
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-96068e84"],{"0d92":function(e,t,a){"use strict";a("e6a6")},"7c22":function(e,t,a){var n=a("24fb");t=n(!1),t.push([e.i,".egg[data-v-0db462a3]{padding:10px 0}.ant-btn[data-v-0db462a3]{margin:10px 10px 0 0}",""]),e.exports=t},e6a6:function(e,t,a){var n=a("7c22");n.__esModule&&(n=n.default),"string"===typeof n&&(n=[[e.i,n,""]]),n.locals&&(e.exports=n.locals);var r=a("499e").default;r("1fb1813a",n,!0,{sourceMap:!1,shadowMode:!1})},f820:function(e,t,a){"use strict";a.r(t);var n=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("a-card",[a("h2",[e._v("Nginx UI")]),a("p",[e._v("Yet another WebUI for Nginx")]),a("p",[e._v("Version: "+e._s(e.version)+" ("+e._s(e.build_id)+")")]),a("h3",[e._v("项目组")]),a("p",[e._v("Designer:"),a("a",{attrs:{href:"https://jackyu.cn/"}},[e._v("@0xJacky")])]),a("h3",[e._v("技术栈")]),a("p",[e._v("Go")]),a("p",[e._v("Gin")]),a("p",[e._v("Vue")]),a("p",[e._v("Websocket")]),a("h3",[e._v("开源协议")]),a("p",[e._v("GNU General Public License v2.0")]),a("p",[e._v("Copyright © 2020 - "+e._s(e.this_year)+" 0xJacky ")])])},r=[],s=a("1da1"),i=(a("96cf"),{name:"About",data:function(){var e,t=new Date;return{this_year:t.getFullYear(),version:"1.0.0",build_id:null!==(e="8")&&void 0!==e?e:"开发模式",api_root:"/api"}},methods:{changeUserPower:function(e){var t=this;return Object(s["a"])(regeneratorRuntime.mark((function a(){return regeneratorRuntime.wrap((function(a){while(1)switch(a.prev=a.next){case 0:return a.next=2,t.$store.dispatch("update_mock_user",{power:e});case 2:return a.next=4,t.$api.user.info();case 4:return a.next=6,t.$message.success("修改成功");case 6:case"end":return a.stop()}}),a)})))()}}}),o=i,c=(a("0d92"),a("2877")),u=Object(c["a"])(o,n,r,!1,null,"0db462a3",null);t["default"]=u.exports}}]);
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-96068e84"],{"0d92":function(e,t,a){"use strict";a("e6a6")},"7c22":function(e,t,a){var n=a("24fb");t=n(!1),t.push([e.i,".egg[data-v-0db462a3]{padding:10px 0}.ant-btn[data-v-0db462a3]{margin:10px 10px 0 0}",""]),e.exports=t},e6a6:function(e,t,a){var n=a("7c22");n.__esModule&&(n=n.default),"string"===typeof n&&(n=[[e.i,n,""]]),n.locals&&(e.exports=n.locals);var r=a("499e").default;r("1fb1813a",n,!0,{sourceMap:!1,shadowMode:!1})},f820:function(e,t,a){"use strict";a.r(t);var n=function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("a-card",[a("h2",[e._v("Nginx UI")]),a("p",[e._v("Yet another WebUI for Nginx")]),a("p",[e._v("Version: "+e._s(e.version)+" ("+e._s(e.build_id)+")")]),a("h3",[e._v("项目组")]),a("p",[e._v("Designer:"),a("a",{attrs:{href:"https://jackyu.cn/"}},[e._v("@0xJacky")])]),a("h3",[e._v("技术栈")]),a("p",[e._v("Go")]),a("p",[e._v("Gin")]),a("p",[e._v("Vue")]),a("p",[e._v("Websocket")]),a("h3",[e._v("开源协议")]),a("p",[e._v("GNU General Public License v2.0")]),a("p",[e._v("Copyright © 2020 - "+e._s(e.this_year)+" 0xJacky ")])])},r=[],s=a("1da1"),i=(a("96cf"),{name:"About",data:function(){var e,t=new Date;return{this_year:t.getFullYear(),version:"1.0.0",build_id:null!==(e="14")&&void 0!==e?e:"开发模式",api_root:"/api"}},methods:{changeUserPower:function(e){var t=this;return Object(s["a"])(regeneratorRuntime.mark((function a(){return regeneratorRuntime.wrap((function(a){while(1)switch(a.prev=a.next){case 0:return a.next=2,t.$store.dispatch("update_mock_user",{power:e});case 2:return a.next=4,t.$api.user.info();case 4:return a.next=6,t.$message.success("修改成功");case 6:case"end":return a.stop()}}),a)})))()}}}),o=i,c=(a("0d92"),a("2877")),u=Object(c["a"])(o,n,r,!1,null,"0db462a3",null);t["default"]=u.exports}}]);

+ 0 - 1
frontend/dist/js/chunk-d4ac245c-legacy.d0d1ca92.js

@@ -1 +0,0 @@
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-d4ac245c"],{4159:function(t,e,n){var a=n("24fb");e=a(!1),e.push([t.i,".ant-card[data-v-6d72b90c]{margin:10px}@media (max-width:512px){.ant-card[data-v-6d72b90c]{margin:10px 0}}",""]),t.exports=e},9963:function(t,e,n){var a=n("4159");a.__esModule&&(a=a.default),"string"===typeof a&&(a=[[t.i,a,""]]),a.locals&&(t.exports=a.locals);var o=n("499e").default;o("7aad0ace",a,!0,{sourceMap:!1,shadowMode:!1})},afa2:function(t,e,n){"use strict";n("9963")},e33d:function(t,e,n){"use strict";n.r(e);var a=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("a-card",{attrs:{title:"配置文件编辑"}},[n("vue-itextarea",{model:{value:t.configText,callback:function(e){t.configText=e},expression:"configText"}}),n("footer-tool-bar",[n("a-space",[n("a-button",{on:{click:function(e){return t.$router.go(-1)}}},[t._v("返回")]),n("a-button",{attrs:{type:"primary"},on:{click:t.save}},[t._v("保存")])],1)],1)],1)},o=[],c=(n("b0c0"),n("9c70")),i=n("a002"),s={name:"DomainEdit",components:{FooterToolBar:c["a"],VueItextarea:i["a"]},data:function(){return{name:this.$route.params.name,configText:""}},watch:{$route:function(){this.config={},this.configText=""},config:{handler:function(){this.unparse()},deep:!0}},created:function(){var t=this;this.name?this.$api.config.get(this.name).then((function(e){t.configText=e.config})).catch((function(e){console.log(e),t.$message.error("服务器错误")})):this.configText=""},methods:{save:function(){var t=this;this.$api.config.save(this.name?this.name:this.config.name,{content:this.configText}).then((function(e){t.configText=e.config,t.$message.success("保存成功")})).catch((function(e){console.log(e),t.$message.error("保存错误")}))}}},r=s,f=(n("afa2"),n("2877")),u=Object(f["a"])(r,a,o,!1,null,"6d72b90c",null);e["default"]=u.exports}}]);

+ 0 - 1
frontend/dist/js/chunk-d4ac245c.d0d1ca92.js

@@ -1 +0,0 @@
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-d4ac245c"],{4159:function(t,e,n){var a=n("24fb");e=a(!1),e.push([t.i,".ant-card[data-v-6d72b90c]{margin:10px}@media (max-width:512px){.ant-card[data-v-6d72b90c]{margin:10px 0}}",""]),t.exports=e},9963:function(t,e,n){var a=n("4159");a.__esModule&&(a=a.default),"string"===typeof a&&(a=[[t.i,a,""]]),a.locals&&(t.exports=a.locals);var o=n("499e").default;o("7aad0ace",a,!0,{sourceMap:!1,shadowMode:!1})},afa2:function(t,e,n){"use strict";n("9963")},e33d:function(t,e,n){"use strict";n.r(e);var a=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("a-card",{attrs:{title:"配置文件编辑"}},[n("vue-itextarea",{model:{value:t.configText,callback:function(e){t.configText=e},expression:"configText"}}),n("footer-tool-bar",[n("a-space",[n("a-button",{on:{click:function(e){return t.$router.go(-1)}}},[t._v("返回")]),n("a-button",{attrs:{type:"primary"},on:{click:t.save}},[t._v("保存")])],1)],1)],1)},o=[],c=(n("b0c0"),n("9c70")),i=n("a002"),s={name:"DomainEdit",components:{FooterToolBar:c["a"],VueItextarea:i["a"]},data:function(){return{name:this.$route.params.name,configText:""}},watch:{$route:function(){this.config={},this.configText=""},config:{handler:function(){this.unparse()},deep:!0}},created:function(){var t=this;this.name?this.$api.config.get(this.name).then((function(e){t.configText=e.config})).catch((function(e){console.log(e),t.$message.error("服务器错误")})):this.configText=""},methods:{save:function(){var t=this;this.$api.config.save(this.name?this.name:this.config.name,{content:this.configText}).then((function(e){t.configText=e.config,t.$message.success("保存成功")})).catch((function(e){console.log(e),t.$message.error("保存错误")}))}}},r=s,f=(n("afa2"),n("2877")),u=Object(f["a"])(r,a,o,!1,null,"6d72b90c",null);e["default"]=u.exports}}]);

File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-ddbf168e-legacy.82ea029a.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-ddbf168e.82ea029a.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-e71b472c-legacy.e8ed19fc.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-e71b472c.e8ed19fc.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-vendors-legacy.aa67daf5.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/chunk-vendors.aa67daf5.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/index-legacy.008a35ba.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/index-legacy.b992baa1.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/index.204ef68a.js


File diff suppressed because it is too large
+ 0 - 0
frontend/dist/js/index.b951e46d.js


+ 1 - 1
frontend/dist/version.json

@@ -1 +1 @@
-{"version":"1.0.0","build_id":4,"total_build":8}
+{"version":"1.0.0","build_id":10,"total_build":14}

+ 2 - 2
frontend/src/components/StdDataDisplay/StdTable.vue

@@ -71,14 +71,14 @@
                         v-if="soft_delete&&params.trashed"
                         cancelText="再想想"
                         okText="是的" title="你确定要反删除?"
-                        @confirm="restore(record.id)">
+                        @confirm="restore(record[rowKey])">
                         <a href="javascript:;">反删除</a>
                     </a-popconfirm>
                     <a-popconfirm
                         v-else
                         cancelText="再想想"
                         okText="是的" title="你确定要删除?"
-                        @confirm="destroy(record.id)"
+                        @confirm="destroy(record[rowKey])"
                     >
                         <a href="javascript:;">删除</a>
                     </a-popconfirm>

+ 2 - 2
frontend/src/views/Config.vue

@@ -7,9 +7,9 @@
             :disable_search="true"
             data_key="configs"
             row-key="name"
-            @clickEdit="item => {
+            @clickEdit="r => {
                 $router.push({
-                    path: '/config/' + item.name
+                    path: '/config/' + r
                 })
             }"
         />

+ 15 - 13
frontend/src/views/ConfigEdit.vue

@@ -24,9 +24,8 @@ export default {
         }
     },
     watch: {
-        $route() {
-            this.config = {}
-            this.configText = ""
+        '$route'() {
+            this.init()
         },
         config: {
             handler() {
@@ -36,18 +35,21 @@ export default {
         }
     },
     created() {
-        if (this.name) {
-            this.$api.config.get(this.name).then(r => {
-                this.configText = r.config
-            }).catch(r => {
-                console.log(r)
-                this.$message.error("服务器错误")
-            })
-        } else {
-            this.configText = ""
-        }
+       this.init()
     },
     methods: {
+        init() {
+            if (this.name) {
+                this.$api.config.get(this.name).then(r => {
+                    this.configText = r.config
+                }).catch(r => {
+                    console.log(r)
+                    this.$message.error("服务器错误")
+                })
+            } else {
+                this.configText = ""
+            }
+        },
         save() {
             this.$api.config.save(this.name ? this.name : this.config.name, {content: this.configText}).then(r => {
                 this.configText = r.config

+ 0 - 1
frontend/src/views/DashBoard.vue

@@ -165,7 +165,6 @@ export default {
 
 <style lang="less" scoped>
 .ant-card {
-    margin: 10px;
 
     .chart {
         max-height: 300px;

+ 2 - 2
frontend/src/views/Domain.vue

@@ -11,10 +11,10 @@
                 path: '/domain/' + r
             })"
         >
-            <template #action="{record}">
+            <template #actions="{record}">
+                <a-divider type="vertical"/>
                 <a v-if="record.enabled" @click="disable(record.name)">禁用</a>
                 <a v-else @click="enable(record.name)">启用</a>
-                <a-divider type="vertical"/>
             </template>
         </std-table>
     </a-card>

+ 1 - 1
frontend/src/views/Login.vue

@@ -70,7 +70,7 @@ export default {
     },
     methods: {
         login(values) {
-            this.$api.auth.login(values.name, values.password).then(async () => {
+            return this.$api.auth.login(values.name, values.password).then(async () => {
                 await this.$message.success('登录成功', 1)
                 const next = this.$route.query.next ? this.$route.query.next : '/'
                 await this.$router.push(next)

+ 26 - 24
frontend/src/views/domain_edit/DomainEdit.vue

@@ -57,9 +57,8 @@ export default {
         }
     },
     watch: {
-        $route() {
-            this.config = {}
-            this.configText = ""
+        '$route'() {
+            this.init()
         },
         config: {
             handler() {
@@ -69,27 +68,7 @@ export default {
         }
     },
     created() {
-        if (this.name) {
-            this.$api.domain.get(this.name).then(r => {
-                this.configText = r.config
-                this.parse(r)
-            }).catch(r => {
-                console.log(r)
-                this.$message.error("服务器错误")
-            })
-        } else {
-            this.config = {
-                http_listen_port: 80,
-                https_listen_port: null,
-                server_name: "",
-                index: "",
-                root: "",
-                ssl_certificate: "",
-                ssl_certificate_key: "",
-                support_ssl: false
-            }
-            this.get_template()
-        }
+        this.init()
     },
     destroyed() {
         if (this.ws !== null) {
@@ -97,6 +76,29 @@ export default {
         }
     },
     methods: {
+        init() {
+            if (this.name) {
+                this.$api.domain.get(this.name).then(r => {
+                    this.configText = r.config
+                    this.parse(r)
+                }).catch(r => {
+                    console.log(r)
+                    this.$message.error("服务器错误")
+                })
+            } else {
+                this.config = {
+                    http_listen_port: 80,
+                    https_listen_port: null,
+                    server_name: "",
+                    index: "",
+                    root: "",
+                    ssl_certificate: "",
+                    ssl_certificate_key: "",
+                    support_ssl: false
+                }
+                this.get_template()
+            }
+        },
         parse(r) {
             const text = r.config
             const reg = {

+ 1 - 1
frontend/version.json

@@ -1 +1 @@
-{"version":"1.0.0","build_id":4,"total_build":8}
+{"version":"1.0.0","build_id":10,"total_build":14}

+ 0 - 1
frontend/vue.config.js

@@ -1,5 +1,4 @@
 const webpack = require('webpack')
-const {tuple} = require("ant-design-vue/lib/_util/type");
 
 module.exports = {
     pages: {

+ 0 - 20
install.sh

@@ -1,20 +0,0 @@
-#!/bin/bash
-
-echo "=========================="
-echo
-echo "Nginx UI Install Shell"
-echo "Copyright (c) 0xJacky 2021"
-echo
-echo "=========================="
-
-echo "Compiling api server..."
-cd server || exit 1
-go build -o nginx-ui-server main.go
-
-echo "build completed"
-cd ..
-
-echo "==============="
-echo "frontend dist path: nginx-ui-frontend/dist"
-echo "start server, run server/nginx-ui-server"
-echo "start server at background, run nohup ./nginx-ui-server &"

+ 0 - 24
nginx.conf

@@ -1,24 +0,0 @@
-server {
-    listen       80;
-    server_name  localhost;  # your domain here
-    client_max_body_size 128M;  # maximum upload size
-    root	/app/html;
-	index	index.html;
-
-	location / {
-		# First attempt to serve request as file, then
-		# as directory, then fall back to displaying a 404.
-                index index.html;
-		try_files $uri $uri/ /index.html;
-	}
-
-	location /api/ {
-		proxy_set_header Host $host;
-        proxy_set_header X-Real_IP $remote_addr;
-        proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
-        proxy_http_version 1.1;
-        proxy_set_header Upgrade $http_upgrade;
-        proxy_set_header Connection upgrade;
-		proxy_pass http://127.0.0.1:9100/;
-	}
-}

二進制
screenshots/config-edit.png


二進制
screenshots/config-list.png


二進制
screenshots/dashboard.png


二進制
screenshots/domain-edit.png


二進制
screenshots/domain-list.png


二進制
screenshots/user-list.png


二進制
server/main


二進制
server/nginx-ui@linux-amd64


+ 0 - 4
sources.list

@@ -1,4 +0,0 @@
-deb http://mirrors.aliyun.com/debian/ buster main non-free contrib
-deb http://mirrors.aliyun.com/debian-security buster/updates main
-deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib
-deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib

+ 0 - 4
start.sh

@@ -1,4 +0,0 @@
-#!/bin/bash
-nginx
-cd server
-./nginx-ui@linux-amd64

Some files were not shown because too many files changed in this diff