diff --git a/controller/user.go b/controller/user.go index d6becdd8..b5722668 100644 --- a/controller/user.go +++ b/controller/user.go @@ -91,6 +91,7 @@ func Login(c *gin.Context) { // setup session & cookies and then return user info func setupLogin(user *model.User, c *gin.Context) { + model.UpdateUserLastLoginAt(user.Id) session := sessions.Default(c) session.Set("id", user.Id) session.Set("username", user.Username) diff --git a/model/user.go b/model/user.go index 79e63e8f..b632ef9a 100644 --- a/model/user.go +++ b/model/user.go @@ -50,6 +50,8 @@ type User struct { Setting string `json:"setting" gorm:"type:text;column:setting"` Remark string `json:"remark,omitempty" gorm:"type:varchar(255)" validate:"max=255"` StripeCustomer string `json:"stripe_customer" gorm:"type:varchar(64);column:stripe_customer;index"` + CreatedAt int64 `json:"created_at" gorm:"autoCreateTime;column:created_at"` + LastLoginAt int64 `json:"last_login_at" gorm:"default:0;column:last_login_at"` } func (user *User) ToBaseUser() *UserBase { @@ -951,6 +953,12 @@ func GetRootUser() (user *User) { return user } +func UpdateUserLastLoginAt(id int) { + if err := DB.Model(&User{}).Where("id = ?", id).Update("last_login_at", common.GetTimestamp()).Error; err != nil { + common.SysLog("failed to update user last_login_at: " + err.Error()) + } +} + func UpdateUserUsedQuotaAndRequestCount(id int, quota int) { if common.BatchUpdateEnabled { addNewRecord(BatchUpdateTypeUsedQuota, id, quota) diff --git a/web/src/components/table/users/UsersColumnDefs.jsx b/web/src/components/table/users/UsersColumnDefs.jsx index dc3e6f34..2e0d171a 100644 --- a/web/src/components/table/users/UsersColumnDefs.jsx +++ b/web/src/components/table/users/UsersColumnDefs.jsx @@ -29,7 +29,14 @@ import { Dropdown, } from '@douyinfe/semi-ui'; import { IconMore } from '@douyinfe/semi-icons'; -import { renderGroup, renderNumber, renderQuota } from '../../../helpers'; +import { + renderGroup, + renderNumber, + renderQuota, + timestamp2string, +} from '../../../helpers'; + +const renderTimestamp = (text) => (text ? timestamp2string(text) : '-'); /** * Render user role @@ -350,6 +357,16 @@ export const getUsersColumns = ({ dataIndex: 'invite', render: (text, record, index) => renderInviteInfo(text, record, t), }, + { + title: t('创建时间'), + dataIndex: 'created_at', + render: renderTimestamp, + }, + { + title: t('最后登录'), + dataIndex: 'last_login_at', + render: renderTimestamp, + }, { title: '', dataIndex: 'operate',