mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	[用户]实现对平台用户的增删改查
This commit is contained in:
		@@ -13,7 +13,8 @@ const (
 | 
				
			|||||||
	AdminModuleCodeServer  AdminModuleCode = "server"
 | 
						AdminModuleCodeServer  AdminModuleCode = "server"
 | 
				
			||||||
	AdminModuleCodeNode    AdminModuleCode = "node"
 | 
						AdminModuleCodeNode    AdminModuleCode = "node"
 | 
				
			||||||
	AdminModuleCodeDNS     AdminModuleCode = "dns"
 | 
						AdminModuleCodeDNS     AdminModuleCode = "dns"
 | 
				
			||||||
	AdminModuleCodeAdmin   AdminModuleCode = "admin"
 | 
						AdminModuleCodeAdmin   AdminModuleCode = "admin" // 系统用户
 | 
				
			||||||
 | 
						AdminModuleCodeUser    AdminModuleCode = "user"  // 平台用户
 | 
				
			||||||
	AdminModuleCodeLog     AdminModuleCode = "log"
 | 
						AdminModuleCodeLog     AdminModuleCode = "log"
 | 
				
			||||||
	AdminModuleCodeSetting AdminModuleCode = "setting"
 | 
						AdminModuleCodeSetting AdminModuleCode = "setting"
 | 
				
			||||||
	AdminModuleCodeCommon  AdminModuleCode = "common" // 只要登录就可以访问的模块
 | 
						AdminModuleCodeCommon  AdminModuleCode = "common" // 只要登录就可以访问的模块
 | 
				
			||||||
@@ -118,6 +119,11 @@ func AllModuleMaps() []maps.Map {
 | 
				
			|||||||
			"code": AdminModuleCodeDNS,
 | 
								"code": AdminModuleCodeDNS,
 | 
				
			||||||
			"url":  "/dns",
 | 
								"url":  "/dns",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"name": "平台用户",
 | 
				
			||||||
 | 
								"code": AdminModuleCodeUser,
 | 
				
			||||||
 | 
								"url":  "/users",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"name": "系统用户",
 | 
								"name": "系统用户",
 | 
				
			||||||
			"code": AdminModuleCodeAdmin,
 | 
								"code": AdminModuleCodeAdmin,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -224,6 +224,10 @@ func (this *RPCClient) ACMETaskRPC() pb.ACMETaskServiceClient {
 | 
				
			|||||||
	return pb.NewACMETaskServiceClient(this.pickConn())
 | 
						return pb.NewACMETaskServiceClient(this.pickConn())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *RPCClient) UserRPC() pb.UserServiceClient {
 | 
				
			||||||
 | 
						return pb.NewUserServiceClient(this.pickConn())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 构造Admin上下文
 | 
					// 构造Admin上下文
 | 
				
			||||||
func (this *RPCClient) Context(adminId int64) context.Context {
 | 
					func (this *RPCClient) Context(adminId int64) context.Context {
 | 
				
			||||||
	ctx := context.Background()
 | 
						ctx := context.Background()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -113,7 +113,7 @@ func (this *RequestCertPopupAction) RunPost(params struct {
 | 
				
			|||||||
			this.ErrorPage(err)
 | 
								this.ErrorPage(err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		defer this.CreateLogInfo("创建ACME用户", createUserResp.AcmeUserId)
 | 
							defer this.CreateLogInfo("创建ACME用户 %d", createUserResp.AcmeUserId)
 | 
				
			||||||
		acmeUserId = createUserResp.AcmeUserId
 | 
							acmeUserId = createUserResp.AcmeUserId
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.Data["acmeUser"] = maps.Map{
 | 
							this.Data["acmeUser"] = maps.Map{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										91
									
								
								internal/web/actions/default/users/createPopup.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								internal/web/actions/default/users/createPopup.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					package users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CreatePopupAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreatePopupAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreatePopupAction) RunGet(params struct{}) {
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *CreatePopupAction) RunPost(params struct {
 | 
				
			||||||
 | 
						Username string
 | 
				
			||||||
 | 
						Pass1    string
 | 
				
			||||||
 | 
						Pass2    string
 | 
				
			||||||
 | 
						Fullname string
 | 
				
			||||||
 | 
						Mobile   string
 | 
				
			||||||
 | 
						Tel      string
 | 
				
			||||||
 | 
						Email    string
 | 
				
			||||||
 | 
						Remark   string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Must *actions.Must
 | 
				
			||||||
 | 
						CSRF *actionutils.CSRF
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						params.Must.
 | 
				
			||||||
 | 
							Field("username", params.Username).
 | 
				
			||||||
 | 
							Require("请输入用户名").
 | 
				
			||||||
 | 
							Match(`^[a-zA-Z0-9_]+$`, "用户名中只能含有英文、数字和下划线")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						checkUsernameResp, err := this.RPC().UserRPC().CheckUsername(this.AdminContext(), &pb.CheckUsernameRequest{
 | 
				
			||||||
 | 
							UserId:   0,
 | 
				
			||||||
 | 
							Username: params.Username,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if checkUsernameResp.Exists {
 | 
				
			||||||
 | 
							this.FailField("username", "此用户名已经被占用,请换一个")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params.Must.
 | 
				
			||||||
 | 
							Field("pass1", params.Pass1).
 | 
				
			||||||
 | 
							Require("请输入密码").
 | 
				
			||||||
 | 
							Field("pass2", params.Pass2).
 | 
				
			||||||
 | 
							Require("请再次输入确认密码").
 | 
				
			||||||
 | 
							Equal(params.Pass1, "两次输入的密码不一致")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params.Must.
 | 
				
			||||||
 | 
							Field("fullname", params.Fullname).
 | 
				
			||||||
 | 
							Require("请输入全名")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(params.Mobile) > 0 {
 | 
				
			||||||
 | 
							params.Must.
 | 
				
			||||||
 | 
								Field("mobile", params.Mobile).
 | 
				
			||||||
 | 
								Mobile("请输入正确的手机号")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(params.Email) > 0 {
 | 
				
			||||||
 | 
							params.Must.
 | 
				
			||||||
 | 
								Field("email", params.Email).
 | 
				
			||||||
 | 
								Email("请输入正确的电子邮箱")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						createResp, err := this.RPC().UserRPC().CreateUser(this.AdminContext(), &pb.CreateUserRequest{
 | 
				
			||||||
 | 
							Username: params.Username,
 | 
				
			||||||
 | 
							Password: params.Pass1,
 | 
				
			||||||
 | 
							Fullname: params.Fullname,
 | 
				
			||||||
 | 
							Mobile:   params.Mobile,
 | 
				
			||||||
 | 
							Tel:      params.Tel,
 | 
				
			||||||
 | 
							Email:    params.Email,
 | 
				
			||||||
 | 
							Remark:   params.Remark,
 | 
				
			||||||
 | 
							Source:   "admin:" + numberutils.FormatInt64(this.AdminId()),
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer this.CreateLogInfo("创建用户 %d", createResp.UserId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								internal/web/actions/default/users/delete.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								internal/web/actions/default/users/delete.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					package users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DeleteAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *DeleteAction) RunPost(params struct {
 | 
				
			||||||
 | 
						UserId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						defer this.CreateLogInfo("删除用户 %d", params.UserId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO 检查用户是否有未完成的业务
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := this.RPC().UserRPC().DeleteUser(this.AdminContext(), &pb.DeleteUserRequest{UserId: params.UserId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										51
									
								
								internal/web/actions/default/users/index.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								internal/web/actions/default/users/index.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					package users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"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 {
 | 
				
			||||||
 | 
						Keyword string
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						countResp, err := this.RPC().UserRPC().CountAllEnabledUsers(this.AdminContext(), &pb.CountAllEnabledUsersRequest{Keyword: params.Keyword})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						count := countResp.Count
 | 
				
			||||||
 | 
						page := this.NewPage(count)
 | 
				
			||||||
 | 
						this.Data["page"] = page.AsHTML()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						usersResp, err := this.RPC().UserRPC().ListEnabledUsers(this.AdminContext(), &pb.ListEnabledUsersRequest{Keyword: params.Keyword})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						userMaps := []maps.Map{}
 | 
				
			||||||
 | 
						for _, user := range usersResp.Users {
 | 
				
			||||||
 | 
							userMaps = append(userMaps, maps.Map{
 | 
				
			||||||
 | 
								"id":          user.Id,
 | 
				
			||||||
 | 
								"username":    user.Username,
 | 
				
			||||||
 | 
								"isOn":        user.IsOn,
 | 
				
			||||||
 | 
								"fullname":    user.Fullname,
 | 
				
			||||||
 | 
								"email":       user.Email,
 | 
				
			||||||
 | 
								"mobile":      user.Mobile,
 | 
				
			||||||
 | 
								"tel":         user.Tel,
 | 
				
			||||||
 | 
								"createdTime": timeutil.FormatTime("Y-m-d H:i:s", user.CreatedAt),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Data["users"] = userMaps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										22
									
								
								internal/web/actions/default/users/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								internal/web/actions/default/users/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					package users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
				
			||||||
 | 
							server.
 | 
				
			||||||
 | 
								Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeUser)).
 | 
				
			||||||
 | 
								Data("teaMenu", "users").
 | 
				
			||||||
 | 
								Prefix("/users").
 | 
				
			||||||
 | 
								Get("", new(IndexAction)).
 | 
				
			||||||
 | 
								GetPost("/createPopup", new(CreatePopupAction)).
 | 
				
			||||||
 | 
								Get("/user", new(UserAction)).
 | 
				
			||||||
 | 
								GetPost("/update", new(UpdateAction)).
 | 
				
			||||||
 | 
								Post("/delete", new(DeleteAction)).
 | 
				
			||||||
 | 
								EndAll()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										128
									
								
								internal/web/actions/default/users/update.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								internal/web/actions/default/users/update.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
				
			|||||||
 | 
					package users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/users/userutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UpdateAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdateAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "update")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdateAction) RunGet(params struct {
 | 
				
			||||||
 | 
						UserId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						err := userutils.InitUser(this.Parent(), params.UserId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						userResp, err := this.RPC().UserRPC().FindEnabledUser(this.AdminContext(), &pb.FindEnabledUserRequest{UserId: params.UserId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						user := userResp.User
 | 
				
			||||||
 | 
						if user == nil {
 | 
				
			||||||
 | 
							this.NotFound("user", params.UserId)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Data["user"] = maps.Map{
 | 
				
			||||||
 | 
							"id":       user.Id,
 | 
				
			||||||
 | 
							"username": user.Username,
 | 
				
			||||||
 | 
							"fullname": user.Fullname,
 | 
				
			||||||
 | 
							"email":    user.Email,
 | 
				
			||||||
 | 
							"tel":      user.Tel,
 | 
				
			||||||
 | 
							"remark":   user.Remark,
 | 
				
			||||||
 | 
							"mobile":   user.Mobile,
 | 
				
			||||||
 | 
							"isOn":     user.IsOn,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UpdateAction) RunPost(params struct {
 | 
				
			||||||
 | 
						UserId   int64
 | 
				
			||||||
 | 
						Username string
 | 
				
			||||||
 | 
						Pass1    string
 | 
				
			||||||
 | 
						Pass2    string
 | 
				
			||||||
 | 
						Fullname string
 | 
				
			||||||
 | 
						Mobile   string
 | 
				
			||||||
 | 
						Tel      string
 | 
				
			||||||
 | 
						Email    string
 | 
				
			||||||
 | 
						Remark   string
 | 
				
			||||||
 | 
						IsOn     bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Must *actions.Must
 | 
				
			||||||
 | 
						CSRF *actionutils.CSRF
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						defer this.CreateLogInfo("修改用户 %d", params.UserId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params.Must.
 | 
				
			||||||
 | 
							Field("username", params.Username).
 | 
				
			||||||
 | 
							Require("请输入用户名").
 | 
				
			||||||
 | 
							Match(`^[a-zA-Z0-9_]+$`, "用户名中只能含有英文、数字和下划线")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						checkUsernameResp, err := this.RPC().UserRPC().CheckUsername(this.AdminContext(), &pb.CheckUsernameRequest{
 | 
				
			||||||
 | 
							UserId:   params.UserId,
 | 
				
			||||||
 | 
							Username: params.Username,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if checkUsernameResp.Exists {
 | 
				
			||||||
 | 
							this.FailField("username", "此用户名已经被占用,请换一个")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(params.Pass1) > 0 {
 | 
				
			||||||
 | 
							params.Must.
 | 
				
			||||||
 | 
								Field("pass1", params.Pass1).
 | 
				
			||||||
 | 
								Require("请输入密码").
 | 
				
			||||||
 | 
								Field("pass2", params.Pass2).
 | 
				
			||||||
 | 
								Require("请再次输入确认密码").
 | 
				
			||||||
 | 
								Equal(params.Pass1, "两次输入的密码不一致")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						params.Must.
 | 
				
			||||||
 | 
							Field("fullname", params.Fullname).
 | 
				
			||||||
 | 
							Require("请输入全名")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(params.Mobile) > 0 {
 | 
				
			||||||
 | 
							params.Must.
 | 
				
			||||||
 | 
								Field("mobile", params.Mobile).
 | 
				
			||||||
 | 
								Mobile("请输入正确的手机号")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(params.Email) > 0 {
 | 
				
			||||||
 | 
							params.Must.
 | 
				
			||||||
 | 
								Field("email", params.Email).
 | 
				
			||||||
 | 
								Email("请输入正确的电子邮箱")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = this.RPC().UserRPC().UpdateUser(this.AdminContext(), &pb.UpdateUserRequest{
 | 
				
			||||||
 | 
							UserId:   params.UserId,
 | 
				
			||||||
 | 
							Username: params.Username,
 | 
				
			||||||
 | 
							Password: params.Pass1,
 | 
				
			||||||
 | 
							Fullname: params.Fullname,
 | 
				
			||||||
 | 
							Mobile:   params.Mobile,
 | 
				
			||||||
 | 
							Tel:      params.Tel,
 | 
				
			||||||
 | 
							Email:    params.Email,
 | 
				
			||||||
 | 
							Remark:   params.Remark,
 | 
				
			||||||
 | 
							IsOn:     params.IsOn,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										50
									
								
								internal/web/actions/default/users/user.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								internal/web/actions/default/users/user.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					package users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/users/userutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UserAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UserAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "index")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *UserAction) RunGet(params struct {
 | 
				
			||||||
 | 
						UserId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						err := userutils.InitUser(this.Parent(), params.UserId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						userResp, err := this.RPC().UserRPC().FindEnabledUser(this.AdminContext(), &pb.FindEnabledUserRequest{UserId: params.UserId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						user := userResp.User
 | 
				
			||||||
 | 
						if user == nil {
 | 
				
			||||||
 | 
							this.NotFound("user", params.UserId)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Data["user"] = maps.Map{
 | 
				
			||||||
 | 
							"id":       user.Id,
 | 
				
			||||||
 | 
							"username": user.Username,
 | 
				
			||||||
 | 
							"fullname": user.Fullname,
 | 
				
			||||||
 | 
							"email":    user.Email,
 | 
				
			||||||
 | 
							"tel":      user.Tel,
 | 
				
			||||||
 | 
							"remark":   user.Remark,
 | 
				
			||||||
 | 
							"mobile":   user.Mobile,
 | 
				
			||||||
 | 
							"isOn":     user.IsOn,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								internal/web/actions/default/users/userutils/utils.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								internal/web/actions/default/users/userutils/utils.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					package userutils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 查找用户基本信息
 | 
				
			||||||
 | 
					func InitUser(p *actionutils.ParentAction, userId int64) error {
 | 
				
			||||||
 | 
						resp, err := p.RPC().UserRPC().FindEnabledUser(p.AdminContext(), &pb.FindEnabledUserRequest{UserId: userId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if resp.User == nil {
 | 
				
			||||||
 | 
							return errors.New("not found user")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						p.Data["user"] = maps.Map{
 | 
				
			||||||
 | 
							"id":       userId,
 | 
				
			||||||
 | 
							"fullname": resp.User.Fullname,
 | 
				
			||||||
 | 
							"username": resp.User.Username,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -215,11 +215,17 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
 | 
				
			|||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"code":   "users",
 | 
				
			||||||
 | 
								"module": configloaders.AdminModuleCodeUser,
 | 
				
			||||||
 | 
								"name":   "平台用户",
 | 
				
			||||||
 | 
								"icon":   "users",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"code":   "admins",
 | 
								"code":   "admins",
 | 
				
			||||||
			"module": configloaders.AdminModuleCodeAdmin,
 | 
								"module": configloaders.AdminModuleCodeAdmin,
 | 
				
			||||||
			"name":   "系统用户",
 | 
								"name":   "系统用户",
 | 
				
			||||||
			"icon":   "users",
 | 
								"icon":   "user secret",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"code":   "log",
 | 
								"code":   "log",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,4 +83,5 @@ import (
 | 
				
			|||||||
	_ "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/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"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								web/views/@default/users/@user_menu.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								web/views/@default/users/@user_menu.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					<first-menu>
 | 
				
			||||||
 | 
					    <menu-item href="/users">用户列表</menu-item>
 | 
				
			||||||
 | 
					    <span class="item">|</span>
 | 
				
			||||||
 | 
					    <menu-item :href="'/users/user?userId=' + user.id" code="index">{{user.fullname}}  <span class="small">({{user.username}})</span></menu-item>
 | 
				
			||||||
 | 
					    <menu-item :href="'/users/update?userId=' + user.id" code="update">修改</menu-item>
 | 
				
			||||||
 | 
					</first-menu>
 | 
				
			||||||
							
								
								
									
										65
									
								
								web/views/@default/users/createPopup.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								web/views/@default/users/createPopup.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					{$layout "layout_popup"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<h3>创建用户</h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<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="username" maxlength="100" ref="focus"/>
 | 
				
			||||||
 | 
					                <p class="comment">用户名只能是英文、数字、下划线的组合。</p>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>密码 *</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="password" name="pass1" maxlength="100"/>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>确认密码 *</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="password" name="pass2" maxlength="100"/>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>全名 *</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="text" name="fullname" maxlength="100"/>
 | 
				
			||||||
 | 
					                <p class="comment">用户姓名或者公司名称等等。</p>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tbody v-show="moreOptionsVisible">
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>手机号</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="mobile" maxlength="11"/>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>联系电话</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="tel" maxlength="100"/>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>电子邮箱</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="email" maxlength="100"/>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>备注</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <textarea rows="3" name="remark"></textarea>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
						</table>
 | 
				
			||||||
 | 
						<submit-btn></submit-btn>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
							
								
								
									
										37
									
								
								web/views/@default/users/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								web/views/@default/users/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<first-menu>
 | 
				
			||||||
 | 
						<menu-item @click.prevent="createUser">创建</menu-item>
 | 
				
			||||||
 | 
					</first-menu>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p class="comment" v-if="users.length == 0">暂时还没有用户。</p>
 | 
				
			||||||
 | 
					<table class="ui table selectable" v-if="users.length > 0">
 | 
				
			||||||
 | 
						<thead>
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<th>用户名</th>
 | 
				
			||||||
 | 
								<th>全名</th>
 | 
				
			||||||
 | 
								<th>手机号</th>
 | 
				
			||||||
 | 
								<th>注册时间</th>
 | 
				
			||||||
 | 
								<th class="center width10">状态</th>
 | 
				
			||||||
 | 
								<th class="two op">操作</th>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
						</thead>
 | 
				
			||||||
 | 
						<tr v-for="user in users">
 | 
				
			||||||
 | 
					        <td :class="{disabled:!user.isOn}">{{user.username}}</td>
 | 
				
			||||||
 | 
					        <td :class="{disabled:!user.isOn}">{{user.fullname}}</td>
 | 
				
			||||||
 | 
					        <td :class="{disabled:!user.isOn}">
 | 
				
			||||||
 | 
					            <span v-if="user.mobile.length > 0">{{user.mobile}}</span>
 | 
				
			||||||
 | 
					            <span v-else class="disabled">-</span>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					        <td :class="{disabled:!user.isOn}">{{user.createdTime}}</td>
 | 
				
			||||||
 | 
					        <td class="center">
 | 
				
			||||||
 | 
					            <label-on :v-is-on="user.isOn"></label-on>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <a :href="'/users/user?userId=' + user.id">详情</a>  
 | 
				
			||||||
 | 
					            <a href="" @click.prevent="deleteUser(user.id)">删除</a>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
						</tr>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="page" v-html="page"></div>
 | 
				
			||||||
							
								
								
									
										22
									
								
								web/views/@default/users/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								web/views/@default/users/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.createUser = function () {
 | 
				
			||||||
 | 
							teaweb.popup(Tea.url(".createPopup"), {
 | 
				
			||||||
 | 
								callback: function () {
 | 
				
			||||||
 | 
									teaweb.success("保存成功", function () {
 | 
				
			||||||
 | 
										teaweb.reload()
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.deleteUser = function (userId) {
 | 
				
			||||||
 | 
							let that = this
 | 
				
			||||||
 | 
							teaweb.confirm("确定要删除这个用户吗?", function () {
 | 
				
			||||||
 | 
								that.$post(".delete")
 | 
				
			||||||
 | 
									.params({
 | 
				
			||||||
 | 
										userId: userId
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
									.refresh()
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										78
									
								
								web/views/@default/users/update.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								web/views/@default/users/update.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					{$template "user_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
 | 
				
			||||||
 | 
						<csrf-token></csrf-token>
 | 
				
			||||||
 | 
					    <input type="hidden" name="userId" :value="user.id"/>
 | 
				
			||||||
 | 
						<table class="ui table definition selectable">
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td class="title">用户名 *</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="text" name="username" maxlength="100" ref="focus" v-model="user.username"/>
 | 
				
			||||||
 | 
					                <p class="comment">用户名只能是英文、数字、下划线的组合。</p>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>密码</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <div>
 | 
				
			||||||
 | 
					                    <a href="" @click.prevent="changePasswordEditing">修改密码<i class="icon angle" :class="{down:!passwordEditing, up:passwordEditing}"></i></a>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <div v-show="passwordEditing" style="margin-top: 0.6em">
 | 
				
			||||||
 | 
					                    <input type="password" name="pass1" maxlength="100"/>
 | 
				
			||||||
 | 
					                    <p class="comment">留空表示不修改。</p>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr v-show="passwordEditing">
 | 
				
			||||||
 | 
					            <td>确认密码</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="password" name="pass2" maxlength="100"/>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td>全名 *</td>
 | 
				
			||||||
 | 
					            <td>
 | 
				
			||||||
 | 
					                <input type="text" name="fullname" maxlength="100" v-model="user.fullname"/>
 | 
				
			||||||
 | 
					                <p class="comment">用户姓名或者公司名称等等。</p>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					            <td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					        <tbody v-show="moreOptionsVisible">
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>手机号</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="mobile" maxlength="11" v-model="user.mobile"/>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>联系电话</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="tel" maxlength="100" v-model="user.tel"/>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>电子邮箱</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="email" maxlength="100" v-model="user.email"/>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>备注</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <textarea rows="3" name="remark" v-model="user.remark"></textarea>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td>是否启用</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <checkbox name="isOn" v-model="user.isOn"></checkbox>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
						</table>
 | 
				
			||||||
 | 
						<submit-btn></submit-btn>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
							
								
								
									
										9
									
								
								web/views/@default/users/update.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								web/views/@default/users/update.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.success = NotifySuccess("保存成功", "/users/user?userId=" + this.user.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.passwordEditing = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.changePasswordEditing = function () {
 | 
				
			||||||
 | 
							this.passwordEditing = !this.passwordEditing
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										51
									
								
								web/views/@default/users/user.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								web/views/@default/users/user.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					{$template "user_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<table class="ui table definition selectable">
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>状态</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <label-on :v-is-on="user.isOn"></label-on>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td class="title">用户名</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            {{user.username}}
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>全名</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            {{user.fullname}}
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>手机号</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <span v-if="user.mobile.length > 0">{{user.mobile}}</span>
 | 
				
			||||||
 | 
					            <span v-else class="disabled">-</span>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>联系电话</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <span v-if="user.tel.length > 0">{{user.tel}}</span>
 | 
				
			||||||
 | 
					            <span v-else class="disabled">-</span>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>电子邮箱</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <span v-if="user.email.length > 0">{{user.email}}</span>
 | 
				
			||||||
 | 
					            <span v-else class="disabled">-</span>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					        <td>备注</td>
 | 
				
			||||||
 | 
					        <td>
 | 
				
			||||||
 | 
					            <span v-if="user.remark.length > 0">{{user.remark}}</span>
 | 
				
			||||||
 | 
					            <span v-else class="disabled">-</span>
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user