mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-04 21:50:28 +08:00
增加用户系统界面管理、用户可以设置关联集群
This commit is contained in:
@@ -9,17 +9,17 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
var sharedUIConfig *systemconfigs.AdminUIConfig = nil
|
var sharedAdminUIConfig *systemconfigs.AdminUIConfig = nil
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UISettingName = "adminUIConfig"
|
AdminUISettingName = "adminUIConfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadUIConfig() (*systemconfigs.AdminUIConfig, error) {
|
func LoadAdminUIConfig() (*systemconfigs.AdminUIConfig, error) {
|
||||||
locker.Lock()
|
locker.Lock()
|
||||||
defer locker.Unlock()
|
defer locker.Unlock()
|
||||||
|
|
||||||
config, err := loadUIConfig()
|
config, err := loadAdminUIConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ func LoadUIConfig() (*systemconfigs.AdminUIConfig, error) {
|
|||||||
return &v, nil
|
return &v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateUIConfig(uiConfig *systemconfigs.AdminUIConfig) error {
|
func UpdateAdminUIConfig(uiConfig *systemconfigs.AdminUIConfig) error {
|
||||||
locker.Lock()
|
locker.Lock()
|
||||||
defer locker.Unlock()
|
defer locker.Unlock()
|
||||||
|
|
||||||
@@ -41,48 +41,48 @@ func UpdateUIConfig(uiConfig *systemconfigs.AdminUIConfig) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = rpcClient.SysSettingRPC().UpdateSysSetting(rpcClient.Context(0), &pb.UpdateSysSettingRequest{
|
_, err = rpcClient.SysSettingRPC().UpdateSysSetting(rpcClient.Context(0), &pb.UpdateSysSettingRequest{
|
||||||
Code: UISettingName,
|
Code: AdminUISettingName,
|
||||||
ValueJSON: valueJSON,
|
ValueJSON: valueJSON,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sharedUIConfig = uiConfig
|
sharedAdminUIConfig = uiConfig
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadUIConfig() (*systemconfigs.AdminUIConfig, error) {
|
func loadAdminUIConfig() (*systemconfigs.AdminUIConfig, error) {
|
||||||
if sharedUIConfig != nil {
|
if sharedAdminUIConfig != nil {
|
||||||
return sharedUIConfig, nil
|
return sharedAdminUIConfig, nil
|
||||||
}
|
}
|
||||||
var rpcClient, err = rpc.SharedRPC()
|
var rpcClient, err = rpc.SharedRPC()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := rpcClient.SysSettingRPC().ReadSysSetting(rpcClient.Context(0), &pb.ReadSysSettingRequest{
|
resp, err := rpcClient.SysSettingRPC().ReadSysSetting(rpcClient.Context(0), &pb.ReadSysSettingRequest{
|
||||||
Code: UISettingName,
|
Code: AdminUISettingName,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(resp.ValueJSON) == 0 {
|
if len(resp.ValueJSON) == 0 {
|
||||||
sharedUIConfig = defaultUIConfig()
|
sharedAdminUIConfig = defaultAdminUIConfig()
|
||||||
return sharedUIConfig, nil
|
return sharedAdminUIConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &systemconfigs.AdminUIConfig{}
|
config := &systemconfigs.AdminUIConfig{}
|
||||||
err = json.Unmarshal(resp.ValueJSON, config)
|
err = json.Unmarshal(resp.ValueJSON, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Println("[UI_MANAGER]" + err.Error())
|
logs.Println("[UI_MANAGER]" + err.Error())
|
||||||
sharedUIConfig = defaultUIConfig()
|
sharedAdminUIConfig = defaultAdminUIConfig()
|
||||||
return sharedUIConfig, nil
|
return sharedAdminUIConfig, nil
|
||||||
}
|
}
|
||||||
sharedUIConfig = config
|
sharedAdminUIConfig = config
|
||||||
return sharedUIConfig, nil
|
return sharedAdminUIConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultUIConfig() *systemconfigs.AdminUIConfig {
|
func defaultAdminUIConfig() *systemconfigs.AdminUIConfig {
|
||||||
return &systemconfigs.AdminUIConfig{
|
return &systemconfigs.AdminUIConfig{
|
||||||
ProductName: "GoEdge",
|
ProductName: "GoEdge",
|
||||||
AdminSystemName: "GoEdge管理员系统",
|
AdminSystemName: "GoEdge管理员系统",
|
||||||
92
internal/configloaders/user_ui_config.go
Normal file
92
internal/configloaders/user_ui_config.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package configloaders
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
||||||
|
"github.com/iwind/TeaGo/logs"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
var sharedUserUIConfig *systemconfigs.UserUIConfig = nil
|
||||||
|
|
||||||
|
const (
|
||||||
|
UserUISettingName = "userUIConfig"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadUserUIConfig() (*systemconfigs.UserUIConfig, error) {
|
||||||
|
locker.Lock()
|
||||||
|
defer locker.Unlock()
|
||||||
|
|
||||||
|
config, err := loadUserUIConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := reflect.Indirect(reflect.ValueOf(config)).Interface().(systemconfigs.UserUIConfig)
|
||||||
|
return &v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateUserUIConfig(uiConfig *systemconfigs.UserUIConfig) error {
|
||||||
|
locker.Lock()
|
||||||
|
defer locker.Unlock()
|
||||||
|
|
||||||
|
var rpcClient, err = rpc.SharedRPC()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
valueJSON, err := json.Marshal(uiConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = rpcClient.SysSettingRPC().UpdateSysSetting(rpcClient.Context(0), &pb.UpdateSysSettingRequest{
|
||||||
|
Code: UserUISettingName,
|
||||||
|
ValueJSON: valueJSON,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sharedUserUIConfig = uiConfig
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadUserUIConfig() (*systemconfigs.UserUIConfig, error) {
|
||||||
|
if sharedUserUIConfig != nil {
|
||||||
|
return sharedUserUIConfig, nil
|
||||||
|
}
|
||||||
|
var rpcClient, err = rpc.SharedRPC()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := rpcClient.SysSettingRPC().ReadSysSetting(rpcClient.Context(0), &pb.ReadSysSettingRequest{
|
||||||
|
Code: UserUISettingName,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(resp.ValueJSON) == 0 {
|
||||||
|
sharedUserUIConfig = defaultUserUIConfig()
|
||||||
|
return sharedUserUIConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
config := &systemconfigs.UserUIConfig{}
|
||||||
|
err = json.Unmarshal(resp.ValueJSON, config)
|
||||||
|
if err != nil {
|
||||||
|
logs.Println("[UI_MANAGER]" + err.Error())
|
||||||
|
sharedUserUIConfig = defaultUserUIConfig()
|
||||||
|
return sharedUserUIConfig, nil
|
||||||
|
}
|
||||||
|
sharedUserUIConfig = config
|
||||||
|
return sharedUserUIConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultUserUIConfig() *systemconfigs.UserUIConfig {
|
||||||
|
return &systemconfigs.UserUIConfig{
|
||||||
|
ProductName: "GoEdge",
|
||||||
|
UserSystemName: "GoEdge用户系统",
|
||||||
|
ShowOpenSourceInfo: true,
|
||||||
|
ShowVersion: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,12 @@ func init() {
|
|||||||
GetPost("/create", new(CreateAction)).
|
GetPost("/create", new(CreateAction)).
|
||||||
Post("/sync", new(SyncAction)).
|
Post("/sync", new(SyncAction)).
|
||||||
Post("/checkChange", new(CheckChangeAction)).
|
Post("/checkChange", new(CheckChangeAction)).
|
||||||
|
|
||||||
|
// 只要登录即可访问的Action
|
||||||
|
EndHelpers().
|
||||||
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeCommon)).
|
||||||
|
Post("/options", new(OptionsAction)).
|
||||||
|
|
||||||
EndAll()
|
EndAll()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
30
internal/web/actions/default/clusters/options.go
Normal file
30
internal/web/actions/default/clusters/options.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package clusters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OptionsAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *OptionsAction) RunPost(params struct{}) {
|
||||||
|
clustersResp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClusters(this.AdminContext(), &pb.FindAllEnabledNodeClustersRequest{})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterMaps := []maps.Map{}
|
||||||
|
for _, cluster := range clustersResp.Clusters {
|
||||||
|
clusterMaps = append(clusterMaps, maps.Map{
|
||||||
|
"id": cluster.Id,
|
||||||
|
"name": cluster.Name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.Data["clusters"] = clusterMaps
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -78,7 +78,7 @@ func (this *PricesAction) formatBits(bits int64) string {
|
|||||||
} else if bits < 1_000_000_000_000_000 {
|
} else if bits < 1_000_000_000_000_000 {
|
||||||
sizeHuman = fmt.Sprintf("%.2fTBPS", float64(bits)/1000/1000/1000/1000)
|
sizeHuman = fmt.Sprintf("%.2fTBPS", float64(bits)/1000/1000/1000/1000)
|
||||||
} else {
|
} else {
|
||||||
sizeHuman = fmt.Sprintf("%.2fPTBPS", float64(bits)/1000/1000/1000/1000/1000)
|
sizeHuman = fmt.Sprintf("%.2fPBPS", float64(bits)/1000/1000/1000/1000/1000)
|
||||||
}
|
}
|
||||||
return sizeHuman
|
return sizeHuman
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,4 @@ func (this *IndexAction) Init() {
|
|||||||
func (this *IndexAction) RunGet(params struct{}) {
|
func (this *IndexAction) RunGet(params struct{}) {
|
||||||
// TODO 暂时先跳转到账单页,将来做成Dashboard
|
// TODO 暂时先跳转到账单页,将来做成Dashboard
|
||||||
this.RedirectURL("/finance/bills")
|
this.RedirectURL("/finance/bills")
|
||||||
|
|
||||||
this.Show()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
this.Data["token"] = stringutil.Md5(TokenSalt+timestamp) + timestamp
|
this.Data["token"] = stringutil.Md5(TokenSalt+timestamp) + timestamp
|
||||||
this.Data["from"] = params.From
|
this.Data["from"] = params.From
|
||||||
|
|
||||||
config, err := configloaders.LoadUIConfig()
|
config, err := configloaders.LoadAdminUIConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ func (this *Helper) BeforeAction(actionPtr actions.ActionWrapper) (goNext bool)
|
|||||||
var adminId = session.GetInt64("adminId")
|
var adminId = session.GetInt64("adminId")
|
||||||
if configloaders.AllowModule(adminId, configloaders.AdminModuleCodeSetting) {
|
if configloaders.AllowModule(adminId, configloaders.AdminModuleCodeSetting) {
|
||||||
tabbar.Add("Web服务", "", "/settings/server", "", this.tab == "server")
|
tabbar.Add("Web服务", "", "/settings/server", "", this.tab == "server")
|
||||||
tabbar.Add("界面设置", "", "/settings/ui", "", this.tab == "ui")
|
tabbar.Add("管理界面设置", "", "/settings/ui", "", this.tab == "ui")
|
||||||
|
tabbar.Add("用户界面设置", "", "/settings/user-ui", "", this.tab == "userUI")
|
||||||
tabbar.Add("安全设置", "", "/settings/security", "", this.tab == "security")
|
tabbar.Add("安全设置", "", "/settings/security", "", this.tab == "security")
|
||||||
tabbar.Add("IP库", "", "/settings/ip-library", "", this.tab == "ipLibrary")
|
tabbar.Add("IP库", "", "/settings/ip-library", "", this.tab == "ipLibrary")
|
||||||
tabbar.Add("备份", "", "/settings/backup", "", this.tab == "backup")
|
tabbar.Add("备份", "", "/settings/backup", "", this.tab == "backup")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package server
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
@@ -15,7 +15,7 @@ func (this *IndexAction) Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *IndexAction) RunGet(params struct{}) {
|
func (this *IndexAction) RunGet(params struct{}) {
|
||||||
config, err := configloaders.LoadUIConfig()
|
config, err := configloaders.LoadAdminUIConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
@@ -41,7 +41,7 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
Field("adminSystemName", params.AdminSystemName).
|
Field("adminSystemName", params.AdminSystemName).
|
||||||
Require("请输入管理员系统名称")
|
Require("请输入管理员系统名称")
|
||||||
|
|
||||||
config, err := configloaders.LoadUIConfig()
|
config, err := configloaders.LoadAdminUIConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
@@ -51,7 +51,7 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
config.ShowOpenSourceInfo = params.ShowOpenSourceInfo
|
config.ShowOpenSourceInfo = params.ShowOpenSourceInfo
|
||||||
config.ShowVersion = params.ShowVersion
|
config.ShowVersion = params.ShowVersion
|
||||||
config.Version = params.Version
|
config.Version = params.Version
|
||||||
err = configloaders.UpdateUIConfig(config)
|
err = configloaders.UpdateAdminUIConfig(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package server
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
|
|||||||
61
internal/web/actions/default/settings/user-ui/index.go
Normal file
61
internal/web/actions/default/settings/user-ui/index.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package userui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) Init() {
|
||||||
|
this.Nav("", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunGet(params struct{}) {
|
||||||
|
config, err := configloaders.LoadUserUIConfig()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.Data["config"] = config
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunPost(params struct {
|
||||||
|
ProductName string
|
||||||
|
UserSystemName string
|
||||||
|
ShowOpenSourceInfo bool
|
||||||
|
ShowVersion bool
|
||||||
|
Version string
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
CSRF *actionutils.CSRF
|
||||||
|
}) {
|
||||||
|
params.Must.
|
||||||
|
Field("productName", params.ProductName).
|
||||||
|
Require("请输入产品名称").
|
||||||
|
Field("userSystemName", params.UserSystemName).
|
||||||
|
Require("请输入管理员系统名称")
|
||||||
|
|
||||||
|
config, err := configloaders.LoadUserUIConfig()
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
config.ProductName = params.ProductName
|
||||||
|
config.UserSystemName = params.UserSystemName
|
||||||
|
config.ShowOpenSourceInfo = params.ShowOpenSourceInfo
|
||||||
|
config.ShowVersion = params.ShowVersion
|
||||||
|
config.Version = params.Version
|
||||||
|
err = configloaders.UpdateUserUIConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
19
internal/web/actions/default/settings/user-ui/init.go
Normal file
19
internal/web/actions/default/settings/user-ui/init.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package userui
|
||||||
|
|
||||||
|
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.AdminModuleCodeCommon)).
|
||||||
|
Helper(settingutils.NewHelper("userUI")).
|
||||||
|
Prefix("/settings/user-ui").
|
||||||
|
GetPost("", new(IndexAction)).
|
||||||
|
EndAll()
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
|||||||
Tel string
|
Tel string
|
||||||
Email string
|
Email string
|
||||||
Remark string
|
Remark string
|
||||||
|
ClusterId int64
|
||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
CSRF *actionutils.CSRF
|
CSRF *actionutils.CSRF
|
||||||
@@ -60,6 +61,10 @@ func (this *CreatePopupAction) RunPost(params struct {
|
|||||||
Field("fullname", params.Fullname).
|
Field("fullname", params.Fullname).
|
||||||
Require("请输入全名")
|
Require("请输入全名")
|
||||||
|
|
||||||
|
if params.ClusterId <= 0 {
|
||||||
|
this.Fail("请选择关联集群")
|
||||||
|
}
|
||||||
|
|
||||||
if len(params.Mobile) > 0 {
|
if len(params.Mobile) > 0 {
|
||||||
params.Must.
|
params.Must.
|
||||||
Field("mobile", params.Mobile).
|
Field("mobile", params.Mobile).
|
||||||
@@ -80,6 +85,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
|||||||
Email: params.Email,
|
Email: params.Email,
|
||||||
Remark: params.Remark,
|
Remark: params.Remark,
|
||||||
Source: "admin:" + numberutils.FormatInt64(this.AdminId()),
|
Source: "admin:" + numberutils.FormatInt64(this.AdminId()),
|
||||||
|
ClusterId: params.ClusterId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
|
|||||||
@@ -34,6 +34,13 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
}
|
}
|
||||||
userMaps := []maps.Map{}
|
userMaps := []maps.Map{}
|
||||||
for _, user := range usersResp.Users {
|
for _, user := range usersResp.Users {
|
||||||
|
var clusterMap maps.Map = nil
|
||||||
|
if user.Cluster != nil {
|
||||||
|
clusterMap = maps.Map{
|
||||||
|
"id": user.Cluster.Id,
|
||||||
|
"name": user.Cluster.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
userMaps = append(userMaps, maps.Map{
|
userMaps = append(userMaps, maps.Map{
|
||||||
"id": user.Id,
|
"id": user.Id,
|
||||||
"username": user.Username,
|
"username": user.Username,
|
||||||
@@ -43,6 +50,7 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
"mobile": user.Mobile,
|
"mobile": user.Mobile,
|
||||||
"tel": user.Tel,
|
"tel": user.Tel,
|
||||||
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", user.CreatedAt),
|
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", user.CreatedAt),
|
||||||
|
"cluster": clusterMap,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.Data["users"] = userMaps
|
this.Data["users"] = userMaps
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ func (this *UpdateAction) RunGet(params struct {
|
|||||||
"isOn": user.IsOn,
|
"isOn": user.IsOn,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.Data["clusterId"] = 0
|
||||||
|
if user.Cluster != nil {
|
||||||
|
this.Data["clusterId"] = user.Cluster.Id
|
||||||
|
}
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +66,7 @@ func (this *UpdateAction) RunPost(params struct {
|
|||||||
Email string
|
Email string
|
||||||
Remark string
|
Remark string
|
||||||
IsOn bool
|
IsOn bool
|
||||||
|
ClusterId int64
|
||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
CSRF *actionutils.CSRF
|
CSRF *actionutils.CSRF
|
||||||
@@ -118,6 +124,7 @@ func (this *UpdateAction) RunPost(params struct {
|
|||||||
Email: params.Email,
|
Email: params.Email,
|
||||||
Remark: params.Remark,
|
Remark: params.Remark,
|
||||||
IsOn: params.IsOn,
|
IsOn: params.IsOn,
|
||||||
|
ClusterId: params.ClusterId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
|
|||||||
@@ -35,6 +35,14 @@ func (this *UserAction) RunGet(params struct {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clusterMap maps.Map = nil
|
||||||
|
if user.Cluster != nil {
|
||||||
|
clusterMap = maps.Map{
|
||||||
|
"id": user.Cluster.Id,
|
||||||
|
"name": user.Cluster.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.Data["user"] = maps.Map{
|
this.Data["user"] = maps.Map{
|
||||||
"id": user.Id,
|
"id": user.Id,
|
||||||
"username": user.Username,
|
"username": user.Username,
|
||||||
@@ -44,6 +52,7 @@ func (this *UserAction) RunGet(params struct {
|
|||||||
"remark": user.Remark,
|
"remark": user.Remark,
|
||||||
"mobile": user.Mobile,
|
"mobile": user.Mobile,
|
||||||
"isOn": user.IsOn,
|
"isOn": user.IsOn,
|
||||||
|
"cluster": clusterMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Show()
|
this.Show()
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ func (this *userMustAuth) BeforeAction(actionPtr actions.ActionWrapper, paramNam
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := configloaders.LoadUIConfig()
|
config, err := configloaders.LoadAdminUIConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
action.WriteString(err.Error())
|
action.WriteString(err.Error())
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ import (
|
|||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/ui"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/ui"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/upgrade"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/upgrade"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/user-nodes"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/user-nodes"
|
||||||
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/user-ui"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/setup"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/setup"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ui"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ui"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/users"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/users"
|
||||||
|
|||||||
28
web/public/js/components/cluster/cluster-selector.js
Normal file
28
web/public/js/components/cluster/cluster-selector.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
Vue.component("cluster-selector", {
|
||||||
|
mounted: function () {
|
||||||
|
let that = this
|
||||||
|
|
||||||
|
Tea.action("/clusters/options")
|
||||||
|
.post()
|
||||||
|
.success(function (resp) {
|
||||||
|
that.clusters = resp.data.clusters
|
||||||
|
})
|
||||||
|
},
|
||||||
|
props: ["v-cluster-id"],
|
||||||
|
data: function () {
|
||||||
|
let clusterId = this.vClusterId
|
||||||
|
if (clusterId == null) {
|
||||||
|
clusterId = 0
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
clusters: [],
|
||||||
|
clusterId: clusterId
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: `<div>
|
||||||
|
<select class="ui dropdown auto-width" name="clusterId" v-model="clusterId">
|
||||||
|
<option value="0">[选择集群]</option>
|
||||||
|
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
|
||||||
|
</select>
|
||||||
|
</div>`
|
||||||
|
})
|
||||||
@@ -213,9 +213,6 @@ body .ui.menu .item .blink {
|
|||||||
body.expanded .main-menu {
|
body.expanded .main-menu {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
body.expanded .sub-menu {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
body.expanded .main {
|
body.expanded .main {
|
||||||
left: 1em;
|
left: 1em;
|
||||||
}
|
}
|
||||||
@@ -226,6 +223,7 @@ body.expanded .main {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
border: 0 !important;
|
||||||
background: #276ac6 !important;
|
background: #276ac6 !important;
|
||||||
}
|
}
|
||||||
.top-nav::-webkit-scrollbar {
|
.top-nav::-webkit-scrollbar {
|
||||||
@@ -362,6 +360,8 @@ body.expanded .main {
|
|||||||
}
|
}
|
||||||
.main-menu .menu {
|
.main-menu .menu {
|
||||||
background: #276ac6 !important;
|
background: #276ac6 !important;
|
||||||
|
border: 0 !important;
|
||||||
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
.main-menu::-webkit-scrollbar {
|
.main-menu::-webkit-scrollbar {
|
||||||
width: 2px;
|
width: 2px;
|
||||||
@@ -401,113 +401,6 @@ body.expanded .main {
|
|||||||
z-index: 999999;
|
z-index: 999999;
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
/** 子菜单 **/
|
|
||||||
.main.without-menu .sub-menu {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.sub-menu {
|
|
||||||
position: fixed;
|
|
||||||
left: 8em;
|
|
||||||
width: 12.5em;
|
|
||||||
top: 3em;
|
|
||||||
bottom: 2.8em;
|
|
||||||
}
|
|
||||||
.sub-menu .menus-box {
|
|
||||||
overflow-y: auto;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
left: 0;
|
|
||||||
padding-right: 0.4em !important;
|
|
||||||
}
|
|
||||||
.sub-menu .menus-box::-webkit-scrollbar {
|
|
||||||
width: 4px;
|
|
||||||
height: 4px;
|
|
||||||
}
|
|
||||||
.sub-menu .menu {
|
|
||||||
max-width: 12em !important;
|
|
||||||
border-right: 0 !important;
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 512px) {
|
|
||||||
.sub-menu {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
.sub-menu .menus-box {
|
|
||||||
position: relative !important;
|
|
||||||
}
|
|
||||||
.sub-menu .menu {
|
|
||||||
width: 100% !important;
|
|
||||||
max-width: 30em !important;
|
|
||||||
}
|
|
||||||
.sub-menu .menus-box .menu .item {
|
|
||||||
width: 100% !important;
|
|
||||||
max-width: 30em !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sub-menu .menu .item.active {
|
|
||||||
font-weight: normal !important;
|
|
||||||
outline: none !important;
|
|
||||||
}
|
|
||||||
.sub-menu .menu .item:not(.header) {
|
|
||||||
padding-top: 0.7em !important;
|
|
||||||
padding-bottom: 0.7em !important;
|
|
||||||
}
|
|
||||||
.sub-menu .menu .item:not(.header) span {
|
|
||||||
font-size: 0.8em;
|
|
||||||
display: block;
|
|
||||||
margin-top: 0.6em !important;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
.sub-menu .menu .item:not(.active):hover {
|
|
||||||
background: rgba(0, 0, 0, 0.05) !important;
|
|
||||||
border-top: 1px white solid !important;
|
|
||||||
border-bottom: 1px white solid !important;
|
|
||||||
margin-top: -1px !important;
|
|
||||||
margin-bottom: -1px !important;
|
|
||||||
}
|
|
||||||
.sub-menu .menu .item.active {
|
|
||||||
background: rgba(0, 0, 0, 0.05) !important;
|
|
||||||
}
|
|
||||||
.sub-menu .menu .item var {
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
.sub-menu .menu .item:not(.active) var.grey {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
.sub-menu .menu .item span:not(.green) {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
.sub-menu .menu .item span.red {
|
|
||||||
color: #db2828 !important;
|
|
||||||
}
|
|
||||||
.sub-menu .menus-box .menu .item.header {
|
|
||||||
padding-right: 0.2em !important;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.sub-menu .menus-box .menu .item.header span {
|
|
||||||
font-weight: normal;
|
|
||||||
color: grey;
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
.sub-menu .menus-box .menu a {
|
|
||||||
display: block;
|
|
||||||
word-break: break-all;
|
|
||||||
line-height: 1.6 !important;
|
|
||||||
}
|
|
||||||
.sub-menu .menus-box .menu .item .menu {
|
|
||||||
margin-top: 0 !important;
|
|
||||||
}
|
|
||||||
.sub-menu .fourth-menu {
|
|
||||||
margin-left: 1.2em;
|
|
||||||
}
|
|
||||||
.sub-menu .fourth-menu .icon,
|
|
||||||
.sub-menu .third-menu .icon {
|
|
||||||
float: left !important;
|
|
||||||
}
|
|
||||||
/** 右侧文本子菜单 **/
|
/** 右侧文本子菜单 **/
|
||||||
.text.menu {
|
.text.menu {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -171,10 +171,6 @@ body.expanded .main-menu {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.expanded .sub-menu {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.expanded .main {
|
body.expanded .main {
|
||||||
left: 1em;
|
left: 1em;
|
||||||
}
|
}
|
||||||
@@ -186,6 +182,7 @@ body.expanded .main {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
border: 0 !important;
|
||||||
background: #276ac6 !important;
|
background: #276ac6 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,10 +346,12 @@ body.expanded .main {
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
background: #276ac6 !important;
|
background: #276ac6 !important;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
|
||||||
|
|
||||||
.main-menu .menu {
|
.menu {
|
||||||
background: #276ac6 !important;
|
background: #276ac6 !important;
|
||||||
|
border: 0 !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-menu::-webkit-scrollbar {
|
.main-menu::-webkit-scrollbar {
|
||||||
@@ -405,136 +404,6 @@ body.expanded .main {
|
|||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 子菜单 **/
|
|
||||||
.main.without-menu .sub-menu {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu {
|
|
||||||
position: fixed;
|
|
||||||
left: 8em;
|
|
||||||
width: 12.5em;
|
|
||||||
top: 3em;
|
|
||||||
bottom: 2.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menus-box {
|
|
||||||
overflow-y: auto;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
left: 0;
|
|
||||||
padding-right: 0.4em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menus-box::-webkit-scrollbar {
|
|
||||||
width: 4px;
|
|
||||||
height: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu {
|
|
||||||
max-width: 12em !important;
|
|
||||||
border-right: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 512px) {
|
|
||||||
.sub-menu {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menus-box {
|
|
||||||
position: relative !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu {
|
|
||||||
width: 100% !important;
|
|
||||||
max-width: 30em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menus-box .menu .item {
|
|
||||||
width: 100% !important;
|
|
||||||
max-width: 30em !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu .item.active {
|
|
||||||
font-weight: normal !important;
|
|
||||||
outline: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu .item:not(.header) {
|
|
||||||
padding-top: 0.7em !important;
|
|
||||||
padding-bottom: 0.7em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu .item:not(.header) span {
|
|
||||||
font-size: 0.8em;
|
|
||||||
display: block;
|
|
||||||
margin-top: 0.6em !important;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu .item:not(.active):hover {
|
|
||||||
background: rgba(0, 0, 0, 0.05) !important;
|
|
||||||
border-top: 1px white solid !important;
|
|
||||||
border-bottom: 1px white solid !important;
|
|
||||||
margin-top: -1px !important;
|
|
||||||
margin-bottom: -1px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu .item.active {
|
|
||||||
background: rgba(0, 0, 0, 0.05) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu .item var {
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu .item:not(.active) var.grey {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu .item span:not(.green) {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menu .item span.red {
|
|
||||||
color: #db2828 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menus-box .menu .item.header {
|
|
||||||
padding-right: 0.2em !important;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menus-box .menu .item.header span {
|
|
||||||
font-weight: normal;
|
|
||||||
color: grey;
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menus-box .menu a {
|
|
||||||
display: block;
|
|
||||||
word-break: break-all;
|
|
||||||
line-height: 1.6 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .menus-box .menu .item .menu {
|
|
||||||
margin-top: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .fourth-menu {
|
|
||||||
margin-left: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-menu .fourth-menu .icon, .sub-menu .third-menu .icon {
|
|
||||||
float: left !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 右侧文本子菜单 **/
|
/** 右侧文本子菜单 **/
|
||||||
.text.menu {
|
.text.menu {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|||||||
41
web/views/@default/settings/user-ui/index.html
Normal file
41
web/views/@default/settings/user-ui/index.html
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{$layout}
|
||||||
|
|
||||||
|
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
|
||||||
|
<csrf-token></csrf-token>
|
||||||
|
|
||||||
|
<table class="ui table definition selectable">
|
||||||
|
<tr>
|
||||||
|
<td class="title">产品名称 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="productName" v-model="config.productName" maxlength="100"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>用户系统名称 *</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="userSystemName" v-model="config.userSystemName" maxlength="100"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>是否显示底部开源信息</td>
|
||||||
|
<td>
|
||||||
|
<checkbox name="showOpenSourceInfo" v-model="config.showOpenSourceInfo"></checkbox>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>是否显示版本号</td>
|
||||||
|
<td>
|
||||||
|
<checkbox name="showVersion" v-model="config.showVersion"></checkbox>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-show="config.showVersion">
|
||||||
|
<td>定制版本号</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="version" v-model="config.version" maxlength="100"/>
|
||||||
|
<p class="comment">定制自己的版本号,留空表示使用系统自带的版本号。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<submit-btn></submit-btn>
|
||||||
|
</form>
|
||||||
3
web/views/@default/settings/user-ui/index.js
Normal file
3
web/views/@default/settings/user-ui/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.success = NotifyReloadSuccess("保存成功")
|
||||||
|
})
|
||||||
@@ -31,6 +31,13 @@
|
|||||||
<p class="comment">用户姓名或者公司名称等等。</p>
|
<p class="comment">用户姓名或者公司名称等等。</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>关联集群 *</td>
|
||||||
|
<td>
|
||||||
|
<cluster-selector></cluster-selector>
|
||||||
|
<p class="comment">用户发布的网站服务会自动部署到此集群。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>用户名</th>
|
<th>用户名</th>
|
||||||
<th>全名</th>
|
<th>全名</th>
|
||||||
|
<th>关联集群</th>
|
||||||
<th>手机号</th>
|
<th>手机号</th>
|
||||||
<th>注册时间</th>
|
<th>注册时间</th>
|
||||||
<th class="center width10">状态</th>
|
<th class="center width10">状态</th>
|
||||||
@@ -19,6 +20,10 @@
|
|||||||
<tr v-for="user in users">
|
<tr v-for="user in users">
|
||||||
<td :class="{disabled:!user.isOn}">{{user.username}}</td>
|
<td :class="{disabled:!user.isOn}">{{user.username}}</td>
|
||||||
<td :class="{disabled:!user.isOn}">{{user.fullname}}</td>
|
<td :class="{disabled:!user.isOn}">{{user.fullname}}</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="user.cluster != null">{{user.cluster.name}} <link-icon :href="'/clusters/cluster?clusterId=' + user.cluster.id"></link-icon></span>
|
||||||
|
<span v-else class="disabled">-</span>
|
||||||
|
</td>
|
||||||
<td :class="{disabled:!user.isOn}">
|
<td :class="{disabled:!user.isOn}">
|
||||||
<span v-if="user.mobile.length > 0">{{user.mobile}}</span>
|
<span v-if="user.mobile.length > 0">{{user.mobile}}</span>
|
||||||
<span v-else class="disabled">-</span>
|
<span v-else class="disabled">-</span>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
Tea.context(function () {
|
Tea.context(function () {
|
||||||
this.createUser = function () {
|
this.createUser = function () {
|
||||||
teaweb.popup(Tea.url(".createPopup"), {
|
teaweb.popup(Tea.url(".createPopup"), {
|
||||||
|
height: "30em",
|
||||||
callback: function () {
|
callback: function () {
|
||||||
teaweb.success("保存成功", function () {
|
teaweb.success("保存成功", function () {
|
||||||
teaweb.reload()
|
teaweb.reload()
|
||||||
|
|||||||
@@ -38,6 +38,13 @@
|
|||||||
<p class="comment">用户姓名或者公司名称等等。</p>
|
<p class="comment">用户姓名或者公司名称等等。</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>关联集群 *</td>
|
||||||
|
<td>
|
||||||
|
<cluster-selector :v-cluster-id="clusterId"></cluster-selector>
|
||||||
|
<p class="comment">用户发布的网站服务会自动部署到此集群。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -20,6 +20,13 @@
|
|||||||
{{user.fullname}}
|
{{user.fullname}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>关联集群</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="user.cluster != null">{{user.cluster.name}} <link-icon :href="'/clusters/cluster?clusterId=' + user.cluster.id"></link-icon></span>
|
||||||
|
<span v-else class="disabled">-</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>手机号</td>
|
<td>手机号</td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
Reference in New Issue
Block a user