mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	增加企业版认证相关API
This commit is contained in:
		
							
								
								
									
										6
									
								
								internal/const/plus.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								internal/const/plus.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package teaconst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsPlus 是否为企业版
 | 
				
			||||||
 | 
					var IsPlus = false
 | 
				
			||||||
@@ -87,7 +87,7 @@ func (this *AdminNode) Run() {
 | 
				
			|||||||
		Start()
 | 
							Start()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 实现守护进程
 | 
					// Daemon 实现守护进程
 | 
				
			||||||
func (this *AdminNode) Daemon() {
 | 
					func (this *AdminNode) Daemon() {
 | 
				
			||||||
	path := os.TempDir() + "/edge-admin.sock"
 | 
						path := os.TempDir() + "/edge-admin.sock"
 | 
				
			||||||
	isDebug := lists.ContainsString(os.Args, "debug")
 | 
						isDebug := lists.ContainsString(os.Args, "debug")
 | 
				
			||||||
@@ -132,7 +132,7 @@ func (this *AdminNode) Daemon() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 安装系统服务
 | 
					// InstallSystemService 安装系统服务
 | 
				
			||||||
func (this *AdminNode) InstallSystemService() error {
 | 
					func (this *AdminNode) InstallSystemService() error {
 | 
				
			||||||
	shortName := teaconst.SystemdServiceName
 | 
						shortName := teaconst.SystemdServiceName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -149,7 +149,7 @@ func (this *AdminNode) InstallSystemService() error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 添加子PID
 | 
					// AddSubPID 添加子PID
 | 
				
			||||||
func (this *AdminNode) AddSubPID(pid int) {
 | 
					func (this *AdminNode) AddSubPID(pid int) {
 | 
				
			||||||
	this.subPIDs = append(this.subPIDs, pid)
 | 
						this.subPIDs = append(this.subPIDs, pid)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -207,7 +207,7 @@ func (this *RPCClient) HTTPRewriteRuleRPC() pb.HTTPRewriteRuleServiceClient {
 | 
				
			|||||||
	return pb.NewHTTPRewriteRuleServiceClient(this.pickConn())
 | 
						return pb.NewHTTPRewriteRuleServiceClient(this.pickConn())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 访问日志
 | 
					// HTTPAccessLogRPC 访问日志
 | 
				
			||||||
func (this *RPCClient) HTTPAccessLogRPC() pb.HTTPAccessLogServiceClient {
 | 
					func (this *RPCClient) HTTPAccessLogRPC() pb.HTTPAccessLogServiceClient {
 | 
				
			||||||
	return pb.NewHTTPAccessLogServiceClient(this.pickConn())
 | 
						return pb.NewHTTPAccessLogServiceClient(this.pickConn())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -328,7 +328,11 @@ func (this *RPCClient) NodeTaskRPC() pb.NodeTaskServiceClient {
 | 
				
			|||||||
	return pb.NewNodeTaskServiceClient(this.pickConn())
 | 
						return pb.NewNodeTaskServiceClient(this.pickConn())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 构造Admin上下文
 | 
					func (this *RPCClient) AuthorityKeyRPC() pb.AuthorityKeyServiceClient {
 | 
				
			||||||
 | 
						return pb.NewAuthorityKeyServiceClient(this.pickConn())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Context 构造Admin上下文
 | 
				
			||||||
func (this *RPCClient) Context(adminId int64) context.Context {
 | 
					func (this *RPCClient) Context(adminId int64) context.Context {
 | 
				
			||||||
	ctx := context.Background()
 | 
						ctx := context.Background()
 | 
				
			||||||
	m := maps.Map{
 | 
						m := maps.Map{
 | 
				
			||||||
@@ -351,7 +355,7 @@ func (this *RPCClient) Context(adminId int64) context.Context {
 | 
				
			|||||||
	return ctx
 | 
						return ctx
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 构造API上下文
 | 
					// APIContext 构造API上下文
 | 
				
			||||||
func (this *RPCClient) APIContext(apiNodeId int64) context.Context {
 | 
					func (this *RPCClient) APIContext(apiNodeId int64) context.Context {
 | 
				
			||||||
	ctx := context.Background()
 | 
						ctx := context.Background()
 | 
				
			||||||
	m := maps.Map{
 | 
						m := maps.Map{
 | 
				
			||||||
@@ -374,7 +378,7 @@ func (this *RPCClient) APIContext(apiNodeId int64) context.Context {
 | 
				
			|||||||
	return ctx
 | 
						return ctx
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 修改配置
 | 
					// UpdateConfig 修改配置
 | 
				
			||||||
func (this *RPCClient) UpdateConfig(config *configs.APIConfig) error {
 | 
					func (this *RPCClient) UpdateConfig(config *configs.APIConfig) error {
 | 
				
			||||||
	this.apiConfig = config
 | 
						this.apiConfig = config
 | 
				
			||||||
	return this.init()
 | 
						return this.init()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										68
									
								
								internal/tasks/task_authority.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								internal/tasks/task_authority.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package tasks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/events"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/logs"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						events.On(events.EventStart, func() {
 | 
				
			||||||
 | 
							task := NewAuthorityTask()
 | 
				
			||||||
 | 
							go task.Start()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type AuthorityTask struct {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewAuthorityTask() *AuthorityTask {
 | 
				
			||||||
 | 
						return &AuthorityTask{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *AuthorityTask) Start() {
 | 
				
			||||||
 | 
						ticker := time.NewTicker(10 * time.Minute)
 | 
				
			||||||
 | 
						if Tea.IsTesting() {
 | 
				
			||||||
 | 
							// 快速测试
 | 
				
			||||||
 | 
							ticker = time.NewTicker(1 * time.Minute)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 初始化的时候先获取一次
 | 
				
			||||||
 | 
						timeout := time.NewTimer(5 * time.Second)
 | 
				
			||||||
 | 
						<-timeout.C
 | 
				
			||||||
 | 
						err := this.Loop()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logs.Println("[TASK][AuthorityTask]" + err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 定时获取
 | 
				
			||||||
 | 
						for range ticker.C {
 | 
				
			||||||
 | 
							err := this.Loop()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logs.Println("[TASK][AuthorityTask]" + err.Error())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *AuthorityTask) Loop() error {
 | 
				
			||||||
 | 
						rpcClient, err := rpc.SharedRPC()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						resp, err := rpcClient.AuthorityKeyRPC().ReadAuthorityKey(rpcClient.Context(0), &pb.ReadAuthorityKeyRequest{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if resp.AuthorityKey != nil {
 | 
				
			||||||
 | 
							teaconst.IsPlus = true
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							teaconst.IsPlus = false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										51
									
								
								internal/web/actions/default/settings/authority/index.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								internal/web/actions/default/settings/authority/index.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
						timeutil "github.com/iwind/TeaGo/utils/time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type IndexAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IndexAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *IndexAction) RunGet(params struct{}) {
 | 
				
			||||||
 | 
						keyResp, err := this.RPC().AuthorityKeyRPC().ReadAuthorityKey(this.AdminContext(), &pb.ReadAuthorityKeyRequest{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var keyMap maps.Map = nil
 | 
				
			||||||
 | 
						teaconst.IsPlus = false
 | 
				
			||||||
 | 
						if keyResp.AuthorityKey != nil {
 | 
				
			||||||
 | 
							if len(keyResp.AuthorityKey.MacAddresses) == 0 {
 | 
				
			||||||
 | 
								keyResp.AuthorityKey.MacAddresses = []string{}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							isActive := len(keyResp.AuthorityKey.DayTo) > 0 && keyResp.AuthorityKey.DayTo >= timeutil.Format("Y-m-d")
 | 
				
			||||||
 | 
							if isActive {
 | 
				
			||||||
 | 
								teaconst.IsPlus = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							keyMap = maps.Map{
 | 
				
			||||||
 | 
								"dayFrom":      keyResp.AuthorityKey.DayFrom,
 | 
				
			||||||
 | 
								"dayTo":        keyResp.AuthorityKey.DayTo,
 | 
				
			||||||
 | 
								"macAddresses": keyResp.AuthorityKey.MacAddresses,
 | 
				
			||||||
 | 
								"hostname":     keyResp.AuthorityKey.Hostname,
 | 
				
			||||||
 | 
								"isExpired":    !isActive,
 | 
				
			||||||
 | 
								"updatedTime":  timeutil.FormatTime("Y-m-d H:i:s", keyResp.AuthorityKey.UpdatedAt),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["key"] = keyMap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								internal/web/actions/default/settings/authority/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								internal/web/actions/default/settings/authority/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					package server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/settingutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
				
			||||||
 | 
							server.
 | 
				
			||||||
 | 
								Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeSetting)).
 | 
				
			||||||
 | 
								Helper(settingutils.NewAdvancedHelper("authority")).
 | 
				
			||||||
 | 
								Prefix("/settings/authority").
 | 
				
			||||||
 | 
								Get("", new(IndexAction)).
 | 
				
			||||||
 | 
								EndAll()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,6 +2,7 @@ package settingutils
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
				
			||||||
 | 
						teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
	"github.com/iwind/TeaGo/actions"
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -34,7 +35,10 @@ func (this *AdvancedHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNex
 | 
				
			|||||||
		tabbar.Add("API节点", "", "/api", "", this.tab == "apiNodes")
 | 
							tabbar.Add("API节点", "", "/api", "", this.tab == "apiNodes")
 | 
				
			||||||
		tabbar.Add("用户节点", "", "/settings/userNodes", "", this.tab == "userNodes")
 | 
							tabbar.Add("用户节点", "", "/settings/userNodes", "", this.tab == "userNodes")
 | 
				
			||||||
		tabbar.Add("日志数据库", "", "/db", "", this.tab == "dbNodes")
 | 
							tabbar.Add("日志数据库", "", "/db", "", this.tab == "dbNodes")
 | 
				
			||||||
		tabbar.Add("监控节点", "", "/settings/monitorNodes", "", this.tab == "monitorNodes")
 | 
							if teaconst.IsPlus {
 | 
				
			||||||
 | 
								tabbar.Add("监控节点", "", "/settings/monitorNodes", "", this.tab == "monitorNodes")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							tabbar.Add("企业版认证", "", "/settings/authority", "", this.tab == "authority")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//tabbar.Add("备份", "", "/settings/backup", "", this.tab == "backup")
 | 
							//tabbar.Add("备份", "", "/settings/backup", "", this.tab == "backup")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -234,6 +234,7 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
 | 
				
			|||||||
					"name": "通知媒介",
 | 
										"name": "通知媒介",
 | 
				
			||||||
					"url":  "/admins/recipients",
 | 
										"url":  "/admins/recipients",
 | 
				
			||||||
					"code": "recipients",
 | 
										"code": "recipients",
 | 
				
			||||||
 | 
										"isOn": teaconst.IsPlus,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,6 +84,7 @@ import (
 | 
				
			|||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/websocket"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/websocket"
 | 
				
			||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/stat"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/stat"
 | 
				
			||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings"
 | 
				
			||||||
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority"
 | 
				
			||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/backup"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/backup"
 | 
				
			||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/database"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/database"
 | 
				
			||||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/ip-library"
 | 
						_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/ip-library"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,7 +85,7 @@
 | 
				
			|||||||
                    <div class="subtitle" v-if="module.subtitle != null && module.subtitle.length > 0">{{module.subtitle}}</div>
 | 
					                    <div class="subtitle" v-if="module.subtitle != null && module.subtitle.length > 0">{{module.subtitle}}</div>
 | 
				
			||||||
				</a>
 | 
									</a>
 | 
				
			||||||
				<div v-if="teaMenu == module.code" class="sub-items">
 | 
									<div v-if="teaMenu == module.code" class="sub-items">
 | 
				
			||||||
					<a class="item" v-for="subItem in module.subItems" :href="subItem.url" :class="{active:subItem.code == teaSubMenu}">{{subItem.name}}</a>
 | 
										<a class="item" v-for="subItem in module.subItems" v-if="subItem.isOn !== false" :href="subItem.url" :class="{active:subItem.code == teaSubMenu}">{{subItem.name}}</a>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										41
									
								
								web/views/@default/settings/authority/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								web/views/@default/settings/authority/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="ui message warning" v-if="key == null">认证之后,可以使用企业版功能,当前你还没有认证,<a href="http://edge.teaos.cn/docs/Plus/Authority/Index.md" target="_blank">[在这里看认证方法]</a>。</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div v-if="key != null">
 | 
				
			||||||
 | 
					    <div class="margin"></div>
 | 
				
			||||||
 | 
					    <table class="ui table definition selectable">
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>状态</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <span class="green">已认证</span>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td class="title">开始日期</td>
 | 
				
			||||||
 | 
					            <td>{{key.dayFrom}}</td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td class="title">结束日期</td>
 | 
				
			||||||
 | 
					            <td>{{key.dayTo}}
 | 
				
			||||||
 | 
					                <div v-if="key.isExpired" style="margin-top: 0.5em">
 | 
				
			||||||
 | 
					                    <span class="red">已过期,请尽快更新认证信息。</span>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>主机名</td>
 | 
				
			||||||
 | 
					            <td>{{key.hostname}}
 | 
				
			||||||
 | 
					                <p class="comment">认证服务所在服务器主机名。</p>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>主机MAC地址</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <span v-for="address in key.macAddresses" class="ui label basic small">{{address}}</span>
 | 
				
			||||||
 | 
					                <p class="comment">认证服务所在服务器的MAC地址。</p>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					    <p class="comment">数据更新于{{key.updatedTime}}。</p>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user