mirror of
https://github.com/nezhahq/nezha.git
synced 2025-01-22 12:48:14 -05:00
✨ feat: 展示排序 close #29
This commit is contained in:
parent
35766e590d
commit
347bb7faa0
@ -27,7 +27,7 @@ func (cp *commonPage) home(c *gin.Context) {
|
||||
dao.ServerLock.RLock()
|
||||
defer dao.ServerLock.RUnlock()
|
||||
data := gin.H{
|
||||
"Servers": dao.ServerList,
|
||||
"Servers": dao.SortedServerList,
|
||||
"CustomCode": dao.Conf.Site.CustomCode,
|
||||
}
|
||||
u, ok := c.Get(model.CtxKeyAuthorizedUser)
|
||||
@ -54,7 +54,7 @@ func (cp *commonPage) ws(c *gin.Context) {
|
||||
defer conn.Close()
|
||||
for {
|
||||
dao.ServerLock.RLock()
|
||||
err = conn.WriteJSON(dao.ServerList)
|
||||
err = conn.WriteJSON(dao.SortedServerList)
|
||||
dao.ServerLock.RUnlock()
|
||||
if err != nil {
|
||||
break
|
||||
|
@ -56,7 +56,8 @@ func (ma *memberAPI) delete(c *gin.Context) {
|
||||
defer dao.ServerLock.Unlock()
|
||||
err = dao.DB.Delete(&model.Server{}, "id = ?", id).Error
|
||||
if err == nil {
|
||||
delete(dao.ServerList, strconv.FormatUint(id, 10))
|
||||
delete(dao.ServerList, id)
|
||||
dao.ReSortServer()
|
||||
}
|
||||
case "notification":
|
||||
err = dao.DB.Delete(&model.Notification{}, "id = ?", id).Error
|
||||
@ -82,9 +83,10 @@ func (ma *memberAPI) delete(c *gin.Context) {
|
||||
}
|
||||
|
||||
type serverForm struct {
|
||||
ID uint64
|
||||
Name string `binding:"required"`
|
||||
Secret string
|
||||
ID uint64
|
||||
Name string `binding:"required"`
|
||||
DisplayIndex int
|
||||
Secret string
|
||||
}
|
||||
|
||||
func (ma *memberAPI) addOrEditServer(c *gin.Context) {
|
||||
@ -97,14 +99,15 @@ func (ma *memberAPI) addOrEditServer(c *gin.Context) {
|
||||
defer dao.ServerLock.Unlock()
|
||||
s.Name = sf.Name
|
||||
s.Secret = sf.Secret
|
||||
s.DisplayIndex = sf.DisplayIndex
|
||||
s.ID = sf.ID
|
||||
}
|
||||
if sf.ID == 0 {
|
||||
s.Secret = com.MD5(fmt.Sprintf("%s%s%d", time.Now(), sf.Name, admin.ID))
|
||||
s.Secret = s.Secret[:10]
|
||||
err = dao.DB.Create(&s).Error
|
||||
} else {
|
||||
err = dao.DB.Save(&s).Error
|
||||
if sf.ID == 0 {
|
||||
s.Secret = com.MD5(fmt.Sprintf("%s%s%d", time.Now(), sf.Name, admin.ID))
|
||||
s.Secret = s.Secret[:10]
|
||||
err = dao.DB.Create(&s).Error
|
||||
} else {
|
||||
err = dao.DB.Save(&s).Error
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
@ -115,7 +118,8 @@ func (ma *memberAPI) addOrEditServer(c *gin.Context) {
|
||||
}
|
||||
s.Host = &model.Host{}
|
||||
s.State = &model.State{}
|
||||
dao.ServerList[fmt.Sprintf("%d", s.ID)] = &s
|
||||
dao.ServerList[s.ID] = &s
|
||||
dao.ReSortServer()
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
Code: http.StatusOK,
|
||||
})
|
||||
|
@ -32,7 +32,7 @@ func (mp *memberPage) server(c *gin.Context) {
|
||||
defer dao.ServerLock.RUnlock()
|
||||
c.HTML(http.StatusOK, "dashboard/server", mygin.CommonEnvironment(c, gin.H{
|
||||
"Title": "服务器管理",
|
||||
"Servers": dao.ServerList,
|
||||
"Servers": dao.SortedServerList,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/patrickmn/go-cache"
|
||||
@ -17,7 +16,7 @@ import (
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
dao.ServerList = make(map[string]*model.Server)
|
||||
dao.ServerList = make(map[uint64]*model.Server)
|
||||
dao.Conf = &model.Config{}
|
||||
err = dao.Conf.Read("data/config.yaml")
|
||||
if err != nil {
|
||||
@ -43,8 +42,9 @@ func initDB() {
|
||||
innerS := s
|
||||
innerS.Host = &model.Host{}
|
||||
innerS.State = &model.State{}
|
||||
dao.ServerList[fmt.Sprintf("%d", innerS.ID)] = &innerS
|
||||
dao.ServerList[innerS.ID] = &innerS
|
||||
}
|
||||
dao.ReSortServer()
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -11,8 +11,9 @@ import (
|
||||
// Server ..
|
||||
type Server struct {
|
||||
Common
|
||||
Name string
|
||||
Secret string `json:"-"`
|
||||
Name string
|
||||
DisplayIndex int // 展示权重,越大越靠前
|
||||
Secret string `json:"-"`
|
||||
|
||||
Host *Host `gorm:"-"`
|
||||
State *State `gorm:"-"`
|
||||
|
@ -36,7 +36,10 @@ function showFormModal(modelSelector, formID, URL, getData) {
|
||||
form.children('.message').remove()
|
||||
btn.toggleClass('loading')
|
||||
const data = getData ? getData() : $(formID).serializeArray().reduce(function (obj, item) {
|
||||
obj[item.name] = (item.name.endsWith('_id') || item.name === 'id' || item.name === 'ID' || item.name === 'RequestType' || item.name === 'RequestMethod') ? parseInt(item.value) : item.value;
|
||||
obj[item.name] = (item.name.endsWith('_id') ||
|
||||
item.name === 'id' || item.name === 'ID' ||
|
||||
item.name === 'RequestType' || item.name === 'RequestMethod' ||
|
||||
item.name === 'DisplayIndex') ? parseInt(item.value) : item.value;
|
||||
return obj;
|
||||
}, {});
|
||||
$.post(URL, JSON.stringify(data)).done(function (resp) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.1/dist/semantic.min.js"></script>
|
||||
<script src="/static/semantic-ui-alerts.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.min.js"></script>
|
||||
<script src="/static/main.js?v202012211616"></script>
|
||||
<script src="/static/main.js?v202101082103"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
@ -8,6 +8,10 @@
|
||||
<label>备注</label>
|
||||
<input type="text" name="name" placeholder="爱因斯坦-光速1号">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>展示权重</label>
|
||||
<input type="number" name="DisplayIndex" placeholder="越大越靠前">
|
||||
</div>
|
||||
<div class="secret field">
|
||||
<label>密钥</label>
|
||||
<input type="text" name="secret">
|
||||
|
@ -13,20 +13,20 @@
|
||||
<table class="ui very basic table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>权重</th>
|
||||
<th>备注</th>
|
||||
<th>IP</th>
|
||||
<th>密钥</th>
|
||||
<th>最后活跃</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range $server := .Servers}}
|
||||
<tr>
|
||||
<td>{{$server.ID}}</td>
|
||||
<td>{{$server.DisplayIndex}}</td>
|
||||
<td>{{$server.Name}}</td>
|
||||
<td>{{$server.Host.IP}}</td>
|
||||
<td>{{$server.Secret}}</td>
|
||||
<td>{{$server.LastActive}}</td>
|
||||
<td>
|
||||
<div class="ui mini icon buttons">
|
||||
<button class="ui button" onclick="addOrEditServer({{$server.Marshal}})">
|
||||
|
@ -172,9 +172,8 @@
|
||||
ws.onmessage = function (evt) {
|
||||
const oldServers = statusCards.servers
|
||||
statusCards.servers = JSON.parse(evt.data)
|
||||
const keys = Object.keys(statusCards.servers)
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const ns = statusCards.servers[keys[i]];
|
||||
for (let i = 0; i < statusCards.servers.length; i++) {
|
||||
const ns = statusCards.servers[i];
|
||||
if (!ns.Host) ns.live = false
|
||||
else {
|
||||
const lastActive = new Date(ns.LastActive).getTime()
|
||||
|
@ -238,9 +238,8 @@
|
||||
}
|
||||
ws.onmessage = function (evt) {
|
||||
statusCards.servers = JSON.parse(evt.data)
|
||||
const keys = Object.keys(statusCards.servers)
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const ns = statusCards.servers[keys[i]];
|
||||
for (let i = 0; i < statusCards.servers.length; i++) {
|
||||
const ns = statusCards.servers[i];
|
||||
if (!ns.Host) ns.live = false
|
||||
else {
|
||||
const lastActive = new Date(ns.LastActive).getTime()
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/patrickmn/go-cache"
|
||||
@ -25,7 +26,8 @@ var Cache *cache.Cache
|
||||
var DB *gorm.DB
|
||||
|
||||
// ServerList ..
|
||||
var ServerList map[string]*model.Server
|
||||
var ServerList map[uint64]*model.Server
|
||||
var SortedServerList []*model.Server
|
||||
|
||||
// ServerLock ..
|
||||
var ServerLock sync.RWMutex
|
||||
@ -39,6 +41,17 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func ReSortServer() {
|
||||
SortedServerList = []*model.Server{}
|
||||
for _, s := range ServerList {
|
||||
SortedServerList = append(SortedServerList, s)
|
||||
}
|
||||
|
||||
sort.SliceStable(SortedServerList, func(i, j int) bool {
|
||||
return SortedServerList[i].DisplayIndex > SortedServerList[j].DisplayIndex
|
||||
})
|
||||
}
|
||||
|
||||
// SendCommand ..
|
||||
func SendCommand(cmd *pb.Command) {
|
||||
ServerLock.RLock()
|
||||
|
@ -2,6 +2,7 @@ package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/naiba/nezha/service/dao"
|
||||
"google.golang.org/grpc/codes"
|
||||
@ -26,18 +27,15 @@ func (a *AuthHandler) RequireTransportSecurity() bool {
|
||||
}
|
||||
|
||||
// Check ..
|
||||
func (a *AuthHandler) Check(ctx context.Context) (clientID string, err error) {
|
||||
func (a *AuthHandler) Check(ctx context.Context) (clientID uint64, err error) {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
err = status.Errorf(codes.Unauthenticated, "获取 metaData 失败")
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
clientSecret string
|
||||
)
|
||||
var clientSecret string
|
||||
if value, ok := md["client_id"]; ok {
|
||||
clientID = value[0]
|
||||
clientID, _ = strconv.ParseUint(value[0], 10, 64)
|
||||
}
|
||||
if value, ok := md["client_secret"]; ok {
|
||||
clientSecret = value[0]
|
||||
|
@ -17,7 +17,7 @@ type NezhaHandler struct {
|
||||
|
||||
// ReportState ..
|
||||
func (s *NezhaHandler) ReportState(c context.Context, r *pb.State) (*pb.Receipt, error) {
|
||||
var clientID string
|
||||
var clientID uint64
|
||||
var err error
|
||||
if clientID, err = s.Auth.Check(c); err != nil {
|
||||
return nil, err
|
||||
@ -32,7 +32,7 @@ func (s *NezhaHandler) ReportState(c context.Context, r *pb.State) (*pb.Receipt,
|
||||
|
||||
// Heartbeat ..
|
||||
func (s *NezhaHandler) Heartbeat(r *pb.Beat, stream pb.NezhaService_HeartbeatServer) error {
|
||||
var clientID string
|
||||
var clientID uint64
|
||||
var err error
|
||||
defer log.Printf("Heartbeat exit server:%v err:%v", clientID, err)
|
||||
if clientID, err = s.Auth.Check(stream.Context()); err != nil {
|
||||
@ -52,7 +52,7 @@ func (s *NezhaHandler) Heartbeat(r *pb.Beat, stream pb.NezhaService_HeartbeatSer
|
||||
|
||||
// Register ..
|
||||
func (s *NezhaHandler) Register(c context.Context, r *pb.Host) (*pb.Receipt, error) {
|
||||
var clientID string
|
||||
var clientID uint64
|
||||
var err error
|
||||
if clientID, err = s.Auth.Check(c); err != nil {
|
||||
return nil, err
|
||||
|
Loading…
Reference in New Issue
Block a user