260 lines
6.7 KiB
Go
260 lines
6.7 KiB
Go
package controllers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"server/models"
|
|
"server/pkg/jwtutil"
|
|
|
|
"github.com/beego/beego/v2/client/orm"
|
|
beego "github.com/beego/beego/v2/server/web"
|
|
)
|
|
|
|
// PlatformLoginLogController 登录日志(yz_system_login_log,平台端)
|
|
type PlatformLoginLogController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
func (c *PlatformLoginLogController) jsonErr(httpStatus, bizCode int, msg string) {
|
|
c.Ctx.Output.SetStatus(httpStatus)
|
|
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
|
_ = c.ServeJSON()
|
|
}
|
|
|
|
func (c *PlatformLoginLogController) platformClaims() (*jwtutil.Claims, error) {
|
|
auth := c.Ctx.Request.Header.Get("Authorization")
|
|
if auth == "" {
|
|
return nil, fmt.Errorf("未登录")
|
|
}
|
|
parts := strings.SplitN(auth, " ", 2)
|
|
if len(parts) != 2 || parts[0] != "Bearer" {
|
|
return nil, fmt.Errorf("认证信息格式错误")
|
|
}
|
|
claims, err := jwtutil.ParseToken(parts[1])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("无效的token")
|
|
}
|
|
if claims.UserType != "platform" {
|
|
return nil, fmt.Errorf("无权访问")
|
|
}
|
|
return claims, nil
|
|
}
|
|
|
|
// List GET /platform/loginLogs?page=1&pageSize=20&keyword=&status=&loginType=&startTime=&endTime=
|
|
func (c *PlatformLoginLogController) List() {
|
|
if _, err := c.platformClaims(); err != nil {
|
|
c.jsonErr(401, 401, err.Error())
|
|
return
|
|
}
|
|
|
|
page, _ := c.GetInt("page", 1)
|
|
pageSize, _ := c.GetInt("pageSize", 20)
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
if pageSize < 1 {
|
|
pageSize = 20
|
|
}
|
|
if pageSize > 200 {
|
|
pageSize = 200
|
|
}
|
|
|
|
keyword := strings.TrimSpace(c.GetString("keyword"))
|
|
statusStr := strings.TrimSpace(c.GetString("status"))
|
|
loginType := strings.TrimSpace(c.GetString("loginType"))
|
|
startTimeStr := strings.TrimSpace(c.GetString("startTime"))
|
|
endTimeStr := strings.TrimSpace(c.GetString("endTime"))
|
|
|
|
qs := models.Orm.QueryTable(new(models.SystemLoginLog)).Filter("delete_time__isnull", true)
|
|
|
|
cond := orm.NewCondition()
|
|
needCond := false
|
|
|
|
if statusStr != "" {
|
|
if st, err := strconv.Atoi(statusStr); err == nil {
|
|
cond = cond.And("status", st)
|
|
needCond = true
|
|
}
|
|
}
|
|
if loginType != "" {
|
|
cond = cond.And("login_type", loginType)
|
|
needCond = true
|
|
}
|
|
if keyword != "" {
|
|
kw := orm.NewCondition().
|
|
Or("account__icontains", keyword).
|
|
Or("user_name__icontains", keyword).
|
|
Or("tenant_name__icontains", keyword).
|
|
Or("ip__icontains", keyword)
|
|
if uid, err := strconv.ParseUint(keyword, 10, 64); err == nil && uid > 0 {
|
|
kw = kw.Or("user_id", uid)
|
|
}
|
|
cond = cond.AndCond(kw)
|
|
needCond = true
|
|
}
|
|
if t, err := parseTimeFlexible(startTimeStr); err == nil && !t.IsZero() {
|
|
cond = cond.And("create_time__gte", t)
|
|
needCond = true
|
|
}
|
|
if t, err := parseTimeFlexible(endTimeStr); err == nil && !t.IsZero() {
|
|
cond = cond.And("create_time__lte", t)
|
|
needCond = true
|
|
}
|
|
|
|
if needCond {
|
|
qs = qs.SetCond(cond)
|
|
}
|
|
|
|
total, err := qs.Count()
|
|
if err != nil {
|
|
c.jsonErr(500, 500, "获取登录日志失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
var rows []models.SystemLoginLog
|
|
_, err = qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&rows)
|
|
if err != nil {
|
|
c.jsonErr(500, 500, "获取登录日志失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
list := make([]map[string]interface{}, 0, len(rows))
|
|
for i := range rows {
|
|
item := map[string]interface{}{
|
|
"id": rows[i].ID,
|
|
"tid": rows[i].Tid,
|
|
"user_id": rows[i].UserID,
|
|
"account": rows[i].Account,
|
|
"user_name": rows[i].UserName,
|
|
"tenant_name": rows[i].TenantName,
|
|
"login_type": rows[i].LoginType,
|
|
"status": rows[i].Status,
|
|
"message": rows[i].Message,
|
|
"ip": rows[i].IP,
|
|
"user_agent": rows[i].UserAgent,
|
|
"create_time": rows[i].CreateTime.Format("2006-01-02 15:04:05"),
|
|
}
|
|
list = append(list, item)
|
|
}
|
|
|
|
c.Data["json"] = map[string]interface{}{
|
|
"code": 200,
|
|
"msg": "success",
|
|
"data": map[string]interface{}{
|
|
"list": list,
|
|
"total": total,
|
|
},
|
|
}
|
|
_ = c.ServeJSON()
|
|
}
|
|
|
|
// Detail GET /platform/loginLogs/:id
|
|
func (c *PlatformLoginLogController) Detail() {
|
|
if _, err := c.platformClaims(); err != nil {
|
|
c.jsonErr(401, 401, err.Error())
|
|
return
|
|
}
|
|
idStr := c.Ctx.Input.Param(":id")
|
|
id, err := strconv.ParseUint(idStr, 10, 64)
|
|
if err != nil || id == 0 {
|
|
c.jsonErr(400, 400, "无效ID")
|
|
return
|
|
}
|
|
var row models.SystemLoginLog
|
|
err = models.Orm.QueryTable(new(models.SystemLoginLog)).
|
|
Filter("id", id).
|
|
Filter("delete_time__isnull", true).
|
|
One(&row)
|
|
if err != nil {
|
|
c.jsonErr(404, 404, "记录不存在")
|
|
return
|
|
}
|
|
out := map[string]interface{}{
|
|
"id": row.ID,
|
|
"tid": row.Tid,
|
|
"user_id": row.UserID,
|
|
"account": row.Account,
|
|
"user_name": row.UserName,
|
|
"tenant_name": row.TenantName,
|
|
"login_type": row.LoginType,
|
|
"status": row.Status,
|
|
"message": row.Message,
|
|
"ip": row.IP,
|
|
"user_agent": row.UserAgent,
|
|
"create_time": row.CreateTime.Format("2006-01-02 15:04:05"),
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": out}
|
|
_ = c.ServeJSON()
|
|
}
|
|
|
|
// Delete DELETE /platform/loginLogs/:id
|
|
func (c *PlatformLoginLogController) Delete() {
|
|
if _, err := c.platformClaims(); err != nil {
|
|
c.jsonErr(401, 401, err.Error())
|
|
return
|
|
}
|
|
idStr := c.Ctx.Input.Param(":id")
|
|
id, err := strconv.ParseUint(idStr, 10, 64)
|
|
if err != nil || id == 0 {
|
|
c.jsonErr(400, 400, "无效ID")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
n, err := models.Orm.QueryTable(new(models.SystemLoginLog)).
|
|
Filter("id", id).
|
|
Filter("delete_time__isnull", true).
|
|
Update(map[string]interface{}{"delete_time": now})
|
|
if err != nil {
|
|
c.jsonErr(500, 500, "删除失败: "+err.Error())
|
|
return
|
|
}
|
|
if n == 0 {
|
|
c.jsonErr(404, 404, "记录不存在")
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
|
|
_ = c.ServeJSON()
|
|
}
|
|
|
|
type platformLoginLogBatchDeletePayload struct {
|
|
IDs []uint64 `json:"ids"`
|
|
}
|
|
|
|
// BatchDelete POST /platform/loginLogs/batchDelete
|
|
func (c *PlatformLoginLogController) BatchDelete() {
|
|
if _, err := c.platformClaims(); err != nil {
|
|
c.jsonErr(401, 401, err.Error())
|
|
return
|
|
}
|
|
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
|
if err != nil {
|
|
c.jsonErr(400, 400, "参数错误")
|
|
return
|
|
}
|
|
var p platformLoginLogBatchDeletePayload
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
c.jsonErr(400, 400, "参数错误")
|
|
return
|
|
}
|
|
if len(p.IDs) == 0 {
|
|
c.jsonErr(400, 400, "请选择要删除的日志")
|
|
return
|
|
}
|
|
now := time.Now()
|
|
_, err = models.Orm.QueryTable(new(models.SystemLoginLog)).
|
|
Filter("id__in", p.IDs).
|
|
Filter("delete_time__isnull", true).
|
|
Update(map[string]interface{}{"delete_time": now})
|
|
if err != nil {
|
|
c.jsonErr(500, 500, "批量删除失败: "+err.Error())
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "批量删除成功"}
|
|
_ = c.ServeJSON()
|
|
}
|