增加邮件服务功能
This commit is contained in:
1
go.mod
1
go.mod
@ -6,6 +6,7 @@ require (
|
||||
github.com/antonfisher/nested-logrus-formatter v1.3.0
|
||||
github.com/gofrs/uuid v3.3.0+incompatible
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
||||
github.com/labstack/echo/v4 v4.1.17
|
||||
github.com/labstack/gommon v0.3.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
|
12
go.sum
12
go.sum
@ -107,6 +107,8 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr
|
||||
github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E=
|
||||
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
@ -151,9 +153,7 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
@ -182,16 +182,12 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E=
|
||||
github.com/robfig/cron/v3 v3.0.0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
@ -215,7 +211,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
@ -300,7 +295,6 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -308,7 +302,6 @@ golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6 h1:DvY3Zkh7KabQE/kfzMvYvKirS
|
||||
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@ -354,7 +347,6 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@ -14,10 +14,11 @@ func UserCreateEndpoint(c echo.Context) error {
|
||||
if err := c.Bind(&item); err != nil {
|
||||
return err
|
||||
}
|
||||
password := item.Password
|
||||
|
||||
var pass []byte
|
||||
var err error
|
||||
if pass, err = utils.Encoder.Encode([]byte(item.Password)); err != nil {
|
||||
if pass, err = utils.Encoder.Encode([]byte(password)); err != nil {
|
||||
return err
|
||||
}
|
||||
item.Password = string(pass)
|
||||
@ -28,6 +29,10 @@ func UserCreateEndpoint(c echo.Context) error {
|
||||
if err := model.CreateNewUser(&item); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if item.Mail != "" {
|
||||
go model.SendMail(item.Mail, "[Next Terminal] 注册通知", "你好,"+item.Nickname+"。管理员为你注册了账号:"+item.Username+" 密码:"+password)
|
||||
}
|
||||
return Success(c, item)
|
||||
}
|
||||
|
||||
@ -36,11 +41,12 @@ func UserPagingEndpoint(c echo.Context) error {
|
||||
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
||||
username := c.QueryParam("username")
|
||||
nickname := c.QueryParam("nickname")
|
||||
mail := c.QueryParam("mail")
|
||||
|
||||
order := c.QueryParam("order")
|
||||
field := c.QueryParam("field")
|
||||
|
||||
items, total, err := model.FindPageUser(pageIndex, pageSize, username, nickname, order, field)
|
||||
items, total, err := model.FindPageUser(pageIndex, pageSize, username, nickname, mail, order, field)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -109,6 +115,11 @@ func UserChangePasswordEndpoint(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
password := c.QueryParam("password")
|
||||
|
||||
user, err := model.FindUserById(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
passwd, err := utils.Encoder.Encode([]byte(password))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -117,6 +128,11 @@ func UserChangePasswordEndpoint(c echo.Context) error {
|
||||
Password: string(passwd),
|
||||
}
|
||||
model.UpdateUserById(u, id)
|
||||
|
||||
if user.Mail != "" {
|
||||
go model.SendMail(user.Mail, "[Next Terminal] 密码修改通知", "你好,"+user.Nickname+"。管理员已将你的密码修改为:"+password)
|
||||
}
|
||||
|
||||
return Success(c, "")
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,19 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jordan-wright/email"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net/smtp"
|
||||
"next-terminal/pkg/global"
|
||||
"next-terminal/pkg/guacd"
|
||||
)
|
||||
|
||||
const (
|
||||
SshMode = "ssh-mode"
|
||||
MailHost = "mail-host"
|
||||
MailPort = "mail-port"
|
||||
MailUsername = "mail-username"
|
||||
MailPassword = "mail-password"
|
||||
)
|
||||
|
||||
type Property struct {
|
||||
@ -64,3 +71,26 @@ func GetRecordingPath() (string, error) {
|
||||
}
|
||||
return property.Value, nil
|
||||
}
|
||||
|
||||
func SendMail(to, subject, text string) {
|
||||
propertiesMap := FindAllPropertiesMap()
|
||||
host := propertiesMap[MailHost]
|
||||
port := propertiesMap[MailPort]
|
||||
username := propertiesMap[MailUsername]
|
||||
password := propertiesMap[MailPassword]
|
||||
|
||||
if host == "" || port == "" || username == "" || password == "" {
|
||||
logrus.Debugf("邮箱信息不完整,跳过发送邮件。")
|
||||
return
|
||||
}
|
||||
|
||||
e := email.NewEmail()
|
||||
e.From = "Next Terminal <" + username + ">"
|
||||
e.To = []string{to}
|
||||
e.Subject = subject
|
||||
e.Text = []byte(text)
|
||||
err := e.Send(host+":"+port, smtp.PlainAuth("", username, password, host))
|
||||
if err != nil {
|
||||
logrus.Errorf("邮件发送失败: %v", err.Error())
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ type UserVo struct {
|
||||
ID string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Nickname string `json:"nickname"`
|
||||
TOTPSecret string `json:"totpSecret"`
|
||||
Mail string `json:"mail"`
|
||||
Online bool `json:"online"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Created utils.JsonTime `json:"created"`
|
||||
@ -50,8 +52,8 @@ func FindAllUser() (o []User) {
|
||||
return
|
||||
}
|
||||
|
||||
func FindPageUser(pageIndex, pageSize int, username, nickname, order, field string) (o []UserVo, total int64, err error) {
|
||||
db := global.DB.Table("users").Select("users.id,users.username,users.nickname,users.online,users.enabled,users.created,users.type, count(resource_sharers.user_id) as sharer_asset_count").Joins("left join resource_sharers on users.id = resource_sharers.user_id and resource_sharers.resource_type = 'asset'").Group("users.id")
|
||||
func FindPageUser(pageIndex, pageSize int, username, nickname, mail, order, field string) (o []UserVo, total int64, err error) {
|
||||
db := global.DB.Table("users").Select("users.id,users.username,users.nickname,users.mail,users.online,users.enabled,users.created,users.type, count(resource_sharers.user_id) as sharer_asset_count, users.totp_secret").Joins("left join resource_sharers on users.id = resource_sharers.user_id and resource_sharers.resource_type = 'asset'").Group("users.id")
|
||||
dbCounter := global.DB.Table("users")
|
||||
if len(username) > 0 {
|
||||
db = db.Where("users.username like ?", "%"+username+"%")
|
||||
@ -63,6 +65,11 @@ func FindPageUser(pageIndex, pageSize int, username, nickname, order, field stri
|
||||
dbCounter = dbCounter.Where("nickname like ?", "%"+nickname+"%")
|
||||
}
|
||||
|
||||
if len(mail) > 0 {
|
||||
db = db.Where("users.mail like ?", "%"+mail+"%")
|
||||
dbCounter = dbCounter.Where("mail like ?", "%"+mail+"%")
|
||||
}
|
||||
|
||||
err = dbCounter.Count(&total).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
@ -86,6 +93,14 @@ func FindPageUser(pageIndex, pageSize int, username, nickname, order, field stri
|
||||
if o == nil {
|
||||
o = make([]UserVo, 0)
|
||||
}
|
||||
|
||||
for i := 0; i < len(o); i++ {
|
||||
if o[i].TOTPSecret == "" || o[i].TOTPSecret == "-" {
|
||||
o[i].TOTPSecret = "0"
|
||||
} else {
|
||||
o[i].TOTPSecret = "1"
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -318,6 +318,7 @@ class LoginLog extends Component {
|
||||
onSearch={this.handleSearchByNickname}
|
||||
onChange={this.handleChangeByUserId}
|
||||
filterOption={false}
|
||||
allowClear
|
||||
>
|
||||
{userOptions}
|
||||
</Select>
|
||||
|
@ -379,6 +379,7 @@ class OfflineSession extends Component {
|
||||
onSearch={this.handleSearchByNickname}
|
||||
onChange={this.handleChangeByUserId}
|
||||
filterOption={false}
|
||||
allowClear
|
||||
>
|
||||
{userOptions}
|
||||
</Select>
|
||||
|
@ -374,6 +374,7 @@ class OnlineSession extends Component {
|
||||
onSearch={this.handleSearchByNickname}
|
||||
onChange={this.handleChangeByUserId}
|
||||
filterOption={false}
|
||||
allowClear
|
||||
>
|
||||
{userOptions}
|
||||
</Select>
|
||||
|
@ -42,6 +42,7 @@ class Setting extends Component {
|
||||
sshSettingFormRef = React.createRef();
|
||||
vncSettingFormRef = React.createRef();
|
||||
otherSettingFormRef = React.createRef();
|
||||
mailSettingFormRef = React.createRef();
|
||||
|
||||
componentDidMount() {
|
||||
this.getProperties();
|
||||
@ -98,6 +99,10 @@ class Setting extends Component {
|
||||
if (this.otherSettingFormRef.current) {
|
||||
this.otherSettingFormRef.current.setFieldsValue(properties)
|
||||
}
|
||||
|
||||
if (this.mailSettingFormRef.current) {
|
||||
this.mailSettingFormRef.current.setFieldsValue(properties)
|
||||
}
|
||||
} else {
|
||||
message.error(result['message']);
|
||||
}
|
||||
@ -561,6 +566,77 @@ class Setting extends Component {
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item {...formTailLayout}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
更新
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</TabPane>
|
||||
<TabPane tab="邮箱配置" key="mail">
|
||||
<Title level={3}>Guacd 服务配置</Title>
|
||||
<Form ref={this.mailSettingFormRef} name="password" onFinish={this.changeProperties}
|
||||
layout="vertical">
|
||||
|
||||
<Form.Item
|
||||
{...formItemLayout}
|
||||
name="mail-host"
|
||||
label="邮件服务器地址"
|
||||
rules={[
|
||||
{
|
||||
required: false,
|
||||
message: '邮件服务器地址',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input type='text' placeholder="请输入邮件服务器地址"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
{...formItemLayout}
|
||||
name="mail-port"
|
||||
label="邮件服务器端口"
|
||||
rules={[
|
||||
{
|
||||
required: false,
|
||||
message: '邮件服务器地址',
|
||||
min: 1,
|
||||
max: 65535
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input type='number' placeholder="请输入邮件服务器地址"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
{...formItemLayout}
|
||||
name="mail-username"
|
||||
label="邮箱账号"
|
||||
rules={[
|
||||
{
|
||||
required: false,
|
||||
type: "email",
|
||||
message: '请输入正确的邮箱账号',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input type='email' placeholder="请输入邮箱账号"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
{...formItemLayout}
|
||||
name="mail-password"
|
||||
label="邮箱密码"
|
||||
rules={[
|
||||
{
|
||||
required: false,
|
||||
message: '邮箱密码',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input type='password' placeholder="请输入邮箱密码"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item {...formTailLayout}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
更新
|
||||
|
@ -25,9 +25,10 @@ import UserModal from "./UserModal";
|
||||
import request from "../../common/request";
|
||||
import {message} from "antd/es";
|
||||
import {
|
||||
CheckCircleOutlined,
|
||||
DeleteOutlined,
|
||||
DownOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
ExclamationCircleOutlined, InsuranceOutlined,
|
||||
LockOutlined,
|
||||
PlusOutlined,
|
||||
SyncOutlined,
|
||||
@ -58,6 +59,7 @@ class User extends Component {
|
||||
|
||||
inputRefOfNickname = React.createRef();
|
||||
inputRefOfUsername = React.createRef();
|
||||
inputRefOfMail = React.createRef();
|
||||
changePasswordFormRef = React.createRef()
|
||||
|
||||
state = {
|
||||
@ -234,6 +236,17 @@ class User extends Component {
|
||||
this.loadTableData(query);
|
||||
};
|
||||
|
||||
handleSearchByMail = mail => {
|
||||
let query = {
|
||||
...this.state.queryParams,
|
||||
'pageIndex': 1,
|
||||
'pageSize': this.state.queryParams.pageSize,
|
||||
'mail': mail,
|
||||
}
|
||||
|
||||
this.loadTableData(query);
|
||||
};
|
||||
|
||||
batchDelete = async () => {
|
||||
this.setState({
|
||||
delBtnLoading: true
|
||||
@ -327,7 +340,22 @@ class User extends Component {
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
title: '邮箱',
|
||||
dataIndex: 'mail',
|
||||
key: 'mail',
|
||||
}, {
|
||||
title: '二次认证',
|
||||
dataIndex: 'totpSecret',
|
||||
key: 'totpSecret',
|
||||
render: (text, record) => {
|
||||
|
||||
if (text === '1') {
|
||||
return <Tag icon={<InsuranceOutlined />} color="success">开启</Tag>;
|
||||
}else {
|
||||
return <Tag icon={<ExclamationCircleOutlined />} color="warning">关闭</Tag>;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
title: '在线状态',
|
||||
@ -394,6 +422,7 @@ class User extends Component {
|
||||
let result = await request.post(`/users/${record['id']}/reset-totp`);
|
||||
if (result['code'] === 1) {
|
||||
message.success('操作成功', 3);
|
||||
this.loadTableData();
|
||||
} else {
|
||||
message.error(result['message'], 10);
|
||||
}
|
||||
@ -414,7 +443,14 @@ class User extends Component {
|
||||
return (
|
||||
<div>
|
||||
<Button type="link" size='small'
|
||||
onClick={() => this.showModal('更新用户', record)}>编辑</Button>
|
||||
onClick={async () => {
|
||||
let result = await request.get(`/users/${record['id']}`);
|
||||
if (result['code'] !== 1) {
|
||||
message.error(result['message']);
|
||||
return;
|
||||
}
|
||||
this.showModal('更新用户', result['data']);
|
||||
}}>编辑</Button>
|
||||
<Dropdown overlay={menu}>
|
||||
<Button type="link" size='small'>
|
||||
更多 <DownOutlined/>
|
||||
@ -474,11 +510,19 @@ class User extends Component {
|
||||
onSearch={this.handleSearchByUsername}
|
||||
/>
|
||||
|
||||
<Search
|
||||
ref={this.inputRefOfMail}
|
||||
placeholder="邮箱"
|
||||
allowClear
|
||||
onSearch={this.handleSearchByMail}
|
||||
/>
|
||||
|
||||
<Tooltip title='重置查询'>
|
||||
|
||||
<Button icon={<UndoOutlined/>} onClick={() => {
|
||||
this.inputRefOfUsername.current.setValue('');
|
||||
this.inputRefOfNickname.current.setValue('');
|
||||
this.inputRefOfMail.current.setValue('');
|
||||
this.loadTableData({pageIndex: 1, pageSize: 10})
|
||||
}}>
|
||||
|
||||
|
@ -52,6 +52,10 @@ const UserModal = ({title, visible, handleOk, handleCancel, confirmLoading, mode
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="邮箱账号" name="mail" rules={[{required: false, type: "email", message: '请输入正确的邮箱账号',},]}>
|
||||
<Input type='email' placeholder="请输入邮箱账号"/>
|
||||
</Form.Item>
|
||||
|
||||
{
|
||||
title.indexOf('新增') > -1 ?
|
||||
(<Form.Item label="登录密码" name='password' rules={[{required: true, message: '请输入登录密码'}]}>
|
||||
|
Reference in New Issue
Block a user