✨ batch update server tag
This commit is contained in:
		
							parent
							
								
									41b84163b9
								
							
						
					
					
						commit
						9352d3d0e0
					
				@ -167,6 +167,8 @@ type Data struct {
 | 
				
			|||||||
	Servers []*model.Server `json:"servers,omitempty"`
 | 
						Servers []*model.Server `json:"servers,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var cloudflareCookiesValidator = regexp.MustCompile("^[A-Za-z0-9-_]+$")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cp *commonPage) ws(c *gin.Context) {
 | 
					func (cp *commonPage) ws(c *gin.Context) {
 | 
				
			||||||
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
 | 
						conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@ -285,7 +287,7 @@ func (cp *commonPage) terminal(c *gin.Context) {
 | 
				
			|||||||
			encodedCookies := strings.Split(cloudflareCookies, ".")
 | 
								encodedCookies := strings.Split(cloudflareCookies, ".")
 | 
				
			||||||
			if len(encodedCookies) == 3 {
 | 
								if len(encodedCookies) == 3 {
 | 
				
			||||||
				for i := 0; i < 3; i++ {
 | 
									for i := 0; i < 3; i++ {
 | 
				
			||||||
					if valid, _ := regexp.MatchString("^[A-Za-z0-9-_]+$", encodedCookies[i]); !valid {
 | 
										if !cloudflareCookiesValidator.MatchString(encodedCookies[i]) {
 | 
				
			||||||
						cloudflareCookies = ""
 | 
											cloudflareCookies = ""
 | 
				
			||||||
						break
 | 
											break
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gin-gonic/gin"
 | 
						"github.com/gin-gonic/gin"
 | 
				
			||||||
 | 
						"github.com/jinzhu/copier"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/naiba/nezha/model"
 | 
						"github.com/naiba/nezha/model"
 | 
				
			||||||
	"github.com/naiba/nezha/pkg/mygin"
 | 
						"github.com/naiba/nezha/pkg/mygin"
 | 
				
			||||||
@ -39,6 +40,7 @@ func (ma *memberAPI) serve() {
 | 
				
			|||||||
	mr.POST("/cron", ma.addOrEditCron)
 | 
						mr.POST("/cron", ma.addOrEditCron)
 | 
				
			||||||
	mr.GET("/cron/:id/manual", ma.manualTrigger)
 | 
						mr.GET("/cron/:id/manual", ma.manualTrigger)
 | 
				
			||||||
	mr.POST("/force-update", ma.forceUpdate)
 | 
						mr.POST("/force-update", ma.forceUpdate)
 | 
				
			||||||
 | 
						mr.POST("/batch-update-server-group", ma.batchUpdateServerGroup)
 | 
				
			||||||
	mr.POST("/notification", ma.addOrEditNotification)
 | 
						mr.POST("/notification", ma.addOrEditNotification)
 | 
				
			||||||
	mr.POST("/alert-rule", ma.addOrEditAlertRule)
 | 
						mr.POST("/alert-rule", ma.addOrEditAlertRule)
 | 
				
			||||||
	mr.POST("/setting", ma.updateSetting)
 | 
						mr.POST("/setting", ma.updateSetting)
 | 
				
			||||||
@ -537,6 +539,67 @@ func (ma *memberAPI) manualTrigger(c *gin.Context) {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BatchUpdateServerGroupRequest struct {
 | 
				
			||||||
 | 
						Servers []uint64
 | 
				
			||||||
 | 
						Group   string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ma *memberAPI) batchUpdateServerGroup(c *gin.Context) {
 | 
				
			||||||
 | 
						var req BatchUpdateServerGroupRequest
 | 
				
			||||||
 | 
						if err := c.ShouldBindJSON(&req); err != nil {
 | 
				
			||||||
 | 
							c.JSON(http.StatusOK, model.Response{
 | 
				
			||||||
 | 
								Code:    http.StatusBadRequest,
 | 
				
			||||||
 | 
								Message: err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := singleton.DB.Model(&model.Server{}).Where("id in (?)", req.Servers).Update("tag", req.Group).Error; err != nil {
 | 
				
			||||||
 | 
							c.JSON(http.StatusOK, model.Response{
 | 
				
			||||||
 | 
								Code:    http.StatusBadRequest,
 | 
				
			||||||
 | 
								Message: err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						singleton.ServerLock.Lock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i := 0; i < len(req.Servers); i++ {
 | 
				
			||||||
 | 
							serverId := req.Servers[i]
 | 
				
			||||||
 | 
							var s model.Server
 | 
				
			||||||
 | 
							copier.Copy(&s, singleton.ServerList[serverId])
 | 
				
			||||||
 | 
							s.Tag = req.Group
 | 
				
			||||||
 | 
							// 如果修改了Tag
 | 
				
			||||||
 | 
							if s.Tag != singleton.ServerList[s.ID].Tag {
 | 
				
			||||||
 | 
								index := -1
 | 
				
			||||||
 | 
								for i := 0; i < len(singleton.ServerTagToIDList[s.Tag]); i++ {
 | 
				
			||||||
 | 
									if singleton.ServerTagToIDList[s.Tag][i] == s.ID {
 | 
				
			||||||
 | 
										index = i
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if index > -1 {
 | 
				
			||||||
 | 
									// 删除旧 Tag-ID 绑定关系
 | 
				
			||||||
 | 
									singleton.ServerTagToIDList[singleton.ServerList[s.ID].Tag] = append(singleton.ServerTagToIDList[singleton.ServerList[s.ID].Tag][:index], singleton.ServerTagToIDList[singleton.ServerList[s.ID].Tag][index+1:]...)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// 设置新的 Tag-ID 绑定关系
 | 
				
			||||||
 | 
								singleton.ServerTagToIDList[s.Tag] = append(singleton.ServerTagToIDList[s.Tag], s.ID)
 | 
				
			||||||
 | 
								if len(singleton.ServerTagToIDList[s.Tag]) == 0 {
 | 
				
			||||||
 | 
									delete(singleton.ServerTagToIDList, s.Tag)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							singleton.ServerList[s.ID] = &s
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						singleton.ServerLock.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						singleton.ReSortServer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c.JSON(http.StatusOK, model.Response{
 | 
				
			||||||
 | 
							Code: http.StatusOK,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ma *memberAPI) forceUpdate(c *gin.Context) {
 | 
					func (ma *memberAPI) forceUpdate(c *gin.Context) {
 | 
				
			||||||
	var forceUpdateServers []uint64
 | 
						var forceUpdateServers []uint64
 | 
				
			||||||
	if err := c.ShouldBindJSON(&forceUpdateServers); err != nil {
 | 
						if err := c.ShouldBindJSON(&forceUpdateServers); err != nil {
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,7 @@ import (
 | 
				
			|||||||
	"github.com/xanzy/go-gitlab"
 | 
						"github.com/xanzy/go-gitlab"
 | 
				
			||||||
	"golang.org/x/oauth2"
 | 
						"golang.org/x/oauth2"
 | 
				
			||||||
	GitHubOauth2 "golang.org/x/oauth2/github"
 | 
						GitHubOauth2 "golang.org/x/oauth2/github"
 | 
				
			||||||
	GitlabOauth2 "golang.org/x/oauth2/github"
 | 
						GitlabOauth2 "golang.org/x/oauth2/gitlab"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/naiba/nezha/model"
 | 
						"github.com/naiba/nezha/model"
 | 
				
			||||||
	"github.com/naiba/nezha/pkg/mygin"
 | 
						"github.com/naiba/nezha/pkg/mygin"
 | 
				
			||||||
@ -156,7 +156,7 @@ func (oa *oauth2controller) callback(c *gin.Context) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	var isAdmin bool
 | 
						var isAdmin bool
 | 
				
			||||||
	for _, admin := range strings.Split(singleton.Conf.Oauth2.Admin, ",") {
 | 
						for _, admin := range strings.Split(singleton.Conf.Oauth2.Admin, ",") {
 | 
				
			||||||
		if admin != "" && strings.ToLower(user.Login) == strings.ToLower(admin) {
 | 
							if admin != "" && strings.EqualFold(user.Login, admin) {
 | 
				
			||||||
			isAdmin = true
 | 
								isAdmin = true
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								resource/l10n/zh-CN.toml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								resource/l10n/zh-CN.toml
									
									
									
									
										vendored
									
									
								
							@ -181,6 +181,12 @@ other = "启用"
 | 
				
			|||||||
[AddServer]
 | 
					[AddServer]
 | 
				
			||||||
other = "添加服务器"
 | 
					other = "添加服务器"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[BatchEditServerGroup]
 | 
				
			||||||
 | 
					other = "批量修改分组"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[InputServerGroupName]
 | 
				
			||||||
 | 
					other = "输入分组名称"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ServerGroup]
 | 
					[ServerGroup]
 | 
				
			||||||
other = "服务器分组"
 | 
					other = "服务器分组"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										54
									
								
								resource/template/dashboard-default/server.html
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								resource/template/dashboard-default/server.html
									
									
									
									
										vendored
									
									
								
							@ -5,6 +5,9 @@
 | 
				
			|||||||
    <div class="ui container">
 | 
					    <div class="ui container">
 | 
				
			||||||
        <div class="ui grid">
 | 
					        <div class="ui grid">
 | 
				
			||||||
            <div class="right floated right aligned twelve wide column">
 | 
					            <div class="right floated right aligned twelve wide column">
 | 
				
			||||||
 | 
					                <button class="ui right labeled nezha-primary-btn icon button" onclick="batchEditServerGroup()"><i
 | 
				
			||||||
 | 
					                        class="edit icon"></i> {{tr "BatchEditServerGroup"}}
 | 
				
			||||||
 | 
					                </button>
 | 
				
			||||||
                <button class="ui right labeled nezha-primary-btn icon button" onclick="addOrEditServer()"><i
 | 
					                <button class="ui right labeled nezha-primary-btn icon button" onclick="addOrEditServer()"><i
 | 
				
			||||||
                        class="add icon"></i> {{tr "AddServer"}}
 | 
					                        class="add icon"></i> {{tr "AddServer"}}
 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
@ -128,5 +131,56 @@
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    function batchEditServerGroup() {
 | 
				
			||||||
 | 
					        let groupName = prompt('{{tr "InputServerGroupName"}}')
 | 
				
			||||||
 | 
					        if (!groupName) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const servers = []
 | 
				
			||||||
 | 
					        checkBoxList.forEach(cb => {
 | 
				
			||||||
 | 
					            if (cb.checked) {
 | 
				
			||||||
 | 
					                servers.push(parseInt(cb.value))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        if (servers.length == 0) {
 | 
				
			||||||
 | 
					            $.suiAlert({
 | 
				
			||||||
 | 
					                title: '{{tr "NoServerSelected"}}',
 | 
				
			||||||
 | 
					                description: '',
 | 
				
			||||||
 | 
					                type: 'warning',
 | 
				
			||||||
 | 
					                time: '2',
 | 
				
			||||||
 | 
					                position: 'top-center',
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $.post('/api/batch-update-server-group', JSON.stringify({ servers: servers, group: groupName }))
 | 
				
			||||||
 | 
					            .then((resp) => {
 | 
				
			||||||
 | 
					                if (resp.code == 200) {
 | 
				
			||||||
 | 
					                    $.suiAlert({
 | 
				
			||||||
 | 
					                        title: '{{tr "ExecutionResults"}}',
 | 
				
			||||||
 | 
					                        description: resp.message,
 | 
				
			||||||
 | 
					                        type: 'success',
 | 
				
			||||||
 | 
					                        time: '3',
 | 
				
			||||||
 | 
					                        position: 'top-center',
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                    window.location.reload()
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    $.suiAlert({
 | 
				
			||||||
 | 
					                        title: '',
 | 
				
			||||||
 | 
					                        description: resp.message,
 | 
				
			||||||
 | 
					                        type: 'error',
 | 
				
			||||||
 | 
					                        time: '3',
 | 
				
			||||||
 | 
					                        position: 'top-center',
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }).catch(err => {
 | 
				
			||||||
 | 
					                $.suiAlert({
 | 
				
			||||||
 | 
					                    title: '',
 | 
				
			||||||
 | 
					                    description: err,
 | 
				
			||||||
 | 
					                    type: 'error',
 | 
				
			||||||
 | 
					                    time: '3',
 | 
				
			||||||
 | 
					                    position: 'top-center',
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user