mirror of
https://gitee.com/goploy/goploy.git
synced 2024-12-02 04:07:33 +08:00
rename file and edit file via sftp
This commit is contained in:
parent
4fcd89ca25
commit
55e6299da0
@ -6,8 +6,9 @@ package middleware
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/zhenorzz/goploy/internal/log"
|
||||
model2 "github.com/zhenorzz/goploy/internal/model"
|
||||
"github.com/zhenorzz/goploy/internal/model"
|
||||
"github.com/zhenorzz/goploy/internal/server"
|
||||
"github.com/zhenorzz/goploy/internal/server/response"
|
||||
"strconv"
|
||||
@ -26,7 +27,7 @@ func AddLoginLog(gp *server.Goploy, resp server.Response) {
|
||||
account = reqData.Account
|
||||
}
|
||||
|
||||
err := model2.LoginLog{
|
||||
err := model.LoginLog{
|
||||
Account: account,
|
||||
RemoteAddr: gp.Request.RemoteAddr,
|
||||
UserAgent: gp.Request.UserAgent(),
|
||||
@ -56,7 +57,7 @@ func AddOPLog(gp *server.Goploy, resp server.Response) {
|
||||
responseData = string(jsonBytes)
|
||||
}
|
||||
}
|
||||
err := model2.OperationLog{
|
||||
err := model.OperationLog{
|
||||
NamespaceID: gp.Namespace.ID,
|
||||
UserID: gp.UserInfo.ID,
|
||||
Router: gp.Request.Header.Get("Router"),
|
||||
@ -82,13 +83,13 @@ func AddUploadLog(gp *server.Goploy, resp server.Response) {
|
||||
_ = file.Close()
|
||||
}
|
||||
|
||||
err := model2.SftpLog{
|
||||
err := model.SftpLog{
|
||||
NamespaceID: gp.Namespace.ID,
|
||||
UserID: gp.UserInfo.ID,
|
||||
ServerID: serverID,
|
||||
RemoteAddr: gp.Request.RemoteAddr,
|
||||
UserAgent: gp.Request.UserAgent(),
|
||||
Type: model2.SftpLogTypeUpload,
|
||||
Type: model.SftpLogTypeUpload,
|
||||
Path: path,
|
||||
Reason: respJson.Message,
|
||||
}.AddRow()
|
||||
@ -97,6 +98,74 @@ func AddUploadLog(gp *server.Goploy, resp server.Response) {
|
||||
}
|
||||
}
|
||||
|
||||
func AddEditLog(gp *server.Goploy, resp server.Response) {
|
||||
var serverID int64 = 0
|
||||
var path = ""
|
||||
respJson := resp.(response.JSON)
|
||||
if respJson.Code != response.IllegalParam {
|
||||
type ReqData struct {
|
||||
ServerID int64 `json:"serverId"`
|
||||
File string `json:"file"`
|
||||
NewName string `json:"newName"`
|
||||
CurrentName string `json:"currentName"`
|
||||
}
|
||||
var reqData ReqData
|
||||
_ = json.Unmarshal(gp.Body, &reqData)
|
||||
serverID = reqData.ServerID
|
||||
path = reqData.File
|
||||
}
|
||||
|
||||
err := model.SftpLog{
|
||||
NamespaceID: gp.Namespace.ID,
|
||||
UserID: gp.UserInfo.ID,
|
||||
ServerID: serverID,
|
||||
RemoteAddr: gp.Request.RemoteAddr,
|
||||
UserAgent: gp.Request.UserAgent(),
|
||||
Type: model.SftpLogTypeEdit,
|
||||
Path: path,
|
||||
Reason: respJson.Message,
|
||||
}.AddRow()
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func AddRenameLog(gp *server.Goploy, resp server.Response) {
|
||||
var serverID int64 = 0
|
||||
var dir = ""
|
||||
var currentName = ""
|
||||
var newName = ""
|
||||
respJson := resp.(response.JSON)
|
||||
if respJson.Code != response.IllegalParam {
|
||||
type ReqData struct {
|
||||
ServerID int64 `json:"serverId"`
|
||||
Dir string `json:"dir"`
|
||||
NewName string `json:"newName"`
|
||||
CurrentName string `json:"currentName"`
|
||||
}
|
||||
var reqData ReqData
|
||||
_ = json.Unmarshal(gp.Body, &reqData)
|
||||
serverID = reqData.ServerID
|
||||
dir = reqData.Dir
|
||||
currentName = reqData.CurrentName
|
||||
newName = reqData.NewName
|
||||
}
|
||||
|
||||
err := model.SftpLog{
|
||||
NamespaceID: gp.Namespace.ID,
|
||||
UserID: gp.UserInfo.ID,
|
||||
ServerID: serverID,
|
||||
RemoteAddr: gp.Request.RemoteAddr,
|
||||
UserAgent: gp.Request.UserAgent(),
|
||||
Type: model.SftpLogTypeRename,
|
||||
Path: fmt.Sprintf("%s/%s->%s", dir, currentName, newName),
|
||||
Reason: respJson.Message,
|
||||
}.AddRow()
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func AddDeleteLog(gp *server.Goploy, resp server.Response) {
|
||||
var serverID int64 = 0
|
||||
var path = ""
|
||||
@ -112,13 +181,13 @@ func AddDeleteLog(gp *server.Goploy, resp server.Response) {
|
||||
path = reqData.File
|
||||
}
|
||||
|
||||
err := model2.SftpLog{
|
||||
err := model.SftpLog{
|
||||
NamespaceID: gp.Namespace.ID,
|
||||
UserID: gp.UserInfo.ID,
|
||||
ServerID: serverID,
|
||||
RemoteAddr: gp.Request.RemoteAddr,
|
||||
UserAgent: gp.Request.UserAgent(),
|
||||
Type: model2.SftpLogTypeDelete,
|
||||
Type: model.SftpLogTypeDelete,
|
||||
Path: path,
|
||||
Reason: respJson.Message,
|
||||
}.AddRow()
|
||||
@ -142,13 +211,13 @@ func AddDownloadLog(gp *server.Goploy, resp server.Response) {
|
||||
path = resp.(response.SftpFile).Filename
|
||||
}
|
||||
|
||||
err := model2.SftpLog{
|
||||
err := model.SftpLog{
|
||||
NamespaceID: gp.Namespace.ID,
|
||||
UserID: gp.UserInfo.ID,
|
||||
ServerID: serverID,
|
||||
RemoteAddr: gp.Request.RemoteAddr,
|
||||
UserAgent: gp.Request.UserAgent(),
|
||||
Type: model2.SftpLogTypeDownload,
|
||||
Type: model.SftpLogTypeDownload,
|
||||
Path: path,
|
||||
Reason: msg,
|
||||
}.AddRow()
|
||||
@ -172,13 +241,13 @@ func AddPreviewLog(gp *server.Goploy, resp server.Response) {
|
||||
path = resp.(response.SftpFile).Filename
|
||||
}
|
||||
|
||||
err := model2.SftpLog{
|
||||
err := model.SftpLog{
|
||||
NamespaceID: gp.Namespace.ID,
|
||||
UserID: gp.UserInfo.ID,
|
||||
ServerID: serverID,
|
||||
RemoteAddr: gp.Request.RemoteAddr,
|
||||
UserAgent: gp.Request.UserAgent(),
|
||||
Type: model2.SftpLogTypePreview,
|
||||
Type: model.SftpLogTypePreview,
|
||||
Path: path,
|
||||
Reason: msg,
|
||||
}.AddRow()
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"github.com/zhenorzz/goploy/cmd/server/api/middleware"
|
||||
"github.com/zhenorzz/goploy/config"
|
||||
"github.com/zhenorzz/goploy/internal/log"
|
||||
model2 "github.com/zhenorzz/goploy/internal/model"
|
||||
"github.com/zhenorzz/goploy/internal/model"
|
||||
"github.com/zhenorzz/goploy/internal/pkg"
|
||||
"github.com/zhenorzz/goploy/internal/server"
|
||||
"github.com/zhenorzz/goploy/internal/server/response"
|
||||
@ -43,6 +43,8 @@ func (s Server) Handler() []server.Route {
|
||||
server.NewRoute("/server/previewFile", http.MethodGet, s.PreviewFile).Permissions(config.SFTPPreviewFile).LogFunc(middleware.AddPreviewLog),
|
||||
server.NewRoute("/server/downloadFile", http.MethodGet, s.DownloadFile).Permissions(config.SFTPDownloadFile).LogFunc(middleware.AddDownloadLog),
|
||||
server.NewRoute("/server/uploadFile", http.MethodPost, s.UploadFile).Permissions(config.SFTPTransferFile).LogFunc(middleware.AddUploadLog),
|
||||
server.NewRoute("/server/editFile", http.MethodPut, s.EditFile).Permissions(config.SFTPEditFile).LogFunc(middleware.AddEditLog),
|
||||
server.NewRoute("/server/renameFile", http.MethodPut, s.RenameFile).Permissions(config.SFTPRenameFile).LogFunc(middleware.AddRenameLog),
|
||||
server.NewRoute("/server/deleteFile", http.MethodDelete, s.DeleteFile).Permissions(config.SFTPDeleteFile).LogFunc(middleware.AddDeleteLog),
|
||||
server.NewRoute("/server/transferFile", http.MethodPost, s.TransferFile).Permissions(config.SFTPUploadFile),
|
||||
server.NewRoute("/server/report", http.MethodGet, s.Report).Permissions(config.ShowServerMonitorPage),
|
||||
@ -60,25 +62,25 @@ func (s Server) Handler() []server.Route {
|
||||
}
|
||||
|
||||
func (Server) GetList(gp *server.Goploy) server.Response {
|
||||
serverList, err := model2.Server{NamespaceID: gp.Namespace.ID}.GetList()
|
||||
serverList, err := model.Server{NamespaceID: gp.Namespace.ID}.GetList()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
return response.JSON{
|
||||
Data: struct {
|
||||
Servers model2.Servers `json:"list"`
|
||||
Servers model.Servers `json:"list"`
|
||||
}{Servers: serverList},
|
||||
}
|
||||
}
|
||||
|
||||
func (Server) GetOption(gp *server.Goploy) server.Response {
|
||||
serverList, err := model2.Server{NamespaceID: gp.Namespace.ID}.GetAll()
|
||||
serverList, err := model.Server{NamespaceID: gp.Namespace.ID}.GetAll()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
return response.JSON{
|
||||
Data: struct {
|
||||
Servers model2.Servers `json:"list"`
|
||||
Servers model.Servers `json:"list"`
|
||||
}{Servers: serverList},
|
||||
}
|
||||
}
|
||||
@ -194,7 +196,7 @@ func (Server) Import(gp *server.Goploy) server.Response {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
errMsg := ""
|
||||
srv := model2.Server{
|
||||
srv := model.Server{
|
||||
NamespaceID: gp.Namespace.ID,
|
||||
}
|
||||
srv.Name = record[headerIdx["name"]]
|
||||
@ -301,7 +303,7 @@ func (s Server) Add(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
srv := model2.Server{
|
||||
srv := model.Server{
|
||||
NamespaceID: reqData.NamespaceID,
|
||||
Name: reqData.Name,
|
||||
OS: reqData.OS,
|
||||
@ -353,7 +355,7 @@ func (s Server) Edit(gp *server.Goploy) server.Response {
|
||||
if err := decodeJson(gp.Body, &reqData); err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
srv := model2.Server{
|
||||
srv := model.Server{
|
||||
ID: reqData.ID,
|
||||
NamespaceID: reqData.NamespaceID,
|
||||
Name: reqData.Name,
|
||||
@ -388,7 +390,7 @@ func (Server) Toggle(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
if err := (model2.Server{ID: reqData.ID, State: reqData.State}).ToggleRow(); err != nil {
|
||||
if err := (model.Server{ID: reqData.ID, State: reqData.State}).ToggleRow(); err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
return response.JSON{}
|
||||
@ -415,7 +417,7 @@ func (Server) InstallAgent(gp *server.Goploy) server.Response {
|
||||
|
||||
for _, id := range reqData.IDs {
|
||||
go func(id int64) {
|
||||
srv, err := (model2.Server{ID: id}).GetData()
|
||||
srv, err := (model.Server{ID: id}).GetData()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("Error on %d server, %s", id, err.Error()))
|
||||
return
|
||||
@ -471,7 +473,7 @@ func (Server) PreviewFile(gp *server.Goploy) server.Response {
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: "invalid server id"}
|
||||
}
|
||||
srv, err := (model2.Server{ID: id}).GetData()
|
||||
srv, err := (model.Server{ID: id}).GetData()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
@ -488,7 +490,7 @@ func (Server) DownloadFile(gp *server.Goploy) server.Response {
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: "invalid server id"}
|
||||
}
|
||||
srv, err := (model2.Server{ID: id}).GetData()
|
||||
srv, err := (model.Server{ID: id}).GetData()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
@ -516,7 +518,7 @@ func (Server) UploadFile(gp *server.Goploy) server.Response {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
srv, err := (model2.Server{ID: reqData.ID}).GetData()
|
||||
srv, err := (model.Server{ID: reqData.ID}).GetData()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
@ -547,6 +549,80 @@ func (Server) UploadFile(gp *server.Goploy) server.Response {
|
||||
return response.JSON{}
|
||||
}
|
||||
|
||||
func (Server) EditFile(gp *server.Goploy) server.Response {
|
||||
type ReqData struct {
|
||||
ServerID int64 `json:"serverId" validate:"gt=0"`
|
||||
File string `json:"file" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
}
|
||||
var reqData ReqData
|
||||
if err := decodeJson(gp.Body, &reqData); err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
srv, err := (model.Server{ID: reqData.ServerID}).GetData()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
client, err := srv.ToSSHConfig().Dial()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
sftpClient, err := sftp.NewClient(client)
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
|
||||
remoteFile, err := sftpClient.Create(reqData.File)
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
_, err = remoteFile.Write([]byte(reqData.Content))
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
return response.JSON{}
|
||||
}
|
||||
|
||||
func (Server) RenameFile(gp *server.Goploy) server.Response {
|
||||
type ReqData struct {
|
||||
ServerID int64 `json:"serverId" validate:"gt=0"`
|
||||
Dir string `json:"dir" validate:"required"`
|
||||
NewName string `json:"newName" validate:"required"`
|
||||
CurrentName string `json:"currentName" validate:"required"`
|
||||
}
|
||||
var reqData ReqData
|
||||
if err := decodeJson(gp.Body, &reqData); err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
srv, err := (model.Server{ID: reqData.ServerID}).GetData()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
client, err := srv.ToSSHConfig().Dial()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
sftpClient, err := sftp.NewClient(client)
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
defer sftpClient.Close()
|
||||
err = sftpClient.Rename(path.Join(reqData.Dir, reqData.CurrentName), path.Join(reqData.Dir, reqData.NewName))
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
return response.JSON{}
|
||||
}
|
||||
|
||||
func (Server) DeleteFile(gp *server.Goploy) server.Response {
|
||||
type ReqData struct {
|
||||
File string `json:"file" validate:"required"`
|
||||
@ -557,7 +633,7 @@ func (Server) DeleteFile(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
srv, err := (model2.Server{ID: reqData.ServerID}).GetData()
|
||||
srv, err := (model.Server{ID: reqData.ServerID}).GetData()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
@ -603,7 +679,7 @@ func (Server) TransferFile(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
sourceServer, err := (model2.Server{ID: reqData.SourceServerID}).GetData()
|
||||
sourceServer, err := (model.Server{ID: reqData.SourceServerID}).GetData()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
@ -621,7 +697,7 @@ func (Server) TransferFile(gp *server.Goploy) server.Response {
|
||||
defer sftpClient.Close()
|
||||
|
||||
for _, destServerID := range reqData.DestServerIDs {
|
||||
destServer, err := (model2.Server{ID: destServerID}).GetData()
|
||||
destServer, err := (model.Server{ID: destServerID}).GetData()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
@ -734,7 +810,7 @@ func (Server) Report(gp *server.Goploy) server.Response {
|
||||
if len(datetimeRange) != 2 {
|
||||
return response.JSON{Code: response.Error, Message: "invalid datetime range"}
|
||||
}
|
||||
serverAgentLogs, err := (model2.ServerAgentLog{ServerID: reqData.ServerID, Type: reqData.Type}).GetListBetweenTime(datetimeRange[0], datetimeRange[1])
|
||||
serverAgentLogs, err := (model.ServerAgentLog{ServerID: reqData.ServerID, Type: reqData.Type}).GetListBetweenTime(datetimeRange[0], datetimeRange[1])
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
@ -753,7 +829,7 @@ func (Server) Report(gp *server.Goploy) server.Response {
|
||||
flagMap[serverAgentLog.Item] = Flag{Count: flagMap[serverAgentLog.Item].Count + 1}
|
||||
}
|
||||
|
||||
serverAgentMap := map[string]model2.ServerAgentLogs{}
|
||||
serverAgentMap := map[string]model.ServerAgentLogs{}
|
||||
for _, serverAgentLog := range serverAgentLogs {
|
||||
flagMap[serverAgentLog.Item] = Flag{
|
||||
Count: flagMap[serverAgentLog.Item].Count,
|
||||
@ -769,20 +845,20 @@ func (Server) Report(gp *server.Goploy) server.Response {
|
||||
|
||||
return response.JSON{
|
||||
Data: struct {
|
||||
ServerAgentMap map[string]model2.ServerAgentLogs `json:"map"`
|
||||
ServerAgentMap map[string]model.ServerAgentLogs `json:"map"`
|
||||
}{ServerAgentMap: serverAgentMap},
|
||||
}
|
||||
}
|
||||
|
||||
func (Server) GetAllMonitor(gp *server.Goploy) server.Response {
|
||||
serverID, err := strconv.ParseInt(gp.URLQuery.Get("serverId"), 10, 64)
|
||||
serverMonitorList, err := model2.ServerMonitor{ServerID: serverID}.GetAll()
|
||||
serverMonitorList, err := model.ServerMonitor{ServerID: serverID}.GetAll()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
return response.JSON{
|
||||
Data: struct {
|
||||
List model2.ServerMonitors `json:"list"`
|
||||
List model.ServerMonitors `json:"list"`
|
||||
}{List: serverMonitorList},
|
||||
}
|
||||
}
|
||||
@ -808,7 +884,7 @@ func (s Server) AddMonitor(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
id, err := model2.ServerMonitor{
|
||||
id, err := model.ServerMonitor{
|
||||
ServerID: reqData.ServerID,
|
||||
Item: reqData.Item,
|
||||
Formula: reqData.Formula,
|
||||
@ -855,7 +931,7 @@ func (s Server) EditMonitor(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
err := model2.ServerMonitor{
|
||||
err := model.ServerMonitor{
|
||||
ID: reqData.ID,
|
||||
Item: reqData.Item,
|
||||
Formula: reqData.Formula,
|
||||
@ -887,7 +963,7 @@ func (s Server) DeleteMonitor(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
err := model2.ServerMonitor{
|
||||
err := model.ServerMonitor{
|
||||
ID: reqData.ID,
|
||||
}.DeleteRow()
|
||||
|
||||
@ -899,13 +975,13 @@ func (s Server) DeleteMonitor(gp *server.Goploy) server.Response {
|
||||
}
|
||||
|
||||
func (Server) GetProcessList(gp *server.Goploy) server.Response {
|
||||
list, err := model2.ServerProcess{NamespaceID: gp.Namespace.ID}.GetList()
|
||||
list, err := model.ServerProcess{NamespaceID: gp.Namespace.ID}.GetList()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
return response.JSON{
|
||||
Data: struct {
|
||||
List model2.ServerProcesses `json:"list"`
|
||||
List model.ServerProcesses `json:"list"`
|
||||
}{List: list},
|
||||
}
|
||||
}
|
||||
@ -921,7 +997,7 @@ func (Server) AddProcess(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
id, err := model2.ServerProcess{
|
||||
id, err := model.ServerProcess{
|
||||
NamespaceID: gp.Namespace.ID,
|
||||
Name: reqData.Name,
|
||||
Items: reqData.Items,
|
||||
@ -948,7 +1024,7 @@ func (Server) EditProcess(gp *server.Goploy) server.Response {
|
||||
if err := decodeJson(gp.Body, &reqData); err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
err := model2.ServerProcess{
|
||||
err := model.ServerProcess{
|
||||
ID: reqData.ID,
|
||||
Name: reqData.Name,
|
||||
Items: reqData.Items,
|
||||
@ -969,7 +1045,7 @@ func (Server) DeleteProcess(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
if err := (model2.ServerProcess{ID: reqData.ID}).DeleteRow(); err != nil {
|
||||
if err := (model.ServerProcess{ID: reqData.ID}).DeleteRow(); err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
@ -1001,18 +1077,18 @@ func (Server) ExecProcess(gp *server.Goploy) server.Response {
|
||||
return response.JSON{Data: respData}
|
||||
}
|
||||
|
||||
serverProcess, err := model2.ServerProcess{ID: reqData.ID}.GetData()
|
||||
serverProcess, err := model.ServerProcess{ID: reqData.ID}.GetData()
|
||||
if err != nil {
|
||||
respData.Stderr = err.Error()
|
||||
return response.JSON{Data: respData}
|
||||
}
|
||||
srv, err := (model2.Server{ID: reqData.ServerID}).GetData()
|
||||
srv, err := (model.Server{ID: reqData.ServerID}).GetData()
|
||||
if err != nil {
|
||||
respData.Stderr = err.Error()
|
||||
return response.JSON{Data: respData}
|
||||
}
|
||||
|
||||
var processItems model2.ServerProcessItems
|
||||
var processItems model.ServerProcessItems
|
||||
if err := json.Unmarshal([]byte(serverProcess.Items), &processItems); err != nil {
|
||||
respData.Stderr = err.Error()
|
||||
return response.JSON{Data: respData}
|
||||
@ -1080,7 +1156,7 @@ func (Server) ExecScript(gp *server.Goploy) server.Response {
|
||||
ServerID: serverId,
|
||||
}
|
||||
|
||||
srv, err := (model2.Server{ID: serverId}).GetData()
|
||||
srv, err := (model.Server{ID: serverId}).GetData()
|
||||
if err != nil {
|
||||
serverResp.ExecRes = false
|
||||
serverResp.Stderr = err.Error()
|
||||
|
@ -82,4 +82,6 @@ const (
|
||||
SFTPTransferFile = 75
|
||||
SFTPDeleteFile = 76
|
||||
ShowServerScriptPage = 77
|
||||
SFTPRenameFile = 78
|
||||
SFTPEditFile = 79
|
||||
)
|
||||
|
@ -3,3 +3,6 @@ ALTER TABLE monitor ADD fail_script text;
|
||||
ALTER TABLE monitor ADD success_server_id INT ( 10 ) UNSIGNED NOT NULL DEFAULT 0;
|
||||
ALTER TABLE monitor ADD fail_server_id INT ( 10 ) UNSIGNED NOT NULL DEFAULT 0;
|
||||
ALTER TABLE project ADD tag VARCHAR ( 6382 ) NOT NULL DEFAULT '';
|
||||
|
||||
INSERT IGNORE INTO `permission` (`id`, `pid`, `name`, `sort`, `description`) VALUES (78, 23, 'SFTPRenameFile', 0, '');
|
||||
INSERT IGNORE INTO `permission` (`id`, `pid`, `name`, `sort`, `description`) VALUES (79, 23, 'SFTPEditFile', 0, '');
|
||||
|
@ -473,6 +473,8 @@ INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALU
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (75, 23, 'SFTPTransferFile', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (76, 23, 'SFTPDeleteFile', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (77, 23, 'ShowServerScriptPage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (78, 23, 'SFTPRenameFile', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (79, 23, 'SFTPEditFile', 0, '');
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 13);
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 14);
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 15);
|
||||
|
@ -32,6 +32,8 @@ const (
|
||||
SftpLogTypeUpload = "UPLOAD"
|
||||
SftpLogTypeRead = "READ"
|
||||
SftpLogTypePreview = "PREVIEW"
|
||||
SftpLogTypeRename = "RENAME"
|
||||
SftpLogTypeEdit = "EDIT"
|
||||
SftpLogTypeDelete = "DELETE"
|
||||
)
|
||||
|
||||
|
1
web/components.d.ts
vendored
1
web/components.d.ts
vendored
@ -25,6 +25,7 @@ declare module '@vue/runtime-core' {
|
||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
||||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
||||
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
|
@ -394,6 +394,37 @@ export class ServerExecProcess extends Request {
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerRenameFile extends Request {
|
||||
readonly url = '/server/renameFile'
|
||||
readonly method = 'put'
|
||||
readonly timeout = 0
|
||||
public param: {
|
||||
serverId: number
|
||||
dir: string
|
||||
currentName: string
|
||||
newName: string
|
||||
}
|
||||
constructor(param: ServerRenameFile['param']) {
|
||||
super()
|
||||
this.param = param
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerEditFile extends Request {
|
||||
readonly url = '/server/editFile'
|
||||
readonly method = 'put'
|
||||
readonly timeout = 0
|
||||
public param: {
|
||||
serverId: number
|
||||
file: string
|
||||
content: string
|
||||
}
|
||||
constructor(param: ServerEditFile['param']) {
|
||||
super()
|
||||
this.param = param
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerDeleteFile extends Request {
|
||||
readonly url = '/server/deleteFile'
|
||||
readonly method = 'delete'
|
||||
@ -407,6 +438,7 @@ export class ServerDeleteFile extends Request {
|
||||
this.param = param
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerTransferFile extends Request {
|
||||
readonly url = '/server/transferFile'
|
||||
readonly method = 'post'
|
||||
|
@ -90,6 +90,7 @@
|
||||
"edit": "Edit",
|
||||
"copy": "Copy",
|
||||
"transfer": "Transfer",
|
||||
"rename": "Rename",
|
||||
"approve": "Approve",
|
||||
"deny": "Deny",
|
||||
"preview": "Preview",
|
||||
@ -305,7 +306,8 @@
|
||||
"advance": "Advanced setting",
|
||||
"transferFile": "Transfer file",
|
||||
"sftpFileCount": "items",
|
||||
"saveTemplate": "Save template"
|
||||
"saveTemplate": "Save template",
|
||||
"renameTips": "rename {name}"
|
||||
},
|
||||
"monitorPage": {
|
||||
"defaultServer": "Follow Host",
|
||||
|
@ -90,6 +90,7 @@
|
||||
"edit": "编辑",
|
||||
"copy": "复制",
|
||||
"transfer": "传输",
|
||||
"rename": "重命名",
|
||||
"approve": "同意",
|
||||
"deny": "拒绝",
|
||||
"preview": "预览",
|
||||
@ -288,7 +289,8 @@
|
||||
"advance": "高级选项",
|
||||
"transferFile": "传输文件",
|
||||
"sftpFileCount": "个项目",
|
||||
"saveTemplate": "保存模板"
|
||||
"saveTemplate": "保存模板",
|
||||
"renameTips": "重命名{name}"
|
||||
},
|
||||
"monitorPage": {
|
||||
"scriptMode": "脚本类型",
|
||||
|
@ -76,4 +76,6 @@ export default Object.freeze({
|
||||
SFTPTransferFile: 75,
|
||||
SFTPDeleteFile: 76,
|
||||
ShowServerScriptPage: 77,
|
||||
SFTPRenameFile: 78,
|
||||
SFTPEditFile: 79,
|
||||
})
|
||||
|
@ -287,7 +287,7 @@
|
||||
<VAceEditor
|
||||
v-model:value="formProps.script"
|
||||
lang="sh"
|
||||
theme="github"
|
||||
:theme="isDark ? 'one_dark' : 'github'"
|
||||
style="height: 360px; width: 100%"
|
||||
:options="{ newLineMode: 'unix' }"
|
||||
/>
|
||||
|
@ -157,6 +157,13 @@
|
||||
{{ $t('preview') }}
|
||||
</Link>
|
||||
</el-dropdown-item>
|
||||
<DropdownItem
|
||||
v-if="selectedFile['isDir'] === false"
|
||||
:permissions="[permission.SFTPEditFile]"
|
||||
@click="editFile"
|
||||
>
|
||||
{{ $t('edit') }}
|
||||
</DropdownItem>
|
||||
<el-dropdown-item
|
||||
v-if="selectedFile['isDir'] === false"
|
||||
style="padding: 0"
|
||||
@ -171,6 +178,12 @@
|
||||
{{ $t('download') }}
|
||||
</Link>
|
||||
</el-dropdown-item>
|
||||
<DropdownItem
|
||||
:permissions="[permission.SFTPRenameFile]"
|
||||
@click="rename"
|
||||
>
|
||||
{{ $t('rename') }}
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
v-if="selectedFile['isDir'] === false"
|
||||
:permissions="[permission.SFTPDeleteFile]"
|
||||
@ -223,14 +236,18 @@ import path from 'path-browserify'
|
||||
import { humanSize, parseTime } from '@/utils'
|
||||
import { NamespaceKey, getNamespaceId } from '@/utils/namespace'
|
||||
import type { ElUpload } from 'element-plus'
|
||||
import { ServerData, ServerSFTPFile, ServerDeleteFile } from '@/api/server'
|
||||
import {
|
||||
ServerData,
|
||||
ServerSFTPFile,
|
||||
ServerRenameFile,
|
||||
ServerDeleteFile,
|
||||
} from '@/api/server'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { HttpResponse } from '@/api/types'
|
||||
import { ref, PropType, computed, onBeforeUnmount } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { t } = useI18n()
|
||||
|
||||
const emit = defineEmits(['dir-change', 'transfer-file'])
|
||||
const emit = defineEmits(['dir-change', 'edit-file', 'transfer-file'])
|
||||
const props = defineProps({
|
||||
uuid: {
|
||||
type: Number,
|
||||
@ -443,6 +460,43 @@ function deleteFile() {
|
||||
.catch()
|
||||
}
|
||||
|
||||
function editFile() {
|
||||
emit('edit-file', selectedFile.value)
|
||||
}
|
||||
|
||||
function rename() {
|
||||
ElMessageBox.prompt(
|
||||
t('serverPage.renameTips', { name: selectedFile.value.name }),
|
||||
t('rename'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
inputPattern: /.+/,
|
||||
inputErrorMessage: 'Name required',
|
||||
}
|
||||
)
|
||||
.then(({ value }) => {
|
||||
fileListLoading.value = true
|
||||
new ServerRenameFile({
|
||||
serverId: serverId.value,
|
||||
dir: dir.value,
|
||||
currentName: selectedFile.value.name,
|
||||
newName: value,
|
||||
})
|
||||
.request()
|
||||
.then(() => {
|
||||
const pos = fileList.value.findIndex(
|
||||
(item) => item.name === selectedFile.value.name
|
||||
)
|
||||
fileList.value[pos].name = value
|
||||
})
|
||||
.finally(() => {
|
||||
fileListLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch()
|
||||
}
|
||||
|
||||
function transferFile() {
|
||||
emit('transfer-file', selectedFile.value)
|
||||
}
|
||||
|
@ -56,6 +56,7 @@
|
||||
:key="item.uuid"
|
||||
:server="item.server"
|
||||
@dir-change="handleDirChange"
|
||||
@edit-file="handleEditFile"
|
||||
@transfer-file="handleTransferFile"
|
||||
></explorer>
|
||||
<el-dialog
|
||||
@ -130,6 +131,36 @@
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
v-model="fileEditorDialogVisible"
|
||||
:fullscreen="$store.state.app.device === 'mobile'"
|
||||
:title="selectedFile['name']"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<VAceEditor
|
||||
ref="fileEditor"
|
||||
v-model:value="fileContent"
|
||||
v-loading="formProps.disabled"
|
||||
:lang="getModeForPath(selectedFile['name']).name"
|
||||
:theme="isDark ? 'one_dark' : 'github'"
|
||||
style="height: 360px; width: 100%"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button
|
||||
:disabled="formProps.disabled"
|
||||
@click="fileEditorDialogVisible = false"
|
||||
>
|
||||
{{ $t('cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="formProps.disabled"
|
||||
@click="editFile"
|
||||
>
|
||||
{{ $t('confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@ -141,20 +172,36 @@ import explorer from './explorer.vue'
|
||||
import path from 'path-browserify'
|
||||
import type { ElForm } from 'element-plus'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { VAceEditor } from 'vue3-ace-editor'
|
||||
import * as ace from 'ace-builds/src-noconflict/ace'
|
||||
import { getModeForPath } from 'ace-builds/src-noconflict/ext-modelist'
|
||||
import { NamespaceKey, getNamespaceId } from '@/utils/namespace'
|
||||
import {
|
||||
ServerOption,
|
||||
ServerData,
|
||||
ServerSFTPFile,
|
||||
ServerEditFile,
|
||||
ServerTransferFile,
|
||||
} from '@/api/server'
|
||||
import { useDark } from '@vueuse/core'
|
||||
import { ref } from 'vue'
|
||||
interface sftp {
|
||||
uuid: number
|
||||
server: ServerData
|
||||
dir: string
|
||||
}
|
||||
ace.config.set(
|
||||
'basePath',
|
||||
'https://cdn.jsdelivr.net/npm/ace-builds@' + ace.version + '/src-noconflict/'
|
||||
)
|
||||
ace.config.set(
|
||||
'themePath',
|
||||
'https://cdn.jsdelivr.net/npm/ace-builds@' + ace.version + '/src-noconflict/'
|
||||
)
|
||||
const isDark = useDark()
|
||||
const currentUUID = ref(0)
|
||||
const transferFileDialogVisible = ref(false)
|
||||
const fileEditorDialogVisible = ref(false)
|
||||
const serverOption = ref<ServerOption['datagram']['list']>([])
|
||||
const serverId = ref('')
|
||||
const serverList = ref<sftp[]>([])
|
||||
@ -171,6 +218,8 @@ const formProps = ref({
|
||||
errorLog: '',
|
||||
})
|
||||
|
||||
const fileContent = ref('')
|
||||
|
||||
getServerOption()
|
||||
|
||||
function getServerOption() {
|
||||
@ -212,6 +261,46 @@ function handleDirChange(dir: string) {
|
||||
selectedSFTP.value.dir = dir
|
||||
}
|
||||
|
||||
function handleEditFile(file: ServerSFTPFile) {
|
||||
selectedFile.value = file
|
||||
fileContent.value = ''
|
||||
fileEditorDialogVisible.value = true
|
||||
formProps.value.disabled = true
|
||||
const f = path.normalize(`${selectedSFTP.value.dir}/${file.name}`)
|
||||
fetch(
|
||||
`${
|
||||
import.meta.env.VITE_APP_BASE_API
|
||||
}/server/previewFile?${NamespaceKey}=${getNamespaceId()}&id=${
|
||||
selectedSFTP.value.server.id
|
||||
}&file=${f}`
|
||||
)
|
||||
.then((response) => response.text())
|
||||
.then((content) => {
|
||||
fileContent.value = content
|
||||
})
|
||||
.finally(() => {
|
||||
formProps.value.disabled = false
|
||||
})
|
||||
}
|
||||
|
||||
function editFile() {
|
||||
formProps.value.disabled = true
|
||||
new ServerEditFile({
|
||||
serverId: selectedSFTP.value.server.id,
|
||||
file: path.normalize(
|
||||
`${selectedSFTP.value.dir}/${selectedFile.value.name}`
|
||||
),
|
||||
content: fileContent.value,
|
||||
})
|
||||
.request()
|
||||
.then(() => {
|
||||
ElMessage.success('Success')
|
||||
})
|
||||
.finally(() => {
|
||||
formProps.value.disabled = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleTransferFile(file: ServerSFTPFile) {
|
||||
formData.value.destDir = selectedSFTP.value.dir
|
||||
formData.value.sourceFile = path.normalize(
|
||||
|
Loading…
Reference in New Issue
Block a user