🎨几乎全部完成

This commit is contained in:
coward 2024-08-12 16:52:28 +08:00
parent 49a851ac92
commit 6af6eec866
8 changed files with 304 additions and 21 deletions

159
.gitignore vendored
View File

@ -101,6 +101,165 @@ fabric.properties
go.work
.idea
web/.idea
web/node_modules
web/.DS_Store
web/dist
web/dist-ssr
web/*.local
web/.eslintcache
web/report.html
web/vite.config.*.timestamp*
web/yarn.lock
web/npm-debug.log*
web/.pnpm-error.log*
web/.pnpm-debug.log
web/tests/**/coverage/
web/.vscode/
# Editor directories and files
web/*.suo
web/*.ntvs*
web/*.njsproj
web/*.sln
web/tsconfig.tsbuildinfo
template/tmp/*
logs/*
app.yaml
*.db
.env
*.env
### GoLand+all template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Go template
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
.idea
web/.idea
web/node_modules
web/.DS_Store
web/dist
web/dist-ssr
web/*.local
web/.eslintcache
web/report.html
web/vite.config.*.timestamp*
web/yarn.lock
web/npm-debug.log*
web/.pnpm-error.log*
web/.pnpm-debug.log
web/tests/**/coverage/
web/.vscode/
# Editor directories and files
web/*.suo
web/*.ntvs*
web/*.njsproj
web/*.sln
web/tsconfig.tsbuildinfo
template/tmp/*
logs/*

View File

@ -3,15 +3,22 @@ package command
import (
"fmt"
"gitee.ltd/lxh/logger/log"
"os"
"os/exec"
"strings"
"wireguard-ui/service"
)
// 分隔符
// getConfigFileName
// @description: 获取服务端配置文件名称
// @return string
func getConfigFileName() string {
func getConfigFileName(filePath string) string {
if filePath != "" {
filePath = strings.Split(filePath, string(os.PathSeparator))[len(strings.Split(filePath, string(os.PathSeparator)))-1] // 这里取到的是wg0.conf
filePath = strings.Split(filePath, ".conf")[0] // 这里取到的就是wg0
return filePath
}
data, err := service.Setting().GetWGSetForConfig()
if err != nil {
log.Errorf("获取服务端配置失败: %v", err.Error())
@ -29,23 +36,23 @@ func getConfigFileName() string {
// RestartWireguard
// @description: 是否重启
// @param isAsync // 是否异步执行
func RestartWireguard(isAsync bool) {
func RestartWireguard(isAsync bool, filePath string) {
if isAsync {
go func() {
StopWireguard() // 停止
StartWireguard() // 启动
StopWireguard(filePath) // 停止
StartWireguard(filePath) // 启动
}()
} else {
StopWireguard() // 停止
StartWireguard() // 启动
StopWireguard(filePath) // 停止
StartWireguard(filePath) // 启动
}
return
}
// StopWireguard
// @description: 停止服务端
func StopWireguard() {
configFileName := getConfigFileName()
func StopWireguard(filePath string) {
configFileName := getConfigFileName(filePath)
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("wg-quick down %s", configFileName))
if err := cmd.Run(); err == nil {
@ -57,12 +64,13 @@ func StopWireguard() {
// StartWireguard
// @description: 启动服务端
func StartWireguard() {
configFileName := getConfigFileName()
func StartWireguard(filePath string) {
configFileName := getConfigFileName(filePath)
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("wg-quick up %s", configFileName))
if err := cmd.Run(); err == nil {
log.Infof("启动wireguard[%s]服务端成功", configFileName)
}
return
}

View File

@ -14,6 +14,7 @@ import (
"wireguard-ui/config"
"wireguard-ui/global/client"
"wireguard-ui/model"
"wireguard-ui/service"
"wireguard-ui/template/render_data"
)
@ -113,20 +114,22 @@ func (w WireguardComponent) GenerateClientFile(clientInfo *model.Client, server
// @receiver w
// @return error
func (w WireguardComponent) ServerControl(filePath string) {
switch config.Config.Wireguard.RestartMode {
case "NOW": // 立即执行
w.watchConfigFile(filePath)
case "DELAY": // 延迟执行
time.Sleep(time.Duration(config.Config.Wireguard.DelayTime) * time.Second)
w.watchConfigFile(filePath)
if filePath == "" {
data, err := service.Setting().GetWGSetForConfig()
if err != nil {
log.Errorf("获取服务端配置失败: %v", err.Error())
return
}
filePath = data.ConfigFilePath
}
w.watchConfigFile(filePath, config.Config.Wireguard.RestartMode, config.Config.Wireguard.DelayTime)
}
// watchConfigFile
// @description: 监听并重新操作配置文件
// @receiver w
// @param filepath
func (w WireguardComponent) watchConfigFile(filepath string) {
func (w WireguardComponent) watchConfigFile(filepath string, mode string, delay int64) {
go func() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
@ -146,7 +149,14 @@ func (w WireguardComponent) watchConfigFile(filepath string) {
}
if event.Op == fsnotify.Write {
command.RestartWireguard(true)
switch mode {
case "NOW":
command.RestartWireguard(false, filepath)
case "DELAY":
time.Sleep(time.Duration(delay) * time.Second)
command.RestartWireguard(true, filepath)
}
}
// 打印监听事件

View File

@ -15,6 +15,7 @@ import (
"wireguard-ui/http/response"
"wireguard-ui/http/vo"
"wireguard-ui/model"
"wireguard-ui/script"
"wireguard-ui/service"
"wireguard-ui/utils"
)
@ -44,7 +45,12 @@ func (ClientApi) Save(c *gin.Context) {
return
}
component.Wireguard().ServerControl("E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\wg0.conf")
go func() {
if err := script.New().GenerateConfig(); err != nil {
log.Errorf("执行脚本失败")
}
}()
response.R(c).OK()
}
@ -64,7 +70,12 @@ func (ClientApi) Delete(c *gin.Context) {
return
}
component.Wireguard().ServerControl("E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\wg0.conf")
go func() {
if err := script.New().GenerateConfig(); err != nil {
log.Errorf("执行脚本失败")
}
}()
response.R(c).OK()
}

View File

@ -1,10 +1,13 @@
package api
import (
"gitee.ltd/lxh/logger/log"
"github.com/gin-gonic/gin"
"slices"
"wireguard-ui/http/param"
"wireguard-ui/http/response"
"wireguard-ui/model"
"wireguard-ui/script"
"wireguard-ui/service"
"wireguard-ui/utils"
)
@ -35,6 +38,15 @@ func (setting) Set(c *gin.Context) {
return
}
var whiteCodes = []string{"WG_SETTING", "WG_SERVER"}
if slices.Contains(whiteCodes, p.Code) {
go func() {
if err := script.New().GenerateConfig(); err != nil {
log.Errorf("执行脚本失败")
}
}()
}
response.R(c).OK()
}

81
script/conf_script.go Normal file
View File

@ -0,0 +1,81 @@
package script
import (
"github.com/spf13/cast"
"os"
"time"
"wireguard-ui/component"
"wireguard-ui/http/param"
"wireguard-ui/service"
"wireguard-ui/template/render_data"
)
// GenerateConfig
// @description: 生成配置文件
// @receiver script
// @return error
func (script) GenerateConfig() error {
// 获取服务端相关配置
serverEnt, err := service.Setting().GetWGServerForConfig()
if err != nil {
return err
}
global, err := service.Setting().GetWGSetForConfig()
if err != nil {
return err
}
// 获取客户端
clientsEnt, _, err := service.Client().List(param.ClientList{
Page: param.Page{
Current: -1,
Size: -1,
},
})
if err != nil {
return err
}
var clients []render_data.Client
for _, client := range clientsEnt {
clients = append(clients, render_data.Client{
ID: client.Id,
Name: client.Name,
Email: client.Email,
PublicKey: client.Keys.PublicKey,
PresharedKey: client.Keys.PresharedKey,
AllowedIPS: client.AllowedIpsStr,
Endpoint: client.Endpoint,
CreateUser: client.CreateUser,
Enabled: cast.ToBool(client.Enabled),
PersistentKeepalive: global.PersistentKeepalive,
CreatedAt: client.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: client.UpdatedAt.Format("2006-01-02 15:04:05"),
SyncAt: time.Now().Format("2006-01-02 15:04:05"),
})
}
execData := map[string]any{
"Server": serverEnt,
"Clients": clients,
}
var templatePath, outFilePath string
if os.Getenv("GIN_MODE") != "release" {
templatePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\conf\\wg.conf"
outFilePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\wg0.conf"
} else {
templatePath = "./template/wg.conf"
outFilePath = cast.ToString(global.ConfigFilePath)
}
// 先渲染模板
if err = component.Template().Execute(templatePath, outFilePath, execData); err != nil {
return nil
}
// 模板渲染成功,开始执行服务端控制
component.Wireguard().ServerControl(outFilePath)
return nil
}

View File

@ -15,6 +15,7 @@ Table = {{ .Server.Table|html }}
# CreatedAt: {{ .CreatedAt|html }}
# UpdatedAt: {{ .UpdatedAt|html }}
# CreateUser: {{ .CreateUser|html }}
# SyncAt: {{ .SyncAt|html }}
[Peer]
PublicKey = {{ .PublicKey|html }}
PresharedKey = {{ .PresharedKey|html }}

View File

@ -30,12 +30,13 @@ type Client struct {
PublicKey string `json:"publicKey"`
PresharedKey string `json:"presharedKey"`
AllowedIPS string `json:"allowedIps"`
PersistentKeepalive string `json:"persistentKeepalive"`
PersistentKeepalive int `json:"persistentKeepalive"`
Endpoint string `json:"endpoint"`
CreateUser string `json:"createUser"`
Enabled bool `json:"enabled"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
SyncAt string `json:"syncAt"`
}
type Keys struct {