diff --git a/component/wireguard.go b/component/wireguard.go
index cefd323..64c84f4 100644
--- a/component/wireguard.go
+++ b/component/wireguard.go
@@ -97,8 +97,8 @@ func (w WireguardComponent) GenerateClientFile(clientInfo *model.Client, server
var outPath = "/tmp/" + fmt.Sprintf("%s.conf", clientInfo.Name)
var templatePath = "./template/wg.client.conf"
if os.Getenv("GIN_MODE") != "release" {
- outPath = "E:\\Workspace\\Go\\wireguard-dashboard\\template\\" + fmt.Sprintf("%s.conf", clientInfo.Name)
- templatePath = "E:\\Workspace\\Go\\wireguard-dashboard\\template\\wg.client.conf"
+ outPath = "E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\" + fmt.Sprintf("%s.conf", clientInfo.Name)
+ templatePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\conf\\wg.client.conf"
}
err = Template().Execute(templatePath, outPath, execData)
diff --git a/cron/cron.go b/cron/cron.go
new file mode 100644
index 0000000..0cb6242
--- /dev/null
+++ b/cron/cron.go
@@ -0,0 +1 @@
+package cron
diff --git a/http/api/setting.go b/http/api/setting.go
index 67b5646..3450e47 100644
--- a/http/api/setting.go
+++ b/http/api/setting.go
@@ -1,11 +1,13 @@
package api
import (
+ "encoding/json"
"gitee.ltd/lxh/logger/log"
"github.com/gin-gonic/gin"
"slices"
"wireguard-ui/http/param"
"wireguard-ui/http/response"
+ "wireguard-ui/http/vo"
"wireguard-ui/model"
"wireguard-ui/script"
"wireguard-ui/service"
@@ -113,3 +115,48 @@ func (setting) GetAllSetting(c *gin.Context) {
func (setting) GetPublicAddr(c *gin.Context) {
response.R(c).OkWithData(utils.Network().GetHostPublicIP())
}
+
+// Export
+// @description: 导出配置
+// @receiver setting
+// @param c
+func (setting) Export(c *gin.Context) {
+ // 获取当前登陆用户
+ var loginUser *vo.User
+ if loginUser = GetCurrentLoginUser(c); c.IsAborted() {
+ return
+ }
+
+ if loginUser.Account != "admin" {
+ response.R(c).FailedWithError("非法操作,你被捕啦!")
+ return
+ }
+
+ // 获取配置
+ data, err := service.Setting().Export()
+ if err != nil {
+ response.R(c).FailedWithError(err)
+ return
+ }
+
+ // 生成配置文件
+ dataBytes, _ := json.Marshal(data)
+ filepath, err := utils.FileUtils().GenerateFile("config.json", dataBytes)
+ if err != nil {
+ response.R(c).FailedWithError(err)
+ return
+ }
+
+ c.Header("Content-Type", "application/octet-stream")
+ c.Header("Content-Disposition", "attachment; filename="+filepath)
+ c.Header("Content-Transfer-Encoding", "binary")
+ c.Header("Connection", "keep-alive")
+ c.File(filepath)
+ //if err = os.Remove(filepath); err != nil {
+ // log.Errorf("删除临时文件失败: %s", err.Error())
+ //}
+}
+
+func (setting) Import(c *gin.Context) {
+
+}
diff --git a/http/router/setting.go b/http/router/setting.go
index 1e976da..9cd3a3e 100644
--- a/http/router/setting.go
+++ b/http/router/setting.go
@@ -17,5 +17,6 @@ func SettingApi(r *gin.RouterGroup) {
setting.GET("", api.Setting().GetSetting) // 获取指定配置
setting.GET("/all", api.Setting().GetAllSetting) // 获取全部配置
setting.GET("/public-addr", api.Setting().GetPublicAddr) // 获取公网IP
+ setting.GET("/export", api.Setting().Export) // 导出配置文件
}
}
diff --git a/http/vo/setting.go b/http/vo/setting.go
index aece1d6..6925e6f 100644
--- a/http/vo/setting.go
+++ b/http/vo/setting.go
@@ -7,3 +7,46 @@ type SettingItem struct {
Data string `json:"data"`
Describe string `json:"describe"`
}
+
+type Export struct {
+ Global Global `json:"global"`
+ Server Server `json:"server"`
+ Clients []Client `json:"clients"`
+}
+
+type Global struct {
+ MTU int `json:"MTU"`
+ ConfigFilePath string `json:"configFilePath"`
+ DnsServer []string `json:"dnsServer"`
+ EndpointAddress string `json:"endpointAddress"`
+ FirewallMark string `json:"firewallMark"`
+ PersistentKeepalive int `json:"persistentKeepalive"`
+ Table string `json:"table"`
+}
+
+type Server struct {
+ IpScope []string `json:"ipScope"`
+ ListenPort int `json:"listenPort"`
+ PrivateKey string `json:"privateKey"`
+ PublicKey string `json:"publicKey"`
+ PostUpScript string `json:"postUpScript"`
+ PostDownScript string `json:"postDownScript"`
+}
+
+type Client struct {
+ Name string `json:"name"`
+ Email string `json:"email"`
+ SubnetRange string `json:"subnetRange"`
+ IpAllocation []string `json:"ipAllocation"`
+ AllowedIps []string `json:"allowedIps"`
+ ExtraAllowedIps []string `json:"extraAllowedIps"`
+ Endpoint string `json:"endpoint"`
+ UseServerDns int `json:"useServerDns"`
+ Keys struct {
+ PresharedKey string `json:"presharedKey"`
+ PrivateKey string `json:"privateKey"`
+ PublicKey string `json:"publicKey"`
+ } `json:"keys"`
+ Enabled int `json:"enabled"`
+ OfflineMonitoring int `json:"offlineMonitoring"`
+}
diff --git a/model/wireguard.go b/model/wireguard.go
index bdf3e13..82ed45e 100644
--- a/model/wireguard.go
+++ b/model/wireguard.go
@@ -22,3 +22,16 @@ type Client struct {
func (Client) TableName() string {
return "t_client"
}
+
+// Watcher
+// @description: 监听日志
+type Watcher struct {
+ Base
+ ClientId string `json:"clientId" gorm:"type:char(36);not null;comment:'客户端id'"`
+ NotifyResult string `json:"notifyResult" gorm:"type:text;default null;comment:'通知结果'"`
+ IsSend int `json:"isSend" gorm:"type:tinyint(1);default 0;comment:'是否已通知'"`
+}
+
+func (Watcher) TableName() string {
+ return "t_watcher"
+}
diff --git a/service/setting.go b/service/setting.go
index c7a2fd4..6ca7296 100644
--- a/service/setting.go
+++ b/service/setting.go
@@ -3,6 +3,7 @@ package service
import (
"encoding/json"
"gorm.io/gorm"
+ "strings"
gdb "wireguard-ui/global/client"
"wireguard-ui/http/vo"
"wireguard-ui/model"
@@ -84,3 +85,60 @@ func (s setting) GetAllSetting(blackList []string) (data []vo.SettingItem, err e
err = s.Model(&model.Setting{}).Select("code, data, describe").Where("code not in ?", blackList).Find(&data).Error
return
}
+
+// Export
+// @description: 导出
+// @receiver s
+// @return data
+// @return err
+func (s setting) Export() (data vo.Export, err error) {
+ // 先查询global配置
+ var gs, ss *model.Setting
+ if err = s.Model(&model.Setting{}).Where("code = ?", "WG_SETTING").Take(&gs).Error; err != nil {
+ return
+ }
+ if err = json.Unmarshal([]byte(gs.Data), &data.Global); err != nil {
+ return
+ }
+
+ // 查询server配置
+ if err = s.Model(&model.Setting{}).Where("code = ?", "WG_SERVER").Take(&ss).Error; err != nil {
+ return
+ }
+ if err = json.Unmarshal([]byte(ss.Data), &data.Server); err != nil {
+ return
+ }
+
+ // 查询client配置
+ var clients []vo.ClientItem
+ if err = s.Model(&model.Client{}).Select("id,name,email,ip_allocation as ip_allocation_str," +
+ "allowed_ips as allowed_ips_str,extra_allowed_ips as extra_allowed_ips_str," +
+ "endpoint,use_server_dns,keys as keys_str," +
+ "enabled,offline_monitoring").Order("created_at DESC").Find(&clients).Error; err != nil {
+ return
+ }
+
+ for i, v := range clients {
+ if v.KeysStr != "" {
+ _ = json.Unmarshal([]byte(v.KeysStr), &clients[i].Keys)
+ }
+ if v.IpAllocationStr != "" {
+ clients[i].IpAllocation = strings.Split(v.IpAllocationStr, ",")
+ }
+ if v.AllowedIpsStr != "" {
+ clients[i].AllowedIps = strings.Split(v.AllowedIpsStr, ",")
+ } else {
+ clients[i].AllowedIps = []string{}
+ }
+ if v.ExtraAllowedIpsStr != "" {
+ clients[i].ExtraAllowedIps = strings.Split(v.ExtraAllowedIpsStr, ",")
+ } else {
+ clients[i].ExtraAllowedIps = []string{}
+ }
+ }
+
+ cj, _ := json.Marshal(clients)
+ _ = json.Unmarshal(cj, &data.Clients)
+
+ return
+}
diff --git a/utils/file.go b/utils/file.go
new file mode 100644
index 0000000..d38e9e1
--- /dev/null
+++ b/utils/file.go
@@ -0,0 +1,28 @@
+package utils
+
+import (
+ "fmt"
+ "os"
+)
+
+type fileUtils struct{}
+
+func FileUtils() fileUtils {
+ return fileUtils{}
+}
+
+// GenerateFile
+// @description: 生成文件
+// @receiver fileUtils
+// @param filename 文件名称
+// @param content 文件内容
+// @return error
+func (fileUtils) GenerateFile(filename string, content []byte) (filepath string, err error) {
+ path := "/tmp/"
+ if os.Getenv("GIN_MODE") != "release" {
+ path = "E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\"
+ }
+ filepath = fmt.Sprintf("%s%s", path, filename)
+ err = os.WriteFile(filepath, content, 0777)
+ return filepath, err
+}
diff --git a/web/src/api/setting.js b/web/src/api/setting.js
new file mode 100644
index 0000000..a8cdf78
--- /dev/null
+++ b/web/src/api/setting.js
@@ -0,0 +1,5 @@
+import { request } from '@/utils'
+
+export default {
+ exportConfig: () => request.get('/setting/export'), // 获取当前登陆用户信息
+}
diff --git a/web/src/layout/components/header/components/Export.vue b/web/src/layout/components/header/components/Export.vue
new file mode 100644
index 0000000..6ee6e41
--- /dev/null
+++ b/web/src/layout/components/header/components/Export.vue
@@ -0,0 +1,40 @@
+
+