移除轮询
This commit is contained in:
@@ -242,14 +242,7 @@ const handleMarkAllRead = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMessagesChanged = () => {
|
// 根据菜单列表和当前路径计算出的面包屑导航
|
||||||
fetchUnreadCount();
|
|
||||||
fetchMessages();
|
|
||||||
};
|
|
||||||
|
|
||||||
let timer: any = null;
|
|
||||||
|
|
||||||
// 根据菜单列表和当前路径计算出的面包屑导航
|
|
||||||
const breadcrumbs = computed(() => {
|
const breadcrumbs = computed(() => {
|
||||||
let chain: Breadcrumb[] = [];
|
let chain: Breadcrumb[] = [];
|
||||||
let currentPath = route.path || '/';
|
let currentPath = route.path || '/';
|
||||||
@@ -433,9 +426,8 @@ onMounted(async () => {
|
|||||||
mediaQuery.addEventListener('change', handleChange);
|
mediaQuery.addEventListener('change', handleChange);
|
||||||
|
|
||||||
if (authStore.token) {
|
if (authStore.token) {
|
||||||
|
// 仅在后台页面刷新/首次挂载时更新未读数量,不再自动轮询。
|
||||||
fetchUnreadCount();
|
fetchUnreadCount();
|
||||||
timer = setInterval(fetchUnreadCount, 60000);
|
|
||||||
window.addEventListener('site-messages-changed', handleMessagesChanged);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -444,10 +436,6 @@ onUnmounted(() => {
|
|||||||
if (mediaQuery && handleChange) {
|
if (mediaQuery && handleChange) {
|
||||||
mediaQuery.removeEventListener('change', handleChange);
|
mediaQuery.removeEventListener('change', handleChange);
|
||||||
}
|
}
|
||||||
if (timer) {
|
|
||||||
clearInterval(timer);
|
|
||||||
}
|
|
||||||
window.removeEventListener('site-messages-changed', handleMessagesChanged);
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,332 +1,339 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"server/models"
|
"server/models"
|
||||||
"server/pkg/jwtutil"
|
"server/pkg/jwtutil"
|
||||||
|
"server/services"
|
||||||
"github.com/beego/beego/v2/client/orm"
|
|
||||||
beego "github.com/beego/beego/v2/server/web"
|
"github.com/beego/beego/v2/client/orm"
|
||||||
)
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
|
)
|
||||||
// BackendOperationLogController 操作日志(yz_system_operation_log)
|
|
||||||
type BackendOperationLogController struct {
|
// BackendOperationLogController 操作日志(yz_system_operation_log)
|
||||||
beego.Controller
|
type BackendOperationLogController struct {
|
||||||
}
|
beego.Controller
|
||||||
|
}
|
||||||
func (c *BackendOperationLogController) backendClaims() (*jwtutil.Claims, error) {
|
|
||||||
auth := c.Ctx.Request.Header.Get("Authorization")
|
func (c *BackendOperationLogController) backendClaims() (*jwtutil.Claims, error) {
|
||||||
if auth == "" {
|
auth := c.Ctx.Request.Header.Get("Authorization")
|
||||||
return nil, fmt.Errorf("未登录")
|
if auth == "" {
|
||||||
}
|
return nil, fmt.Errorf("未登录")
|
||||||
parts := strings.SplitN(auth, " ", 2)
|
}
|
||||||
if len(parts) != 2 || parts[0] != "Bearer" {
|
parts := strings.SplitN(auth, " ", 2)
|
||||||
return nil, fmt.Errorf("认证信息格式错误")
|
if len(parts) != 2 || parts[0] != "Bearer" {
|
||||||
}
|
return nil, fmt.Errorf("认证信息格式错误")
|
||||||
claims, err := jwtutil.ParseToken(parts[1])
|
}
|
||||||
if err != nil {
|
claims, err := jwtutil.ParseToken(parts[1])
|
||||||
return nil, fmt.Errorf("无效的token")
|
if err != nil {
|
||||||
}
|
return nil, fmt.Errorf("无效的token")
|
||||||
if claims.UserType != "backend" {
|
}
|
||||||
return nil, fmt.Errorf("无权访问")
|
if claims.UserType != "backend" {
|
||||||
}
|
return nil, fmt.Errorf("无权访问")
|
||||||
return claims, nil
|
}
|
||||||
}
|
return claims, nil
|
||||||
|
}
|
||||||
func (c *BackendOperationLogController) jsonErr(httpStatus, bizCode int, msg string) {
|
|
||||||
c.Ctx.Output.SetStatus(httpStatus)
|
func (c *BackendOperationLogController) jsonErr(httpStatus, bizCode int, msg string) {
|
||||||
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
c.Ctx.Output.SetStatus(httpStatus)
|
||||||
_ = c.ServeJSON()
|
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
||||||
}
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
// List GET /backend/operationLogs?page=1&pageSize=20&keyword=&module=&action=&status=&startTime=&endTime=
|
|
||||||
func (c *BackendOperationLogController) List() {
|
// List GET /backend/operationLogs?page=1&pageSize=20&keyword=&module=&action=&status=&startTime=&endTime=
|
||||||
if _, err := c.backendClaims(); err != nil {
|
func (c *BackendOperationLogController) List() {
|
||||||
c.jsonErr(401, 401, err.Error())
|
if _, err := c.backendClaims(); err != nil {
|
||||||
return
|
c.jsonErr(401, 401, err.Error())
|
||||||
}
|
return
|
||||||
|
}
|
||||||
page, _ := c.GetInt("page", 1)
|
|
||||||
pageSize, _ := c.GetInt("pageSize", 20)
|
page, _ := c.GetInt("page", 1)
|
||||||
if page < 1 {
|
pageSize, _ := c.GetInt("pageSize", 20)
|
||||||
page = 1
|
if page < 1 {
|
||||||
}
|
page = 1
|
||||||
if pageSize < 1 {
|
}
|
||||||
pageSize = 20
|
if pageSize < 1 {
|
||||||
}
|
pageSize = 20
|
||||||
if pageSize > 200 {
|
}
|
||||||
pageSize = 200
|
if pageSize > 200 {
|
||||||
}
|
pageSize = 200
|
||||||
|
}
|
||||||
keyword := strings.TrimSpace(c.GetString("keyword"))
|
|
||||||
module := strings.TrimSpace(c.GetString("module"))
|
keyword := strings.TrimSpace(c.GetString("keyword"))
|
||||||
action := strings.TrimSpace(c.GetString("action"))
|
module := strings.TrimSpace(c.GetString("module"))
|
||||||
statusStr := strings.TrimSpace(c.GetString("status"))
|
action := strings.TrimSpace(c.GetString("action"))
|
||||||
startTimeStr := strings.TrimSpace(c.GetString("startTime"))
|
statusStr := strings.TrimSpace(c.GetString("status"))
|
||||||
endTimeStr := strings.TrimSpace(c.GetString("endTime"))
|
startTimeStr := strings.TrimSpace(c.GetString("startTime"))
|
||||||
|
endTimeStr := strings.TrimSpace(c.GetString("endTime"))
|
||||||
qs := models.Orm.QueryTable(new(models.SystemOperationLog)).Filter("delete_time__isnull", true)
|
|
||||||
|
qs := models.Orm.QueryTable(new(models.SystemOperationLog)).Filter("delete_time__isnull", true)
|
||||||
// 条件拼装
|
|
||||||
cond := orm.NewCondition()
|
// 条件拼装
|
||||||
needCond := false
|
cond := orm.NewCondition()
|
||||||
|
needCond := false
|
||||||
if module != "" {
|
|
||||||
cond = cond.And("module", module)
|
if module != "" {
|
||||||
needCond = true
|
cond = cond.And("module", module)
|
||||||
}
|
needCond = true
|
||||||
if action != "" {
|
}
|
||||||
cond = cond.And("action", action)
|
if action != "" {
|
||||||
needCond = true
|
cond = cond.And("action", action)
|
||||||
}
|
needCond = true
|
||||||
if statusStr != "" {
|
}
|
||||||
if st, err := strconv.Atoi(statusStr); err == nil {
|
if statusStr != "" {
|
||||||
cond = cond.And("status", st)
|
if st, err := strconv.Atoi(statusStr); err == nil {
|
||||||
needCond = true
|
cond = cond.And("status", st)
|
||||||
}
|
needCond = true
|
||||||
}
|
}
|
||||||
if keyword != "" {
|
}
|
||||||
kw := orm.NewCondition().
|
if keyword != "" {
|
||||||
Or("module__icontains", keyword).
|
kw := orm.NewCondition().
|
||||||
Or("action__icontains", keyword).
|
Or("module__icontains", keyword).
|
||||||
Or("method__icontains", keyword).
|
Or("action__icontains", keyword).
|
||||||
Or("url__icontains", keyword).
|
Or("method__icontains", keyword).
|
||||||
Or("ip__icontains", keyword).
|
Or("url__icontains", keyword).
|
||||||
Or("user_agent__icontains", keyword)
|
Or("ip__icontains", keyword).
|
||||||
if uid, err := strconv.ParseUint(keyword, 10, 64); err == nil && uid > 0 {
|
Or("user_agent__icontains", keyword)
|
||||||
kw = kw.Or("user_id", uid)
|
if uid, err := strconv.ParseUint(keyword, 10, 64); err == nil && uid > 0 {
|
||||||
}
|
kw = kw.Or("user_id", uid)
|
||||||
cond = cond.AndCond(kw)
|
}
|
||||||
needCond = true
|
cond = cond.AndCond(kw)
|
||||||
}
|
needCond = true
|
||||||
if t, err := parseTimeFlexible(startTimeStr); err == nil && !t.IsZero() {
|
}
|
||||||
cond = cond.And("create_time__gte", t)
|
if t, err := parseTimeFlexible(startTimeStr); err == nil && !t.IsZero() {
|
||||||
needCond = true
|
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)
|
if t, err := parseTimeFlexible(endTimeStr); err == nil && !t.IsZero() {
|
||||||
needCond = true
|
cond = cond.And("create_time__lte", t)
|
||||||
}
|
needCond = true
|
||||||
|
}
|
||||||
if needCond {
|
|
||||||
qs = qs.SetCond(cond)
|
if needCond {
|
||||||
}
|
qs = qs.SetCond(cond)
|
||||||
|
}
|
||||||
total, err := qs.Count()
|
|
||||||
if err != nil {
|
total, err := qs.Count()
|
||||||
c.jsonErr(500, 500, "获取操作日志失败: "+err.Error())
|
if err != nil {
|
||||||
return
|
c.jsonErr(500, 500, "获取操作日志失败: "+err.Error())
|
||||||
}
|
return
|
||||||
|
}
|
||||||
var rows []models.SystemOperationLog
|
|
||||||
_, err = qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&rows)
|
var rows []models.SystemOperationLog
|
||||||
if err != nil {
|
_, err = qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&rows)
|
||||||
c.jsonErr(500, 500, "获取操作日志失败: "+err.Error())
|
if err != nil {
|
||||||
return
|
c.jsonErr(500, 500, "获取操作日志失败: "+err.Error())
|
||||||
}
|
return
|
||||||
|
}
|
||||||
list := make([]map[string]interface{}, 0, len(rows))
|
|
||||||
for i := range rows {
|
list := make([]map[string]interface{}, 0, len(rows))
|
||||||
item := map[string]interface{}{
|
for i := range rows {
|
||||||
"id": rows[i].ID,
|
userAccount, userName := services.OperationLogUser(rows[i].Tid, rows[i].UserID)
|
||||||
"tid": rows[i].Tid,
|
item := map[string]interface{}{
|
||||||
"user_id": rows[i].UserID,
|
"id": rows[i].ID,
|
||||||
"module": rows[i].Module,
|
"tid": rows[i].Tid,
|
||||||
"action": rows[i].Action,
|
"user_id": rows[i].UserID,
|
||||||
"method": rows[i].Method,
|
"user_account": userAccount,
|
||||||
"url": rows[i].URL,
|
"user_name": userName,
|
||||||
"ip": rows[i].IP,
|
"module": rows[i].Module,
|
||||||
"user_agent": rows[i].UserAgent,
|
"action": rows[i].Action,
|
||||||
"request_data": rows[i].RequestData,
|
"method": rows[i].Method,
|
||||||
"response_data": rows[i].ResponseData,
|
"url": rows[i].URL,
|
||||||
"status": rows[i].Status,
|
"ip": rows[i].IP,
|
||||||
"error_message": rows[i].ErrorMessage,
|
"user_agent": rows[i].UserAgent,
|
||||||
"execution_time": rows[i].ExecutionTime,
|
"request_data": rows[i].RequestData,
|
||||||
"create_time": rows[i].CreateTime.Format("2006-01-02 15:04:05"),
|
"response_data": rows[i].ResponseData,
|
||||||
"update_time": "",
|
"status": rows[i].Status,
|
||||||
}
|
"error_message": rows[i].ErrorMessage,
|
||||||
if rows[i].UpdateTime != nil {
|
"execution_time": rows[i].ExecutionTime,
|
||||||
item["update_time"] = rows[i].UpdateTime.Format("2006-01-02 15:04:05")
|
"create_time": rows[i].CreateTime.Format("2006-01-02 15:04:05"),
|
||||||
}
|
"update_time": "",
|
||||||
list = append(list, item)
|
}
|
||||||
}
|
if rows[i].UpdateTime != nil {
|
||||||
|
item["update_time"] = rows[i].UpdateTime.Format("2006-01-02 15:04:05")
|
||||||
c.Data["json"] = map[string]interface{}{
|
}
|
||||||
"code": 200,
|
list = append(list, item)
|
||||||
"msg": "success",
|
}
|
||||||
"data": map[string]interface{}{
|
|
||||||
"list": list,
|
c.Data["json"] = map[string]interface{}{
|
||||||
"total": total,
|
"code": 200,
|
||||||
},
|
"msg": "success",
|
||||||
}
|
"data": map[string]interface{}{
|
||||||
_ = c.ServeJSON()
|
"list": list,
|
||||||
}
|
"total": total,
|
||||||
|
},
|
||||||
// Detail GET /backend/operationLogs/:id
|
}
|
||||||
func (c *BackendOperationLogController) Detail() {
|
_ = c.ServeJSON()
|
||||||
if _, err := c.backendClaims(); err != nil {
|
}
|
||||||
c.jsonErr(401, 401, err.Error())
|
|
||||||
return
|
// Detail GET /backend/operationLogs/:id
|
||||||
}
|
func (c *BackendOperationLogController) Detail() {
|
||||||
idStr := c.Ctx.Input.Param(":id")
|
if _, err := c.backendClaims(); err != nil {
|
||||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
c.jsonErr(401, 401, err.Error())
|
||||||
if err != nil || id == 0 {
|
return
|
||||||
c.jsonErr(400, 400, "无效ID")
|
}
|
||||||
return
|
idStr := c.Ctx.Input.Param(":id")
|
||||||
}
|
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||||
var row models.SystemOperationLog
|
if err != nil || id == 0 {
|
||||||
err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
c.jsonErr(400, 400, "无效ID")
|
||||||
Filter("id", id).
|
return
|
||||||
Filter("delete_time__isnull", true).
|
}
|
||||||
One(&row)
|
var row models.SystemOperationLog
|
||||||
if err != nil {
|
err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
c.jsonErr(404, 404, "记录不存在")
|
Filter("id", id).
|
||||||
return
|
Filter("delete_time__isnull", true).
|
||||||
}
|
One(&row)
|
||||||
out := map[string]interface{}{
|
if err != nil {
|
||||||
"id": row.ID,
|
c.jsonErr(404, 404, "记录不存在")
|
||||||
"tid": row.Tid,
|
return
|
||||||
"user_id": row.UserID,
|
}
|
||||||
"module": row.Module,
|
userAccount, userName := services.OperationLogUser(row.Tid, row.UserID)
|
||||||
"action": row.Action,
|
out := map[string]interface{}{
|
||||||
"method": row.Method,
|
"id": row.ID,
|
||||||
"url": row.URL,
|
"tid": row.Tid,
|
||||||
"ip": row.IP,
|
"user_id": row.UserID,
|
||||||
"user_agent": row.UserAgent,
|
"user_account": userAccount,
|
||||||
"request_data": row.RequestData,
|
"user_name": userName,
|
||||||
"response_data": row.ResponseData,
|
"module": row.Module,
|
||||||
"status": row.Status,
|
"action": row.Action,
|
||||||
"error_message": row.ErrorMessage,
|
"method": row.Method,
|
||||||
"execution_time": row.ExecutionTime,
|
"url": row.URL,
|
||||||
"create_time": row.CreateTime.Format("2006-01-02 15:04:05"),
|
"ip": row.IP,
|
||||||
}
|
"user_agent": row.UserAgent,
|
||||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": out}
|
"request_data": row.RequestData,
|
||||||
_ = c.ServeJSON()
|
"response_data": row.ResponseData,
|
||||||
}
|
"status": row.Status,
|
||||||
|
"error_message": row.ErrorMessage,
|
||||||
// Delete DELETE /backend/operationLogs/:id
|
"execution_time": row.ExecutionTime,
|
||||||
func (c *BackendOperationLogController) Delete() {
|
"create_time": row.CreateTime.Format("2006-01-02 15:04:05"),
|
||||||
if _, err := c.backendClaims(); err != nil {
|
}
|
||||||
c.jsonErr(401, 401, err.Error())
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": out}
|
||||||
return
|
_ = c.ServeJSON()
|
||||||
}
|
}
|
||||||
idStr := c.Ctx.Input.Param(":id")
|
|
||||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
// Delete DELETE /backend/operationLogs/:id
|
||||||
if err != nil || id == 0 {
|
func (c *BackendOperationLogController) Delete() {
|
||||||
c.jsonErr(400, 400, "无效ID")
|
if _, err := c.backendClaims(); err != nil {
|
||||||
return
|
c.jsonErr(401, 401, err.Error())
|
||||||
}
|
return
|
||||||
now := time.Now()
|
}
|
||||||
n, err := models.Orm.QueryTable(new(models.SystemOperationLog)).
|
idStr := c.Ctx.Input.Param(":id")
|
||||||
Filter("id", id).
|
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||||
Filter("delete_time__isnull", true).
|
if err != nil || id == 0 {
|
||||||
Update(map[string]interface{}{"delete_time": now})
|
c.jsonErr(400, 400, "无效ID")
|
||||||
if err != nil {
|
return
|
||||||
c.jsonErr(500, 500, "删除失败: "+err.Error())
|
}
|
||||||
return
|
now := time.Now()
|
||||||
}
|
n, err := models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
if n == 0 {
|
Filter("id", id).
|
||||||
c.jsonErr(404, 404, "记录不存在")
|
Filter("delete_time__isnull", true).
|
||||||
return
|
Update(map[string]interface{}{"delete_time": now})
|
||||||
}
|
if err != nil {
|
||||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
|
c.jsonErr(500, 500, "删除失败: "+err.Error())
|
||||||
_ = c.ServeJSON()
|
return
|
||||||
}
|
}
|
||||||
|
if n == 0 {
|
||||||
type backendBatchDeletePayload struct {
|
c.jsonErr(404, 404, "记录不存在")
|
||||||
IDs []uint64 `json:"ids"`
|
return
|
||||||
}
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
|
||||||
// BatchDelete POST /backend/operationLogs/batchDelete
|
_ = c.ServeJSON()
|
||||||
func (c *BackendOperationLogController) BatchDelete() {
|
}
|
||||||
if _, err := c.backendClaims(); err != nil {
|
|
||||||
c.jsonErr(401, 401, err.Error())
|
type backendBatchDeletePayload struct {
|
||||||
return
|
IDs []uint64 `json:"ids"`
|
||||||
}
|
}
|
||||||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
|
||||||
if err != nil {
|
// BatchDelete POST /backend/operationLogs/batchDelete
|
||||||
c.jsonErr(400, 400, "参数错误")
|
func (c *BackendOperationLogController) BatchDelete() {
|
||||||
return
|
if _, err := c.backendClaims(); err != nil {
|
||||||
}
|
c.jsonErr(401, 401, err.Error())
|
||||||
var p backendBatchDeletePayload
|
return
|
||||||
if err := json.Unmarshal(raw, &p); err != nil {
|
}
|
||||||
c.jsonErr(400, 400, "参数错误")
|
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||||||
return
|
if err != nil {
|
||||||
}
|
c.jsonErr(400, 400, "参数错误")
|
||||||
if len(p.IDs) == 0 {
|
return
|
||||||
c.jsonErr(400, 400, "请选择要删除的日志")
|
}
|
||||||
return
|
var p backendBatchDeletePayload
|
||||||
}
|
if err := json.Unmarshal(raw, &p); err != nil {
|
||||||
now := time.Now()
|
c.jsonErr(400, 400, "参数错误")
|
||||||
_, err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
return
|
||||||
Filter("id__in", p.IDs).
|
}
|
||||||
Filter("delete_time__isnull", true).
|
if len(p.IDs) == 0 {
|
||||||
Update(map[string]interface{}{"delete_time": now})
|
c.jsonErr(400, 400, "请选择要删除的日志")
|
||||||
if err != nil {
|
return
|
||||||
c.jsonErr(500, 500, "批量删除失败: "+err.Error())
|
}
|
||||||
return
|
now := time.Now()
|
||||||
}
|
_, err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "批量删除成功"}
|
Filter("id__in", p.IDs).
|
||||||
_ = c.ServeJSON()
|
Filter("delete_time__isnull", true).
|
||||||
}
|
Update(map[string]interface{}{"delete_time": now})
|
||||||
|
if err != nil {
|
||||||
// Statistics GET /backend/operationLogs/statistics
|
c.jsonErr(500, 500, "批量删除失败: "+err.Error())
|
||||||
// 供前端筛选项:modules/actions
|
return
|
||||||
func (c *BackendOperationLogController) Statistics() {
|
}
|
||||||
if _, err := c.backendClaims(); err != nil {
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "批量删除成功"}
|
||||||
c.jsonErr(401, 401, err.Error())
|
_ = c.ServeJSON()
|
||||||
return
|
}
|
||||||
}
|
|
||||||
|
// Statistics GET /backend/operationLogs/statistics
|
||||||
var moduleRows []models.SystemOperationLog
|
// 供前端筛选项:modules/actions
|
||||||
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
func (c *BackendOperationLogController) Statistics() {
|
||||||
Filter("delete_time__isnull", true).
|
if _, err := c.backendClaims(); err != nil {
|
||||||
Filter("module__isnull", false).
|
c.jsonErr(401, 401, err.Error())
|
||||||
Limit(1000).
|
return
|
||||||
All(&moduleRows, "Module")
|
}
|
||||||
modSet := map[string]struct{}{}
|
|
||||||
for i := range moduleRows {
|
var moduleRows []models.SystemOperationLog
|
||||||
m := strings.TrimSpace(moduleRows[i].Module)
|
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
if m != "" {
|
Filter("delete_time__isnull", true).
|
||||||
modSet[m] = struct{}{}
|
Filter("module__isnull", false).
|
||||||
}
|
Limit(1000).
|
||||||
}
|
All(&moduleRows, "Module")
|
||||||
modules := make([]string, 0, len(modSet))
|
modSet := map[string]struct{}{}
|
||||||
for k := range modSet {
|
for i := range moduleRows {
|
||||||
modules = append(modules, k)
|
m := strings.TrimSpace(moduleRows[i].Module)
|
||||||
}
|
if m != "" {
|
||||||
|
modSet[m] = struct{}{}
|
||||||
var actionRows []models.SystemOperationLog
|
}
|
||||||
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
}
|
||||||
Filter("delete_time__isnull", true).
|
modules := make([]string, 0, len(modSet))
|
||||||
Filter("action__isnull", false).
|
for k := range modSet {
|
||||||
Limit(1000).
|
modules = append(modules, k)
|
||||||
All(&actionRows, "Action")
|
}
|
||||||
actSet := map[string]struct{}{}
|
|
||||||
for i := range actionRows {
|
var actionRows []models.SystemOperationLog
|
||||||
a := strings.TrimSpace(actionRows[i].Action)
|
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
if a != "" {
|
Filter("delete_time__isnull", true).
|
||||||
actSet[a] = struct{}{}
|
Filter("action__isnull", false).
|
||||||
}
|
Limit(1000).
|
||||||
}
|
All(&actionRows, "Action")
|
||||||
actions := make([]string, 0, len(actSet))
|
actSet := map[string]struct{}{}
|
||||||
for k := range actSet {
|
for i := range actionRows {
|
||||||
actions = append(actions, k)
|
a := strings.TrimSpace(actionRows[i].Action)
|
||||||
}
|
if a != "" {
|
||||||
|
actSet[a] = struct{}{}
|
||||||
c.Data["json"] = map[string]interface{}{
|
}
|
||||||
"code": 200,
|
}
|
||||||
"msg": "success",
|
actions := make([]string, 0, len(actSet))
|
||||||
"data": map[string]interface{}{
|
for k := range actSet {
|
||||||
"modules": modules,
|
actions = append(actions, k)
|
||||||
"actions": actions,
|
}
|
||||||
},
|
|
||||||
}
|
c.Data["json"] = map[string]interface{}{
|
||||||
_ = c.ServeJSON()
|
"code": 200,
|
||||||
}
|
"msg": "success",
|
||||||
|
"data": map[string]interface{}{
|
||||||
|
"modules": modules,
|
||||||
|
"actions": actions,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,351 +1,358 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"server/models"
|
"server/models"
|
||||||
"server/pkg/jwtutil"
|
"server/pkg/jwtutil"
|
||||||
|
"server/services"
|
||||||
"github.com/beego/beego/v2/client/orm"
|
|
||||||
beego "github.com/beego/beego/v2/server/web"
|
"github.com/beego/beego/v2/client/orm"
|
||||||
)
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
|
)
|
||||||
// PlatformOperationLogController 操作日志(yz_system_operation_log)
|
|
||||||
type PlatformOperationLogController struct {
|
// PlatformOperationLogController 操作日志(yz_system_operation_log)
|
||||||
beego.Controller
|
type PlatformOperationLogController struct {
|
||||||
}
|
beego.Controller
|
||||||
|
}
|
||||||
func (c *PlatformOperationLogController) platformClaims() (*jwtutil.Claims, error) {
|
|
||||||
auth := c.Ctx.Request.Header.Get("Authorization")
|
func (c *PlatformOperationLogController) platformClaims() (*jwtutil.Claims, error) {
|
||||||
if auth == "" {
|
auth := c.Ctx.Request.Header.Get("Authorization")
|
||||||
return nil, fmt.Errorf("未登录")
|
if auth == "" {
|
||||||
}
|
return nil, fmt.Errorf("未登录")
|
||||||
parts := strings.SplitN(auth, " ", 2)
|
}
|
||||||
if len(parts) != 2 || parts[0] != "Bearer" {
|
parts := strings.SplitN(auth, " ", 2)
|
||||||
return nil, fmt.Errorf("认证信息格式错误")
|
if len(parts) != 2 || parts[0] != "Bearer" {
|
||||||
}
|
return nil, fmt.Errorf("认证信息格式错误")
|
||||||
claims, err := jwtutil.ParseToken(parts[1])
|
}
|
||||||
if err != nil {
|
claims, err := jwtutil.ParseToken(parts[1])
|
||||||
return nil, fmt.Errorf("无效的token")
|
if err != nil {
|
||||||
}
|
return nil, fmt.Errorf("无效的token")
|
||||||
if claims.UserType != "platform" {
|
}
|
||||||
return nil, fmt.Errorf("无权访问")
|
if claims.UserType != "platform" {
|
||||||
}
|
return nil, fmt.Errorf("无权访问")
|
||||||
return claims, nil
|
}
|
||||||
}
|
return claims, nil
|
||||||
|
}
|
||||||
func (c *PlatformOperationLogController) jsonErr(httpStatus, bizCode int, msg string) {
|
|
||||||
c.Ctx.Output.SetStatus(httpStatus)
|
func (c *PlatformOperationLogController) jsonErr(httpStatus, bizCode int, msg string) {
|
||||||
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
c.Ctx.Output.SetStatus(httpStatus)
|
||||||
_ = c.ServeJSON()
|
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
||||||
}
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
// List GET /platform/operationLogs?page=1&pageSize=20&keyword=&module=&action=&status=&startTime=&endTime=
|
|
||||||
func (c *PlatformOperationLogController) List() {
|
// List GET /platform/operationLogs?page=1&pageSize=20&keyword=&module=&action=&status=&startTime=&endTime=
|
||||||
if _, err := c.platformClaims(); err != nil {
|
func (c *PlatformOperationLogController) List() {
|
||||||
c.jsonErr(401, 401, err.Error())
|
if _, err := c.platformClaims(); err != nil {
|
||||||
return
|
c.jsonErr(401, 401, err.Error())
|
||||||
}
|
return
|
||||||
|
}
|
||||||
page, _ := c.GetInt("page", 1)
|
|
||||||
pageSize, _ := c.GetInt("pageSize", 20)
|
page, _ := c.GetInt("page", 1)
|
||||||
if page < 1 {
|
pageSize, _ := c.GetInt("pageSize", 20)
|
||||||
page = 1
|
if page < 1 {
|
||||||
}
|
page = 1
|
||||||
if pageSize < 1 {
|
}
|
||||||
pageSize = 20
|
if pageSize < 1 {
|
||||||
}
|
pageSize = 20
|
||||||
if pageSize > 200 {
|
}
|
||||||
pageSize = 200
|
if pageSize > 200 {
|
||||||
}
|
pageSize = 200
|
||||||
|
}
|
||||||
keyword := strings.TrimSpace(c.GetString("keyword"))
|
|
||||||
module := strings.TrimSpace(c.GetString("module"))
|
keyword := strings.TrimSpace(c.GetString("keyword"))
|
||||||
action := strings.TrimSpace(c.GetString("action"))
|
module := strings.TrimSpace(c.GetString("module"))
|
||||||
statusStr := strings.TrimSpace(c.GetString("status"))
|
action := strings.TrimSpace(c.GetString("action"))
|
||||||
startTimeStr := strings.TrimSpace(c.GetString("startTime"))
|
statusStr := strings.TrimSpace(c.GetString("status"))
|
||||||
endTimeStr := strings.TrimSpace(c.GetString("endTime"))
|
startTimeStr := strings.TrimSpace(c.GetString("startTime"))
|
||||||
|
endTimeStr := strings.TrimSpace(c.GetString("endTime"))
|
||||||
qs := models.Orm.QueryTable(new(models.SystemOperationLog)).Filter("delete_time__isnull", true)
|
|
||||||
|
qs := models.Orm.QueryTable(new(models.SystemOperationLog)).Filter("delete_time__isnull", true)
|
||||||
// 条件拼装
|
|
||||||
cond := orm.NewCondition()
|
// 条件拼装
|
||||||
needCond := false
|
cond := orm.NewCondition()
|
||||||
|
needCond := false
|
||||||
if module != "" {
|
|
||||||
cond = cond.And("module", module)
|
if module != "" {
|
||||||
needCond = true
|
cond = cond.And("module", module)
|
||||||
}
|
needCond = true
|
||||||
if action != "" {
|
}
|
||||||
cond = cond.And("action", action)
|
if action != "" {
|
||||||
needCond = true
|
cond = cond.And("action", action)
|
||||||
}
|
needCond = true
|
||||||
if statusStr != "" {
|
}
|
||||||
if st, err := strconv.Atoi(statusStr); err == nil {
|
if statusStr != "" {
|
||||||
cond = cond.And("status", st)
|
if st, err := strconv.Atoi(statusStr); err == nil {
|
||||||
needCond = true
|
cond = cond.And("status", st)
|
||||||
}
|
needCond = true
|
||||||
}
|
}
|
||||||
if keyword != "" {
|
}
|
||||||
kw := orm.NewCondition().
|
if keyword != "" {
|
||||||
Or("module__icontains", keyword).
|
kw := orm.NewCondition().
|
||||||
Or("action__icontains", keyword).
|
Or("module__icontains", keyword).
|
||||||
Or("method__icontains", keyword).
|
Or("action__icontains", keyword).
|
||||||
Or("url__icontains", keyword).
|
Or("method__icontains", keyword).
|
||||||
Or("ip__icontains", keyword).
|
Or("url__icontains", keyword).
|
||||||
Or("user_agent__icontains", keyword)
|
Or("ip__icontains", keyword).
|
||||||
if uid, err := strconv.ParseUint(keyword, 10, 64); err == nil && uid > 0 {
|
Or("user_agent__icontains", keyword)
|
||||||
kw = kw.Or("user_id", uid)
|
if uid, err := strconv.ParseUint(keyword, 10, 64); err == nil && uid > 0 {
|
||||||
}
|
kw = kw.Or("user_id", uid)
|
||||||
cond = cond.AndCond(kw)
|
}
|
||||||
needCond = true
|
cond = cond.AndCond(kw)
|
||||||
}
|
needCond = true
|
||||||
if t, err := parseTimeFlexible(startTimeStr); err == nil && !t.IsZero() {
|
}
|
||||||
cond = cond.And("create_time__gte", t)
|
if t, err := parseTimeFlexible(startTimeStr); err == nil && !t.IsZero() {
|
||||||
needCond = true
|
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)
|
if t, err := parseTimeFlexible(endTimeStr); err == nil && !t.IsZero() {
|
||||||
needCond = true
|
cond = cond.And("create_time__lte", t)
|
||||||
}
|
needCond = true
|
||||||
|
}
|
||||||
if needCond {
|
|
||||||
qs = qs.SetCond(cond)
|
if needCond {
|
||||||
}
|
qs = qs.SetCond(cond)
|
||||||
|
}
|
||||||
total, err := qs.Count()
|
|
||||||
if err != nil {
|
total, err := qs.Count()
|
||||||
c.jsonErr(500, 500, "获取操作日志失败: "+err.Error())
|
if err != nil {
|
||||||
return
|
c.jsonErr(500, 500, "获取操作日志失败: "+err.Error())
|
||||||
}
|
return
|
||||||
|
}
|
||||||
var rows []models.SystemOperationLog
|
|
||||||
_, err = qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&rows)
|
var rows []models.SystemOperationLog
|
||||||
if err != nil {
|
_, err = qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&rows)
|
||||||
c.jsonErr(500, 500, "获取操作日志失败: "+err.Error())
|
if err != nil {
|
||||||
return
|
c.jsonErr(500, 500, "获取操作日志失败: "+err.Error())
|
||||||
}
|
return
|
||||||
|
}
|
||||||
list := make([]map[string]interface{}, 0, len(rows))
|
|
||||||
for i := range rows {
|
list := make([]map[string]interface{}, 0, len(rows))
|
||||||
item := map[string]interface{}{
|
for i := range rows {
|
||||||
"id": rows[i].ID,
|
userAccount, userName := services.OperationLogUser(rows[i].Tid, rows[i].UserID)
|
||||||
"tid": rows[i].Tid,
|
item := map[string]interface{}{
|
||||||
"user_id": rows[i].UserID,
|
"id": rows[i].ID,
|
||||||
"module": rows[i].Module,
|
"tid": rows[i].Tid,
|
||||||
"action": rows[i].Action,
|
"user_id": rows[i].UserID,
|
||||||
"method": rows[i].Method,
|
"user_account": userAccount,
|
||||||
"url": rows[i].URL,
|
"user_name": userName,
|
||||||
"ip": rows[i].IP,
|
"module": rows[i].Module,
|
||||||
"user_agent": rows[i].UserAgent,
|
"action": rows[i].Action,
|
||||||
"request_data": rows[i].RequestData,
|
"method": rows[i].Method,
|
||||||
"response_data": rows[i].ResponseData,
|
"url": rows[i].URL,
|
||||||
"status": rows[i].Status,
|
"ip": rows[i].IP,
|
||||||
"error_message": rows[i].ErrorMessage,
|
"user_agent": rows[i].UserAgent,
|
||||||
"execution_time": rows[i].ExecutionTime,
|
"request_data": rows[i].RequestData,
|
||||||
"create_time": rows[i].CreateTime.Format("2006-01-02 15:04:05"),
|
"response_data": rows[i].ResponseData,
|
||||||
"update_time": "",
|
"status": rows[i].Status,
|
||||||
}
|
"error_message": rows[i].ErrorMessage,
|
||||||
if rows[i].UpdateTime != nil {
|
"execution_time": rows[i].ExecutionTime,
|
||||||
item["update_time"] = rows[i].UpdateTime.Format("2006-01-02 15:04:05")
|
"create_time": rows[i].CreateTime.Format("2006-01-02 15:04:05"),
|
||||||
}
|
"update_time": "",
|
||||||
list = append(list, item)
|
}
|
||||||
}
|
if rows[i].UpdateTime != nil {
|
||||||
|
item["update_time"] = rows[i].UpdateTime.Format("2006-01-02 15:04:05")
|
||||||
c.Data["json"] = map[string]interface{}{
|
}
|
||||||
"code": 200,
|
list = append(list, item)
|
||||||
"msg": "success",
|
}
|
||||||
"data": map[string]interface{}{
|
|
||||||
"list": list,
|
c.Data["json"] = map[string]interface{}{
|
||||||
"total": total,
|
"code": 200,
|
||||||
},
|
"msg": "success",
|
||||||
}
|
"data": map[string]interface{}{
|
||||||
_ = c.ServeJSON()
|
"list": list,
|
||||||
}
|
"total": total,
|
||||||
|
},
|
||||||
// Detail GET /platform/operationLogs/:id
|
}
|
||||||
func (c *PlatformOperationLogController) Detail() {
|
_ = c.ServeJSON()
|
||||||
if _, err := c.platformClaims(); err != nil {
|
}
|
||||||
c.jsonErr(401, 401, err.Error())
|
|
||||||
return
|
// Detail GET /platform/operationLogs/:id
|
||||||
}
|
func (c *PlatformOperationLogController) Detail() {
|
||||||
idStr := c.Ctx.Input.Param(":id")
|
if _, err := c.platformClaims(); err != nil {
|
||||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
c.jsonErr(401, 401, err.Error())
|
||||||
if err != nil || id == 0 {
|
return
|
||||||
c.jsonErr(400, 400, "无效ID")
|
}
|
||||||
return
|
idStr := c.Ctx.Input.Param(":id")
|
||||||
}
|
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||||
var row models.SystemOperationLog
|
if err != nil || id == 0 {
|
||||||
err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
c.jsonErr(400, 400, "无效ID")
|
||||||
Filter("id", id).
|
return
|
||||||
Filter("delete_time__isnull", true).
|
}
|
||||||
One(&row)
|
var row models.SystemOperationLog
|
||||||
if err != nil {
|
err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
c.jsonErr(404, 404, "记录不存在")
|
Filter("id", id).
|
||||||
return
|
Filter("delete_time__isnull", true).
|
||||||
}
|
One(&row)
|
||||||
out := map[string]interface{}{
|
if err != nil {
|
||||||
"id": row.ID,
|
c.jsonErr(404, 404, "记录不存在")
|
||||||
"tid": row.Tid,
|
return
|
||||||
"user_id": row.UserID,
|
}
|
||||||
"module": row.Module,
|
userAccount, userName := services.OperationLogUser(row.Tid, row.UserID)
|
||||||
"action": row.Action,
|
out := map[string]interface{}{
|
||||||
"method": row.Method,
|
"id": row.ID,
|
||||||
"url": row.URL,
|
"tid": row.Tid,
|
||||||
"ip": row.IP,
|
"user_id": row.UserID,
|
||||||
"user_agent": row.UserAgent,
|
"user_account": userAccount,
|
||||||
"request_data": row.RequestData,
|
"user_name": userName,
|
||||||
"response_data": row.ResponseData,
|
"module": row.Module,
|
||||||
"status": row.Status,
|
"action": row.Action,
|
||||||
"error_message": row.ErrorMessage,
|
"method": row.Method,
|
||||||
"execution_time": row.ExecutionTime,
|
"url": row.URL,
|
||||||
"create_time": row.CreateTime.Format("2006-01-02 15:04:05"),
|
"ip": row.IP,
|
||||||
}
|
"user_agent": row.UserAgent,
|
||||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": out}
|
"request_data": row.RequestData,
|
||||||
_ = c.ServeJSON()
|
"response_data": row.ResponseData,
|
||||||
}
|
"status": row.Status,
|
||||||
|
"error_message": row.ErrorMessage,
|
||||||
// Delete DELETE /platform/operationLogs/:id
|
"execution_time": row.ExecutionTime,
|
||||||
func (c *PlatformOperationLogController) Delete() {
|
"create_time": row.CreateTime.Format("2006-01-02 15:04:05"),
|
||||||
if _, err := c.platformClaims(); err != nil {
|
}
|
||||||
c.jsonErr(401, 401, err.Error())
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": out}
|
||||||
return
|
_ = c.ServeJSON()
|
||||||
}
|
}
|
||||||
idStr := c.Ctx.Input.Param(":id")
|
|
||||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
// Delete DELETE /platform/operationLogs/:id
|
||||||
if err != nil || id == 0 {
|
func (c *PlatformOperationLogController) Delete() {
|
||||||
c.jsonErr(400, 400, "无效ID")
|
if _, err := c.platformClaims(); err != nil {
|
||||||
return
|
c.jsonErr(401, 401, err.Error())
|
||||||
}
|
return
|
||||||
now := time.Now()
|
}
|
||||||
n, err := models.Orm.QueryTable(new(models.SystemOperationLog)).
|
idStr := c.Ctx.Input.Param(":id")
|
||||||
Filter("id", id).
|
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||||
Filter("delete_time__isnull", true).
|
if err != nil || id == 0 {
|
||||||
Update(map[string]interface{}{"delete_time": now})
|
c.jsonErr(400, 400, "无效ID")
|
||||||
if err != nil {
|
return
|
||||||
c.jsonErr(500, 500, "删除失败: "+err.Error())
|
}
|
||||||
return
|
now := time.Now()
|
||||||
}
|
n, err := models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
if n == 0 {
|
Filter("id", id).
|
||||||
c.jsonErr(404, 404, "记录不存在")
|
Filter("delete_time__isnull", true).
|
||||||
return
|
Update(map[string]interface{}{"delete_time": now})
|
||||||
}
|
if err != nil {
|
||||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
|
c.jsonErr(500, 500, "删除失败: "+err.Error())
|
||||||
_ = c.ServeJSON()
|
return
|
||||||
}
|
}
|
||||||
|
if n == 0 {
|
||||||
type batchDeletePayload struct {
|
c.jsonErr(404, 404, "记录不存在")
|
||||||
IDs []uint64 `json:"ids"`
|
return
|
||||||
}
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "删除成功"}
|
||||||
// BatchDelete POST /platform/operationLogs/batchDelete
|
_ = c.ServeJSON()
|
||||||
func (c *PlatformOperationLogController) BatchDelete() {
|
}
|
||||||
if _, err := c.platformClaims(); err != nil {
|
|
||||||
c.jsonErr(401, 401, err.Error())
|
type batchDeletePayload struct {
|
||||||
return
|
IDs []uint64 `json:"ids"`
|
||||||
}
|
}
|
||||||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
|
||||||
if err != nil {
|
// BatchDelete POST /platform/operationLogs/batchDelete
|
||||||
c.jsonErr(400, 400, "参数错误")
|
func (c *PlatformOperationLogController) BatchDelete() {
|
||||||
return
|
if _, err := c.platformClaims(); err != nil {
|
||||||
}
|
c.jsonErr(401, 401, err.Error())
|
||||||
var p batchDeletePayload
|
return
|
||||||
if err := json.Unmarshal(raw, &p); err != nil {
|
}
|
||||||
c.jsonErr(400, 400, "参数错误")
|
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||||||
return
|
if err != nil {
|
||||||
}
|
c.jsonErr(400, 400, "参数错误")
|
||||||
if len(p.IDs) == 0 {
|
return
|
||||||
c.jsonErr(400, 400, "请选择要删除的日志")
|
}
|
||||||
return
|
var p batchDeletePayload
|
||||||
}
|
if err := json.Unmarshal(raw, &p); err != nil {
|
||||||
now := time.Now()
|
c.jsonErr(400, 400, "参数错误")
|
||||||
_, err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
return
|
||||||
Filter("id__in", p.IDs).
|
}
|
||||||
Filter("delete_time__isnull", true).
|
if len(p.IDs) == 0 {
|
||||||
Update(map[string]interface{}{"delete_time": now})
|
c.jsonErr(400, 400, "请选择要删除的日志")
|
||||||
if err != nil {
|
return
|
||||||
c.jsonErr(500, 500, "批量删除失败: "+err.Error())
|
}
|
||||||
return
|
now := time.Now()
|
||||||
}
|
_, err = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "批量删除成功"}
|
Filter("id__in", p.IDs).
|
||||||
_ = c.ServeJSON()
|
Filter("delete_time__isnull", true).
|
||||||
}
|
Update(map[string]interface{}{"delete_time": now})
|
||||||
|
if err != nil {
|
||||||
// Statistics GET /platform/operationLogs/statistics
|
c.jsonErr(500, 500, "批量删除失败: "+err.Error())
|
||||||
// 供前端筛选项:modules/actions
|
return
|
||||||
func (c *PlatformOperationLogController) Statistics() {
|
}
|
||||||
if _, err := c.platformClaims(); err != nil {
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "批量删除成功"}
|
||||||
c.jsonErr(401, 401, err.Error())
|
_ = c.ServeJSON()
|
||||||
return
|
}
|
||||||
}
|
|
||||||
|
// Statistics GET /platform/operationLogs/statistics
|
||||||
var moduleRows []models.SystemOperationLog
|
// 供前端筛选项:modules/actions
|
||||||
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
func (c *PlatformOperationLogController) Statistics() {
|
||||||
Filter("delete_time__isnull", true).
|
if _, err := c.platformClaims(); err != nil {
|
||||||
Filter("module__isnull", false).
|
c.jsonErr(401, 401, err.Error())
|
||||||
Limit(1000).
|
return
|
||||||
All(&moduleRows, "Module")
|
}
|
||||||
modSet := map[string]struct{}{}
|
|
||||||
for i := range moduleRows {
|
var moduleRows []models.SystemOperationLog
|
||||||
m := strings.TrimSpace(moduleRows[i].Module)
|
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
if m != "" {
|
Filter("delete_time__isnull", true).
|
||||||
modSet[m] = struct{}{}
|
Filter("module__isnull", false).
|
||||||
}
|
Limit(1000).
|
||||||
}
|
All(&moduleRows, "Module")
|
||||||
modules := make([]string, 0, len(modSet))
|
modSet := map[string]struct{}{}
|
||||||
for k := range modSet {
|
for i := range moduleRows {
|
||||||
modules = append(modules, k)
|
m := strings.TrimSpace(moduleRows[i].Module)
|
||||||
}
|
if m != "" {
|
||||||
|
modSet[m] = struct{}{}
|
||||||
var actionRows []models.SystemOperationLog
|
}
|
||||||
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
}
|
||||||
Filter("delete_time__isnull", true).
|
modules := make([]string, 0, len(modSet))
|
||||||
Filter("action__isnull", false).
|
for k := range modSet {
|
||||||
Limit(1000).
|
modules = append(modules, k)
|
||||||
All(&actionRows, "Action")
|
}
|
||||||
actSet := map[string]struct{}{}
|
|
||||||
for i := range actionRows {
|
var actionRows []models.SystemOperationLog
|
||||||
a := strings.TrimSpace(actionRows[i].Action)
|
_, _ = models.Orm.QueryTable(new(models.SystemOperationLog)).
|
||||||
if a != "" {
|
Filter("delete_time__isnull", true).
|
||||||
actSet[a] = struct{}{}
|
Filter("action__isnull", false).
|
||||||
}
|
Limit(1000).
|
||||||
}
|
All(&actionRows, "Action")
|
||||||
actions := make([]string, 0, len(actSet))
|
actSet := map[string]struct{}{}
|
||||||
for k := range actSet {
|
for i := range actionRows {
|
||||||
actions = append(actions, k)
|
a := strings.TrimSpace(actionRows[i].Action)
|
||||||
}
|
if a != "" {
|
||||||
|
actSet[a] = struct{}{}
|
||||||
c.Data["json"] = map[string]interface{}{
|
}
|
||||||
"code": 200,
|
}
|
||||||
"msg": "success",
|
actions := make([]string, 0, len(actSet))
|
||||||
"data": map[string]interface{}{
|
for k := range actSet {
|
||||||
"modules": modules,
|
actions = append(actions, k)
|
||||||
"actions": actions,
|
}
|
||||||
},
|
|
||||||
}
|
c.Data["json"] = map[string]interface{}{
|
||||||
_ = c.ServeJSON()
|
"code": 200,
|
||||||
}
|
"msg": "success",
|
||||||
|
"data": map[string]interface{}{
|
||||||
func parseTimeFlexible(s string) (time.Time, error) {
|
"modules": modules,
|
||||||
s = strings.TrimSpace(s)
|
"actions": actions,
|
||||||
if s == "" {
|
},
|
||||||
return time.Time{}, fmt.Errorf("empty")
|
}
|
||||||
}
|
_ = c.ServeJSON()
|
||||||
layouts := []string{
|
}
|
||||||
"2006-01-02 15:04:05",
|
|
||||||
"2006-01-02 15:04",
|
func parseTimeFlexible(s string) (time.Time, error) {
|
||||||
"2006-01-02",
|
s = strings.TrimSpace(s)
|
||||||
time.RFC3339,
|
if s == "" {
|
||||||
}
|
return time.Time{}, fmt.Errorf("empty")
|
||||||
for _, ly := range layouts {
|
}
|
||||||
if t, err := time.ParseInLocation(ly, s, time.Local); err == nil {
|
layouts := []string{
|
||||||
return t, nil
|
"2006-01-02 15:04:05",
|
||||||
}
|
"2006-01-02 15:04",
|
||||||
}
|
"2006-01-02",
|
||||||
return time.Time{}, fmt.Errorf("invalid time")
|
time.RFC3339,
|
||||||
}
|
}
|
||||||
|
for _, ly := range layouts {
|
||||||
|
if t, err := time.ParseInLocation(ly, s, time.Local); err == nil {
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return time.Time{}, fmt.Errorf("invalid time")
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import "server/models"
|
||||||
|
|
||||||
|
// OperationLogUser 根据操作日志的租户范围解析操作人信息。
|
||||||
|
// tid 为空或为 0 时,日志来自平台管理员;否则来自租户用户。
|
||||||
|
func OperationLogUser(tid *uint64, userID uint64) (account, name string) {
|
||||||
|
if userID == 0 {
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if tid != nil && *tid != 0 {
|
||||||
|
var user models.SystemTenantUser
|
||||||
|
if err := models.Orm.QueryTable(new(models.SystemTenantUser)).
|
||||||
|
Filter("tid", *tid).
|
||||||
|
Filter("uid", userID).
|
||||||
|
One(&user); err == nil {
|
||||||
|
if user.Account != nil {
|
||||||
|
account = *user.Account
|
||||||
|
}
|
||||||
|
if user.Name != nil {
|
||||||
|
name = *user.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return account, name
|
||||||
|
}
|
||||||
|
|
||||||
|
var user models.AdminUser
|
||||||
|
if err := models.Orm.QueryTable(new(models.AdminUser)).
|
||||||
|
Filter("id", userID).
|
||||||
|
One(&user); err == nil {
|
||||||
|
account = user.Account
|
||||||
|
if user.Name != nil {
|
||||||
|
name = *user.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return account, name
|
||||||
|
}
|
||||||
@@ -8,34 +8,29 @@ import (
|
|||||||
"server/models"
|
"server/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* findTenantByLoginName 根据租户简称、短名或编码查找租户。
|
|
||||||
*
|
|
||||||
* 当前表结构中 tenant_name 的业务含义就是“租户简称”,同时兼容
|
|
||||||
* tenant_short_name 和 tenant_code 两个历史/备用登录标识。
|
|
||||||
*/
|
|
||||||
func findTenantByLoginName(loginName string) (*models.SystemTenant, error) {
|
func findTenantByLoginName(loginName string) (*models.SystemTenant, error) {
|
||||||
loginName = strings.TrimSpace(loginName)
|
loginName = strings.TrimSpace(loginName)
|
||||||
if loginName == "" {
|
if loginName == "" {
|
||||||
return nil, orm.ErrNoRows
|
return nil, orm.ErrNoRows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qs := models.Orm.QueryTable(new(models.SystemTenant)).
|
||||||
|
Filter("status", 1).
|
||||||
|
Filter("delete_time__isnull", true)
|
||||||
|
|
||||||
// tenant_name 的业务含义是租户简称。使用 TRIM 兼容历史数据中字段值
|
|
||||||
// 前后存在空格的情况;参数通过 SetArgs 绑定,避免 SQL 注入。
|
|
||||||
tenant := &models.SystemTenant{}
|
tenant := &models.SystemTenant{}
|
||||||
query := `
|
err := qs.Filter("tenant_name", loginName).One(tenant)
|
||||||
SELECT id, tenant_code, tenant_name, tenant_short_name,
|
if err == nil {
|
||||||
contact_person, contact_phone, contact_email, address,
|
return tenant, nil
|
||||||
worktime, status, remark, create_time, update_time, delete_time
|
}
|
||||||
FROM yz_system_tenant
|
|
||||||
WHERE (TRIM(tenant_name) = TRIM(?) OR
|
tenant = &models.SystemTenant{}
|
||||||
TRIM(tenant_short_name) = TRIM(?) OR
|
err = models.Orm.QueryTable(new(models.SystemTenant)).
|
||||||
TRIM(tenant_code) = TRIM(?))
|
Filter("status", 1).
|
||||||
AND status <> 0
|
Filter("delete_time__isnull", true).
|
||||||
ORDER BY id ASC
|
Filter("tenant_code", loginName).
|
||||||
LIMIT 1`
|
One(tenant)
|
||||||
err := models.Orm.Raw(query).
|
|
||||||
SetArgs(loginName, loginName, loginName).
|
|
||||||
QueryRow(tenant)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user