fix: align admin behavior and Kratos integrations
This commit is contained in:
@@ -88,8 +88,8 @@ func (h *Announcement) Find(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *Announcement) List(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
|
||||
page, _ := strconv.Atoi(c.Query("page"))
|
||||
pageSize, _ := strconv.Atoi(c.Query("pageSize"))
|
||||
start, startErr := parseTime(c.Query("startCreatedAt"))
|
||||
end, endErr := parseTime(c.Query("endCreatedAt"))
|
||||
if startErr != nil || endErr != nil || (start == nil) != (end == nil) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"kra/internal/server/httpx"
|
||||
"kra/internal/service"
|
||||
@@ -28,7 +28,7 @@ func (h *API) List(c *gin.Context) {
|
||||
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: req.Page, PageSize: req.PageSize}, "获取成功")
|
||||
}
|
||||
func (h *API) All(c *gin.Context) {
|
||||
items, err := h.service.AllAPI(c.Request.Context())
|
||||
items, err := h.service.AllAPI(c.Request.Context(), true)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
@@ -41,11 +41,12 @@ func (h *API) Create(c *gin.Context) {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
if err := h.service.CreateAPIRequest(c.Request.Context(), &req); err != nil {
|
||||
created, err := h.service.CreateAPIRequest(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "创建失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, created, "创建成功")
|
||||
}
|
||||
func (h *API) Update(c *gin.Context) {
|
||||
var req dto.APIRequest
|
||||
@@ -97,28 +98,40 @@ func (h *API) Find(c *gin.Context) {
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"api": item}, "获取成功")
|
||||
}
|
||||
func (h *API) Groups(c *gin.Context) {
|
||||
items, err := h.service.AllAPI(c.Request.Context())
|
||||
items, err := h.service.AllAPI(c.Request.Context(), false)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
seen := map[string]bool{}
|
||||
groups := []string{}
|
||||
groupAPIMap := map[string]string{}
|
||||
for _, item := range items {
|
||||
if item.APIGroup != "" && !seen[item.APIGroup] {
|
||||
if !seen[item.APIGroup] {
|
||||
seen[item.APIGroup] = true
|
||||
groups = append(groups, item.APIGroup)
|
||||
}
|
||||
parts := strings.Split(item.Path, "/")
|
||||
if len(parts) > 1 {
|
||||
groupAPIMap[parts[1]] = item.APIGroup
|
||||
}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"groups": groups}, "获取成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"groups": groups, "apiGroupMap": groupAPIMap}, "获取成功")
|
||||
}
|
||||
func (h *API) Roles(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("apiId"), 10, 64)
|
||||
ids, err := h.service.APIRoleIDs(c.Request.Context(), uint(id))
|
||||
path, method := c.Query("path"), c.Query("method")
|
||||
if path == "" || method == "" {
|
||||
httpx.Fail(c, "API路径和请求方法不能为空")
|
||||
return
|
||||
}
|
||||
ids, err := h.service.APIRoleIDs(c.Request.Context(), path, method)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
ids = []uint{}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, ids, "获取成功")
|
||||
}
|
||||
func (h *API) SetRoles(c *gin.Context) {
|
||||
@@ -127,7 +140,11 @@ func (h *API) SetRoles(c *gin.Context) {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
if err := h.service.SetAPIRoles(c.Request.Context(), req.APIID, req.AuthorityIDs); err != nil {
|
||||
if req.Path == "" || req.Method == "" {
|
||||
httpx.Fail(c, "API路径和请求方法不能为空")
|
||||
return
|
||||
}
|
||||
if err := h.service.SetAPIRoles(c.Request.Context(), req.Path, req.Method, req.AuthorityIDs); err != nil {
|
||||
httpx.Fail(c, "设置失败")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"kra/internal/server/httpx"
|
||||
"kra/internal/service"
|
||||
@@ -15,8 +16,8 @@ type Audit struct{ service *service.AuditService }
|
||||
func NewAudit(service *service.AuditService) *Audit { return &Audit{service: service} }
|
||||
|
||||
func page(c *gin.Context) (int, int) {
|
||||
value, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
size, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
|
||||
value, _ := strconv.Atoi(c.Query("page"))
|
||||
size, _ := strconv.Atoi(c.Query("pageSize"))
|
||||
return value, size
|
||||
}
|
||||
func IDsFromQuery(c *gin.Context) []uint {
|
||||
@@ -37,8 +38,7 @@ func IDsFromQuery(c *gin.Context) []uint {
|
||||
func (h *Audit) Operations(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
status, _ := strconv.Atoi(c.Query("status"))
|
||||
userID, _ := strconv.ParseUint(c.Query("user_id"), 10, 64)
|
||||
items, total, err := h.service.OperationsFilter(c.Request.Context(), p, size, c.Query("path"), c.Query("method"), status, c.Query("ip"), uint(userID))
|
||||
items, total, err := h.service.OperationsFilter(c.Request.Context(), p, size, c.Query("path"), c.Query("method"), status)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
@@ -52,7 +52,7 @@ func (h *Audit) Operation(c *gin.Context) {
|
||||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"resysOperationRecord": item}, "查询成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"reSysOperationRecord": item}, "查询成功")
|
||||
}
|
||||
func (h *Audit) DeleteOperation(c *gin.Context) {
|
||||
var req dto.IDRequest
|
||||
@@ -81,7 +81,8 @@ func (h *Audit) DeleteOperations(c *gin.Context) {
|
||||
|
||||
func (h *Audit) Logins(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
items, total, err := h.service.LoginsFilter(c.Request.Context(), p, size, c.Query("username"), c.Query("ip"))
|
||||
status, _ := strconv.ParseBool(c.Query("status"))
|
||||
items, total, err := h.service.LoginsFilter(c.Request.Context(), p, size, c.Query("username"), status)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
@@ -216,11 +217,20 @@ func (h *Audit) Error(c *gin.Context) {
|
||||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"resysError": item}, "查询成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "查询成功")
|
||||
}
|
||||
func (h *Audit) Errors(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
items, total, err := h.service.ErrorsFilter(c.Request.Context(), p, size, c.Query("form"), c.Query("level"), c.Query("status"))
|
||||
createdAtRange := make([]time.Time, 0, 2)
|
||||
for _, raw := range c.QueryArray("createdAtRange[]") {
|
||||
value, parseErr := time.Parse(time.RFC3339, raw)
|
||||
if parseErr != nil {
|
||||
httpx.Fail(c, parseErr.Error())
|
||||
return
|
||||
}
|
||||
createdAtRange = append(createdAtRange, value)
|
||||
}
|
||||
items, total, err := h.service.ErrorsFilter(c.Request.Context(), p, size, c.Query("form"), c.Query("info"), createdAtRange)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
|
||||
@@ -92,6 +92,9 @@ func (h *Authority) Users(c *gin.Context) {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
ids = []uint{}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, ids, "获取成功")
|
||||
}
|
||||
func (h *Authority) SetDataScope(c *gin.Context) {
|
||||
@@ -113,5 +116,8 @@ func (h *Authority) DataScopeDepartments(c *gin.Context) {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
ids = []uint{}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, ids, "获取成功")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/server/httpx"
|
||||
"kra/internal/service"
|
||||
"kra/internal/service/dto"
|
||||
@@ -54,27 +55,35 @@ func (h *Dictionary) Delete(c *gin.Context) {
|
||||
}
|
||||
func (h *Dictionary) Find(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
item, err := h.service.Dictionary(c.Request.Context(), uint(id), c.Query("type"), true)
|
||||
var status *bool
|
||||
if raw, exists := c.GetQuery("status"); exists {
|
||||
value, parseErr := strconv.ParseBool(raw)
|
||||
if parseErr != nil {
|
||||
httpx.Fail(c, parseErr.Error())
|
||||
return
|
||||
}
|
||||
status = &value
|
||||
}
|
||||
item, err := h.service.Dictionary(c.Request.Context(), uint(id), c.Query("type"), status, true)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"reSysDictionary": item}, "查询成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"resysDictionary": item}, "查询成功")
|
||||
}
|
||||
func (h *Dictionary) List(details bool) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
items, total, err := h.service.Dictionaries(c.Request.Context(), p, size, c.Query("name"), c.Query("type"), details)
|
||||
items, _, err := h.service.Dictionaries(c.Request.Context(), 0, 0, c.Query("name"), "", details)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: p, PageSize: size}, "获取成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, items, "获取成功")
|
||||
}
|
||||
}
|
||||
func (h *Dictionary) Export(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
item, err := h.service.Dictionary(c.Request.Context(), uint(id), "", true)
|
||||
item, err := h.service.ExportDictionary(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "导出失败")
|
||||
return
|
||||
@@ -83,6 +92,13 @@ func (h *Dictionary) Export(c *gin.Context) {
|
||||
delete(item, "CreatedAt")
|
||||
delete(item, "UpdatedAt")
|
||||
delete(item, "DeletedAt")
|
||||
if details, ok := item["sysDictionaryDetails"].([]map[string]any); ok {
|
||||
for _, detail := range details {
|
||||
for _, key := range []string{"ID", "CreatedAt", "UpdatedAt", "DeletedAt", "sysDictionaryID", "parentID", "disabled", "children"} {
|
||||
delete(detail, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "导出成功")
|
||||
}
|
||||
func (h *Dictionary) Import(c *gin.Context) {
|
||||
@@ -146,7 +162,33 @@ func (h *Dictionary) FindDetail(c *gin.Context) {
|
||||
func (h *Dictionary) Details(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
dictionaryID, _ := strconv.ParseUint(c.Query("sysDictionaryID"), 10, 64)
|
||||
items, total, err := h.service.DictionaryDetails(c.Request.Context(), p, size, uint(dictionaryID), c.Query("label"), c.Query("value"))
|
||||
filter := biz.DictionaryDetailFilter{DictionaryID: uint(dictionaryID), Label: c.Query("label"), Value: c.Query("value")}
|
||||
if raw, exists := c.GetQuery("status"); exists {
|
||||
value, parseErr := strconv.ParseBool(raw)
|
||||
if parseErr != nil {
|
||||
httpx.Fail(c, parseErr.Error())
|
||||
return
|
||||
}
|
||||
filter.Status = &value
|
||||
}
|
||||
if raw, exists := c.GetQuery("parentID"); exists {
|
||||
value, parseErr := strconv.ParseUint(raw, 10, 64)
|
||||
if parseErr != nil {
|
||||
httpx.Fail(c, parseErr.Error())
|
||||
return
|
||||
}
|
||||
parentID := uint(value)
|
||||
filter.ParentID = &parentID
|
||||
}
|
||||
if raw, exists := c.GetQuery("level"); exists {
|
||||
value, parseErr := strconv.Atoi(raw)
|
||||
if parseErr != nil {
|
||||
httpx.Fail(c, parseErr.Error())
|
||||
return
|
||||
}
|
||||
filter.Level = &value
|
||||
}
|
||||
items, total, err := h.service.DictionaryDetails(c.Request.Context(), p, size, filter)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
|
||||
@@ -14,7 +14,7 @@ func NewEmail(service *service.EmailService) *Email { return &Email{service: ser
|
||||
|
||||
func (h *Email) Test(c *gin.Context) {
|
||||
if err := h.service.Test(c.Request.Context()); err != nil {
|
||||
httpx.Fail(c, "发送失败:"+err.Error())
|
||||
httpx.Fail(c, "发送失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "发送成功")
|
||||
@@ -22,12 +22,12 @@ func (h *Email) Test(c *gin.Context) {
|
||||
|
||||
func (h *Email) Send(c *gin.Context) {
|
||||
var req dto.SendEmailRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if err := h.service.Send(c.Request.Context(), req.To, req.Subject, req.Body); err != nil {
|
||||
httpx.Fail(c, "发送失败:"+err.Error())
|
||||
httpx.Fail(c, "发送失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "发送成功")
|
||||
|
||||
@@ -106,7 +106,13 @@ func (h *Export) Find(c *gin.Context) {
|
||||
}
|
||||
func (h *Export) List(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
items, total, err := h.service.TemplatesFilter(c.Request.Context(), p, size, c.Query("name"), c.Query("tableName"), c.Query("templateID"))
|
||||
start, startErr := parseTime(c.Query("startCreatedAt"))
|
||||
end, endErr := parseTime(c.Query("endCreatedAt"))
|
||||
if startErr != nil || endErr != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
items, total, err := h.service.TemplatesFilter(c.Request.Context(), p, size, c.Query("name"), c.Query("tableName"), c.Query("templateID"), start, end)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
|
||||
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/server/httpx"
|
||||
servermiddleware "kra/internal/server/middleware"
|
||||
"kra/internal/service"
|
||||
@@ -32,7 +33,7 @@ func (h *Media) Upload(c *gin.Context) {
|
||||
save := c.DefaultQuery("noSave", "0") == "0"
|
||||
item, err := h.service.Upload(c.Request.Context(), claims.ID, header.Filename, header.Header.Get("Content-Type"), category, opened, save)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "上传失败:"+err.Error())
|
||||
httpx.Fail(c, "上传文件失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"file": item}, "上传成功")
|
||||
@@ -44,7 +45,7 @@ func (h *Media) List(c *gin.Context) {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
items, total, err := h.service.MediaList(c.Request.Context(), req.Page, req.PageSize, req.Keyword, req.ClassID, req.Tag, req.UserID)
|
||||
items, total, err := h.service.MediaList(c.Request.Context(), biz.MediaFilter{Page: req.Page, PageSize: req.PageSize, Keyword: req.Keyword, CategoryID: req.ClassID, Tag: req.Tag, UserID: req.UserID, StartCreatedAt: req.StartCreatedAt, EndCreatedAt: req.EndCreatedAt, OrderKey: req.OrderKey, Desc: req.Desc})
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
@@ -58,10 +59,10 @@ func (h *Media) Delete(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
if err := h.service.Delete(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, "删除失败:"+err.Error())
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *Media) DeleteMany(c *gin.Context) {
|
||||
var req dto.IDsRequest
|
||||
@@ -79,7 +80,7 @@ func (h *Media) DeleteMany(c *gin.Context) {
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"failedIds": failed}, "部分文件删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "批量删除成功")
|
||||
}
|
||||
func (h *Media) Find(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("id"), 10, 64)
|
||||
@@ -88,7 +89,7 @@ func (h *Media) Find(c *gin.Context) {
|
||||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "获取成功")
|
||||
httpx.OKWithData(c, item)
|
||||
}
|
||||
func (h *Media) Rename(c *gin.Context) {
|
||||
var req dto.RenameMediaRequest
|
||||
@@ -100,7 +101,7 @@ func (h *Media) Rename(c *gin.Context) {
|
||||
httpx.Fail(c, "编辑失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "编辑成功")
|
||||
}
|
||||
func (h *Media) ImportURLs(c *gin.Context) {
|
||||
var req []dto.ImportMediaRequest
|
||||
@@ -108,16 +109,11 @@ func (h *Media) ImportURLs(c *gin.Context) {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
claims := servermiddleware.Claims(c)
|
||||
if claims == nil {
|
||||
httpx.Fail(c, "未登录")
|
||||
if err := h.service.ImportURLRequests(c.Request.Context(), req); err != nil {
|
||||
httpx.Fail(c, "导入URL失败")
|
||||
return
|
||||
}
|
||||
if err := h.service.ImportURLRequests(c.Request.Context(), claims.ID, req); err != nil {
|
||||
httpx.Fail(c, "导入失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "导入URL成功")
|
||||
}
|
||||
func (h *Media) Storage(c *gin.Context) {
|
||||
var req dto.StorageListRequest
|
||||
@@ -148,10 +144,10 @@ func (h *Media) SaveCategory(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
if err := h.service.SaveCategoryRequest(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
httpx.Fail(c, "创建/更新失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "创建/更新成功")
|
||||
}
|
||||
func (h *Media) DeleteCategory(c *gin.Context) {
|
||||
var req dto.IDRequest
|
||||
@@ -160,10 +156,10 @@ func (h *Media) DeleteCategory(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteCategory(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
|
||||
func (h *Media) InitUpload(c *gin.Context) {
|
||||
|
||||
@@ -15,12 +15,12 @@ type Menu struct{ service *service.MenuService }
|
||||
func NewMenu(service *service.MenuService) *Menu { return &Menu{service: service} }
|
||||
|
||||
func (h *Menu) List(c *gin.Context) {
|
||||
items, err := h.service.List(c.Request.Context())
|
||||
items, err := h.service.Tree(c.Request.Context())
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: int64(len(items)), Page: 1, PageSize: 999}, "获取成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, items, "获取成功")
|
||||
}
|
||||
|
||||
func (h *Menu) Tree(c *gin.Context) {
|
||||
@@ -119,7 +119,18 @@ func (h *Menu) RoleIDs(c *gin.Context) {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, ids, "获取成功")
|
||||
if ids == nil {
|
||||
ids = []uint{}
|
||||
}
|
||||
defaultIDs, err := h.service.DefaultRouterRoleIDs(c.Request.Context(), uint(id))
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
if defaultIDs == nil {
|
||||
defaultIDs = []uint{}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"authorityIds": ids, "defaultRouterAuthorityIds": defaultIDs}, "获取成功")
|
||||
}
|
||||
|
||||
func (h *Menu) SetRoles(c *gin.Context) {
|
||||
|
||||
@@ -28,27 +28,35 @@ func (h *Organization) ListDepartments(c *gin.Context) {
|
||||
}
|
||||
func (h *Organization) CreateDepartment(c *gin.Context) {
|
||||
var req dto.DepartmentRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if req.Name == "" {
|
||||
httpx.Fail(c, "部门名称不能为空")
|
||||
return
|
||||
}
|
||||
if err := h.service.CreateDepartment(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "创建失败")
|
||||
httpx.Fail(c, "创建失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, nil, "创建成功")
|
||||
}
|
||||
func (h *Organization) UpdateDepartment(c *gin.Context) {
|
||||
var req dto.DepartmentRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if req.ID == 0 {
|
||||
httpx.Fail(c, "部门ID不能为空")
|
||||
return
|
||||
}
|
||||
if err := h.service.UpdateDepartment(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "更新失败")
|
||||
httpx.Fail(c, "更新失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, nil, "更新成功")
|
||||
}
|
||||
func (h *Organization) DeleteDepartment(c *gin.Context) {
|
||||
var req dto.DeleteDepartmentRequest
|
||||
@@ -60,7 +68,7 @@ func (h *Organization) DeleteDepartment(c *gin.Context) {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, nil, "删除成功")
|
||||
}
|
||||
func (h *Organization) FindDepartment(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("id"), 10, 64)
|
||||
@@ -78,6 +86,9 @@ func (h *Organization) DepartmentUsers(c *gin.Context) {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
ids = []uint{}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, ids, "获取成功")
|
||||
}
|
||||
func (h *Organization) SetDepartmentUsers(c *gin.Context) {
|
||||
@@ -120,27 +131,35 @@ func (h *Organization) ListPositions(c *gin.Context) {
|
||||
}
|
||||
func (h *Organization) CreatePosition(c *gin.Context) {
|
||||
var req dto.PositionRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if req.Name == "" {
|
||||
httpx.Fail(c, "岗位名称不能为空")
|
||||
return
|
||||
}
|
||||
if err := h.service.CreatePosition(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "创建失败")
|
||||
httpx.Fail(c, "创建失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, nil, "创建成功")
|
||||
}
|
||||
func (h *Organization) UpdatePosition(c *gin.Context) {
|
||||
var req dto.PositionRequest
|
||||
if c.ShouldBindJSON(&req) != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
httpx.Fail(c, err.Error())
|
||||
return
|
||||
}
|
||||
if req.ID == 0 {
|
||||
httpx.Fail(c, "岗位ID不能为空")
|
||||
return
|
||||
}
|
||||
if err := h.service.UpdatePosition(c.Request.Context(), &req); err != nil {
|
||||
httpx.Fail(c, "更新失败")
|
||||
httpx.Fail(c, "更新失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, nil, "更新成功")
|
||||
}
|
||||
func (h *Organization) DeletePosition(c *gin.Context) {
|
||||
var req dto.DeletePositionRequest
|
||||
@@ -149,10 +168,10 @@ func (h *Organization) DeletePosition(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
if err := h.service.DeletePosition(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
httpx.Fail(c, "删除失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, nil, "删除成功")
|
||||
}
|
||||
func (h *Organization) FindPosition(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("id"), 10, 64)
|
||||
@@ -170,6 +189,9 @@ func (h *Organization) PositionUsers(c *gin.Context) {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
if ids == nil {
|
||||
ids = []uint{}
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, ids, "获取成功")
|
||||
}
|
||||
func (h *Organization) SetPositionUsers(c *gin.Context) {
|
||||
|
||||
@@ -77,7 +77,7 @@ func (h *Parameter) Find(c *gin.Context) {
|
||||
httpx.Fail(c, "查询失败")
|
||||
return
|
||||
}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"resysParams": item}, "查询成功")
|
||||
httpx.Write(c, httpx.CodeSuccess, item, "查询成功")
|
||||
}
|
||||
|
||||
func (h *Parameter) Get(c *gin.Context) {
|
||||
@@ -91,7 +91,13 @@ func (h *Parameter) Get(c *gin.Context) {
|
||||
|
||||
func (h *Parameter) List(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
items, total, err := h.service.ParametersFilter(c.Request.Context(), p, size, c.Query("name"), c.Query("key"))
|
||||
start, startErr := parseTime(c.Query("startCreatedAt"))
|
||||
end, endErr := parseTime(c.Query("endCreatedAt"))
|
||||
if startErr != nil || endErr != nil {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
items, total, err := h.service.ParametersFilter(c.Request.Context(), p, size, c.Query("name"), c.Query("key"), start, end)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
|
||||
@@ -2,11 +2,12 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"kra/internal/biz"
|
||||
"kra/internal/conf"
|
||||
"kra/internal/server/httpx"
|
||||
"kra/internal/service"
|
||||
@@ -18,23 +19,22 @@ import (
|
||||
)
|
||||
|
||||
type Public struct {
|
||||
system *service.SystemService
|
||||
settings *service.SettingsService
|
||||
audit *service.AuditService
|
||||
scheduler *worker.TaskScheduler
|
||||
store *captchaStore
|
||||
keyLong int
|
||||
imageWidth int
|
||||
imageHeight int
|
||||
system *service.SystemService
|
||||
settings *service.SettingsService
|
||||
audit *service.AuditService
|
||||
scheduler *worker.TaskScheduler
|
||||
runtime *conf.Runtime
|
||||
store *captchaStore
|
||||
}
|
||||
|
||||
func NewPublic(config *conf.AdminBackend, system *service.SystemService, settings *service.SettingsService, audit *service.AuditService, scheduler *worker.TaskScheduler) *Public {
|
||||
expiration := 3 * time.Minute
|
||||
func NewPublic(runtime *conf.Runtime, system *service.SystemService, settings *service.SettingsService, audit *service.AuditService, scheduler *worker.TaskScheduler) *Public {
|
||||
return &Public{system: system, settings: settings, audit: audit, scheduler: scheduler, runtime: runtime, store: &captchaStore{service: system, runtime: runtime}}
|
||||
}
|
||||
|
||||
func (h *Public) captchaConfig() (int, int, int) {
|
||||
keyLong, width, height := 6, 240, 80
|
||||
config := h.runtime.Admin()
|
||||
if config != nil && config.Captcha != nil {
|
||||
if config.Captcha.StoreExpiration != nil {
|
||||
expiration = config.Captcha.StoreExpiration.AsDuration()
|
||||
}
|
||||
if config.Captcha.KeyLong > 0 {
|
||||
keyLong = int(config.Captcha.KeyLong)
|
||||
}
|
||||
@@ -45,23 +45,18 @@ func NewPublic(config *conf.AdminBackend, system *service.SystemService, setting
|
||||
height = int(config.Captcha.ImgHeight)
|
||||
}
|
||||
}
|
||||
return &Public{system: system, settings: settings, audit: audit, scheduler: scheduler, store: &captchaStore{service: system, expiration: expiration}, keyLong: keyLong, imageWidth: width, imageHeight: height}
|
||||
return keyLong, width, height
|
||||
}
|
||||
|
||||
func (h *Public) Captcha(c *gin.Context) {
|
||||
keyLong, width, height := h.keyLong, h.imageWidth, h.imageHeight
|
||||
keyLong, width, height := h.captchaConfig()
|
||||
security, _ := h.settings.CurrentSecurity(c.Request.Context())
|
||||
openCaptcha := true
|
||||
if security != nil {
|
||||
keyLong, width, height = security.KeyLong, security.ImgWidth, security.ImgHeight
|
||||
if security.CaptchaOpen > 0 {
|
||||
failures, _ := cachedInt(c.Request.Context(), h.system, "login:fail:"+c.ClientIP())
|
||||
openCaptcha = failures >= security.CaptchaOpen
|
||||
}
|
||||
}
|
||||
if !openCaptcha {
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"captchaId": "", "picPath": "", "captchaLength": keyLong, "openCaptcha": false}, "验证码获取成功")
|
||||
return
|
||||
ttl := time.Duration(security.CaptchaTimeout) * time.Second
|
||||
failures, _ := ensureLoginIPCounter(c.Request.Context(), h.system, c.ClientIP(), ttl)
|
||||
openCaptcha = security.CaptchaOpen == 0 || failures > security.CaptchaOpen
|
||||
}
|
||||
driver := base64Captcha.NewDriverDigit(height, width, keyLong, 0.7, 80)
|
||||
id, picture, _, err := base64Captcha.NewCaptcha(driver, h.store).Generate()
|
||||
@@ -81,42 +76,71 @@ func (h *Public) Login(c *gin.Context) {
|
||||
security, _ := h.settings.CurrentSecurity(c.Request.Context())
|
||||
if security != nil && security.LockEnable {
|
||||
if _, locked, _ := h.system.CacheGet(c.Request.Context(), "login:lock:"+req.Username); locked {
|
||||
httpx.Fail(c, "账户已锁定,请稍后重试")
|
||||
httpx.Fail(c, "账号已锁定,请 "+strconv.Itoa(security.LockDuration)+" 分钟后再试")
|
||||
_ = h.audit.RecordLoginRequest(c.Request.Context(), &dto.LoginLogRequest{Username: req.Username, IP: c.ClientIP(), Status: false, ErrorMessage: "账号已锁定", Agent: c.Request.UserAgent()})
|
||||
return
|
||||
}
|
||||
}
|
||||
requireCaptcha := security == nil || security.CaptchaOpen == 0
|
||||
if security != nil && security.CaptchaOpen > 0 {
|
||||
failures, _ := cachedInt(c.Request.Context(), h.system, "login:fail:"+c.ClientIP())
|
||||
requireCaptcha = failures >= security.CaptchaOpen
|
||||
ipTTL := time.Hour
|
||||
if security != nil {
|
||||
if security.CaptchaTimeout > 0 {
|
||||
ipTTL = time.Duration(security.CaptchaTimeout) * time.Second
|
||||
}
|
||||
failures, _ := ensureLoginIPCounter(c.Request.Context(), h.system, c.ClientIP(), ipTTL)
|
||||
requireCaptcha = security.CaptchaOpen == 0 || failures > security.CaptchaOpen
|
||||
}
|
||||
if requireCaptcha && (req.CaptchaID == "" || req.Captcha == "" || !h.store.Verify(req.CaptchaID, req.Captcha, true)) {
|
||||
_, _ = h.system.CacheIncrement(c.Request.Context(), c.ClientIP(), ipTTL)
|
||||
_ = h.audit.RecordLoginRequest(c.Request.Context(), &dto.LoginLogRequest{Username: req.Username, IP: c.ClientIP(), Status: false, ErrorMessage: "验证码错误", Agent: c.Request.UserAgent()})
|
||||
httpx.Fail(c, "验证码错误")
|
||||
return
|
||||
}
|
||||
result, err := h.system.Login(c.Request.Context(), req.Username, req.Password)
|
||||
if err != nil {
|
||||
_ = h.audit.RecordLoginRequest(c.Request.Context(), &dto.LoginLogRequest{Username: req.Username, IP: c.ClientIP(), Status: false, ErrorMessage: "用户名不存在或者密码错误", Agent: c.Request.UserAgent()})
|
||||
ttl := time.Hour
|
||||
if security != nil && security.CaptchaTimeout > 0 {
|
||||
ttl = time.Duration(security.CaptchaTimeout) * time.Second
|
||||
_, _ = h.system.CacheIncrement(c.Request.Context(), c.ClientIP(), ipTTL)
|
||||
if errors.Is(err, biz.ErrUserDisabled) {
|
||||
_ = h.audit.RecordLoginRequest(c.Request.Context(), &dto.LoginLogRequest{Username: req.Username, IP: c.ClientIP(), Status: false, ErrorMessage: "用户被禁止登录", Agent: c.Request.UserAgent()})
|
||||
httpx.Fail(c, "用户被禁止登录")
|
||||
return
|
||||
}
|
||||
failures, _ := incrementCached(c.Request.Context(), h.system, "login:fail:"+c.ClientIP(), ttl)
|
||||
if security != nil && security.LockEnable && failures >= security.LockThreshold {
|
||||
_ = h.system.CacheSet(c.Request.Context(), "login:lock:"+req.Username, "1", time.Duration(security.LockDuration)*time.Minute)
|
||||
_ = h.audit.RecordLoginRequest(c.Request.Context(), &dto.LoginLogRequest{Username: req.Username, IP: c.ClientIP(), Status: false, ErrorMessage: "用户名不存在或者密码错误", Agent: c.Request.UserAgent()})
|
||||
if security != nil && security.LockEnable {
|
||||
lockTTL := time.Duration(security.LockDuration) * time.Minute
|
||||
failures, _ := h.system.CacheIncrement(c.Request.Context(), "login:fail:"+req.Username, lockTTL)
|
||||
if int(failures) >= security.LockThreshold {
|
||||
_ = h.system.CacheSet(c.Request.Context(), "login:lock:"+req.Username, "1", lockTTL)
|
||||
}
|
||||
}
|
||||
httpx.Fail(c, "用户名不存在或者密码错误")
|
||||
return
|
||||
}
|
||||
userID, _ := result.User["ID"].(uint)
|
||||
_ = h.audit.RecordLoginRequest(c.Request.Context(), &dto.LoginLogRequest{Username: req.Username, IP: c.ClientIP(), Status: true, Agent: c.Request.UserAgent(), UserID: userID})
|
||||
_ = h.system.CacheDelete(c.Request.Context(), "login:fail:"+c.ClientIP())
|
||||
_ = h.system.CacheDelete(c.Request.Context(), "login:fail:"+req.Username)
|
||||
_ = h.system.CacheDelete(c.Request.Context(), "login:lock:"+req.Username)
|
||||
maxAge := int(time.Until(time.UnixMilli(result.ExpiresAt)).Seconds())
|
||||
http.SetCookie(c.Writer, &http.Cookie{Name: "x-token", Value: result.Token, Path: "/", MaxAge: maxAge, HttpOnly: true, SameSite: http.SameSiteStrictMode})
|
||||
httpx.SetTokenCookie(c, result.Token, maxAge)
|
||||
httpx.Write(c, httpx.CodeSuccess, result, "登录成功")
|
||||
}
|
||||
|
||||
func ensureLoginIPCounter(ctx context.Context, system *service.SystemService, ip string, expiration time.Duration) (int, error) {
|
||||
value, exists, err := system.CacheGet(ctx, ip)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if exists {
|
||||
return strconv.Atoi(value)
|
||||
}
|
||||
if expiration <= 0 {
|
||||
expiration = time.Hour
|
||||
}
|
||||
if err = system.CacheSet(ctx, ip, "1", expiration); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
func (h *Public) CheckDatabase(c *gin.Context) {
|
||||
initialized, err := h.system.IsInitialized(c.Request.Context())
|
||||
if err != nil {
|
||||
@@ -163,27 +187,19 @@ func (h *Public) InitializeDatabase(engine *gin.Engine) gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func cachedInt(ctx context.Context, system *service.SystemService, key string) (int, error) {
|
||||
value, ok, err := system.CacheGet(ctx, key)
|
||||
if err != nil || !ok {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.Atoi(value)
|
||||
}
|
||||
|
||||
func incrementCached(ctx context.Context, system *service.SystemService, key string, ttl time.Duration) (int, error) {
|
||||
value, err := system.CacheIncrement(ctx, key, ttl)
|
||||
return int(value), err
|
||||
}
|
||||
|
||||
type captchaStore struct {
|
||||
service *service.SystemService
|
||||
expiration time.Duration
|
||||
service *service.SystemService
|
||||
runtime *conf.Runtime
|
||||
}
|
||||
|
||||
func (s *captchaStore) key(id string) string { return "captcha:" + id }
|
||||
func (s *captchaStore) Set(id, value string) error {
|
||||
return s.service.CacheSet(context.Background(), s.key(id), value, s.expiration)
|
||||
expiration := 3 * time.Minute
|
||||
config := s.runtime.Admin()
|
||||
if config != nil && config.Captcha != nil && config.Captcha.StoreExpiration != nil {
|
||||
expiration = config.Captcha.StoreExpiration.AsDuration()
|
||||
}
|
||||
return s.service.CacheSet(context.Background(), s.key(id), value, expiration)
|
||||
}
|
||||
func (s *captchaStore) Get(id string, clear bool) string {
|
||||
value, ok, err := s.service.CacheGet(context.Background(), s.key(id))
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"kra/internal/server/httpx"
|
||||
"kra/internal/service"
|
||||
|
||||
@@ -21,6 +19,6 @@ func (h *Session) Logout(c *gin.Context) {
|
||||
httpx.Fail(c, "退出失败")
|
||||
return
|
||||
}
|
||||
http.SetCookie(c.Writer, &http.Cookie{Name: "x-token", Value: "", Path: "/", MaxAge: -1, HttpOnly: true})
|
||||
httpx.SetTokenCookie(c, "", -1)
|
||||
httpx.OK(c)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package handler
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"kra/internal/server/httpx"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/shirou/gopsutil/v4/cpu"
|
||||
"github.com/shirou/gopsutil/v4/disk"
|
||||
"github.com/shirou/gopsutil/v4/mem"
|
||||
)
|
||||
|
||||
@@ -78,24 +78,31 @@ func (h *SystemConfig) Reload(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *SystemConfig) ServerInfo(c *gin.Context) {
|
||||
cpuPercent, _ := cpu.Percent(200*time.Millisecond, false)
|
||||
memory, _ := mem.VirtualMemory()
|
||||
disk := []gin.H{}
|
||||
var stat syscall.Statfs_t
|
||||
if syscall.Statfs(".", &stat) == nil {
|
||||
total := uint64(stat.Blocks) * uint64(stat.Bsize)
|
||||
free := uint64(stat.Bavail) * uint64(stat.Bsize)
|
||||
used := total - free
|
||||
percent := 0
|
||||
if total > 0 {
|
||||
percent = int(used * 100 / total)
|
||||
physicalCores, err := cpu.Counts(false)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
cpuPercent, err := cpu.Percent(200*time.Millisecond, true)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
memory, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
diskInfo := make([]gin.H, 0)
|
||||
for _, mountPoint := range h.system.DiskMountPoints() {
|
||||
usage, usageErr := disk.Usage(mountPoint)
|
||||
if usageErr != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
}
|
||||
disk = append(disk, gin.H{"mountPoint": ".", "usedMb": used / 1024 / 1024, "usedGb": used / 1024 / 1024 / 1024, "totalMb": total / 1024 / 1024, "totalGb": total / 1024 / 1024 / 1024, "usedPercent": percent})
|
||||
diskInfo = append(diskInfo, gin.H{"mountPoint": mountPoint, "usedMb": usage.Used / 1024 / 1024, "usedGb": usage.Used / 1024 / 1024 / 1024, "totalMb": usage.Total / 1024 / 1024, "totalGb": usage.Total / 1024 / 1024 / 1024, "usedPercent": int(usage.UsedPercent)})
|
||||
}
|
||||
usedMB, totalMB, memoryPercent := uint64(0), uint64(0), float64(0)
|
||||
if memory != nil {
|
||||
usedMB, totalMB, memoryPercent = memory.Used/1024/1024, memory.Total/1024/1024, memory.UsedPercent
|
||||
}
|
||||
server := gin.H{"os": gin.H{"goos": runtime.GOOS, "numCpu": runtime.NumCPU(), "compiler": runtime.Compiler, "goVersion": runtime.Version(), "numGoroutine": runtime.NumGoroutine()}, "cpu": gin.H{"cpus": cpuPercent, "cores": runtime.NumCPU()}, "ram": gin.H{"usedMb": usedMB, "totalMb": totalMB, "usedPercent": memoryPercent}, "disk": disk}
|
||||
usedMB, totalMB, memoryPercent := memory.Used/1024/1024, memory.Total/1024/1024, int(memory.UsedPercent)
|
||||
server := gin.H{"os": gin.H{"goos": runtime.GOOS, "numCpu": runtime.NumCPU(), "compiler": runtime.Compiler, "goVersion": runtime.Version(), "numGoroutine": runtime.NumGoroutine()}, "cpu": gin.H{"cpus": cpuPercent, "cores": physicalCores}, "ram": gin.H{"usedMb": usedMB, "totalMb": totalMB, "usedPercent": memoryPercent}, "disk": diskInfo}
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{"server": server}, "获取成功")
|
||||
}
|
||||
|
||||
@@ -103,8 +103,8 @@ func (h *Task) Trigger(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *Task) List(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
size, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
|
||||
page, _ := strconv.Atoi(c.Query("page"))
|
||||
size, _ := strconv.Atoi(c.Query("pageSize"))
|
||||
var enabled *bool
|
||||
if raw := c.Query("enabled"); raw != "" {
|
||||
value, _ := strconv.ParseBool(raw)
|
||||
@@ -119,8 +119,8 @@ func (h *Task) List(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *Task) Logs(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
size, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
|
||||
page, _ := strconv.Atoi(c.Query("page"))
|
||||
size, _ := strconv.Atoi(c.Query("pageSize"))
|
||||
taskID, _ := strconv.ParseUint(c.Query("taskId"), 10, 64)
|
||||
items, total, err := h.service.Logs(c.Request.Context(), page, size, uint(taskID), c.Query("status"))
|
||||
if err != nil {
|
||||
@@ -144,6 +144,8 @@ func (h *Task) AlertStream(c *gin.Context) {
|
||||
httpx.Fail(c, "SSE 不受支持")
|
||||
return
|
||||
}
|
||||
// Remove the normal server deadline for long-lived SSE connections.
|
||||
_ = http.NewResponseController(c.Writer).SetWriteDeadline(time.Time{})
|
||||
events := h.scheduler.Subscribe()
|
||||
defer h.scheduler.Unsubscribe(events)
|
||||
ticker := time.NewTicker(20 * time.Second)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -69,8 +68,8 @@ func (h *User) UpdateSelf(c *gin.Context) {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
value := &dto.UserRequest{ID: claims.ID, NickName: req.NickName, HeaderImg: req.HeaderImg, Phone: req.Phone, Email: req.Email, Enable: 1}
|
||||
if err := h.service.UpdateUserRequest(c.Request.Context(), value); err != nil {
|
||||
value := service.UserInput{ID: claims.ID, NickName: req.NickName, HeaderImg: req.HeaderImg, Phone: req.Phone, Email: req.Email, Enable: req.Enable}
|
||||
if err := h.service.UpdateSelfUser(c.Request.Context(), value); err != nil {
|
||||
httpx.Fail(c, "修改失败")
|
||||
return
|
||||
}
|
||||
@@ -83,6 +82,11 @@ func (h *User) Delete(c *gin.Context) {
|
||||
httpx.Fail(c, "参数错误")
|
||||
return
|
||||
}
|
||||
claims := middleware.Claims(c)
|
||||
if claims != nil && claims.ID == req.ID {
|
||||
httpx.Fail(c, "删除失败, 无法删除自己。")
|
||||
return
|
||||
}
|
||||
if err := h.service.DeleteUser(c.Request.Context(), req.ID); err != nil {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
@@ -159,7 +163,7 @@ func (h *User) SwitchAuthority(c *gin.Context) {
|
||||
c.Header("new-token", login.Token)
|
||||
c.Header("new-expires-at", strconv.FormatInt(login.ExpiresAt/1000, 10))
|
||||
maxAge := int(time.Until(time.UnixMilli(login.ExpiresAt)).Seconds())
|
||||
http.SetCookie(c.Writer, &http.Cookie{Name: "x-token", Value: login.Token, Path: "/", MaxAge: maxAge, HttpOnly: true, SameSite: http.SameSiteStrictMode})
|
||||
httpx.SetTokenCookie(c, login.Token, maxAge)
|
||||
httpx.OK(c)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ func (h *Version) Delete(c *gin.Context) {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
|
||||
}
|
||||
func (h *Version) DeleteMany(c *gin.Context) {
|
||||
raw := c.QueryArray("IDs[]")
|
||||
@@ -36,7 +36,7 @@ func (h *Version) DeleteMany(c *gin.Context) {
|
||||
httpx.Fail(c, "删除失败")
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "批量删除成功")
|
||||
}
|
||||
func (h *Version) Find(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
@@ -49,7 +49,16 @@ func (h *Version) Find(c *gin.Context) {
|
||||
}
|
||||
func (h *Version) List(c *gin.Context) {
|
||||
p, size := page(c)
|
||||
items, total, err := h.service.Versions(c.Request.Context(), p, size, c.Query("versionName"), c.Query("versionCode"))
|
||||
createdAtRange := make([]*time.Time, 0, 2)
|
||||
for _, raw := range c.QueryArray("createdAtRange[]") {
|
||||
value, parseErr := parseTime(raw)
|
||||
if parseErr != nil {
|
||||
httpx.Fail(c, parseErr.Error())
|
||||
return
|
||||
}
|
||||
createdAtRange = append(createdAtRange, value)
|
||||
}
|
||||
items, total, err := h.service.Versions(c.Request.Context(), p, size, c.Query("versionName"), c.Query("versionCode"), createdAtRange)
|
||||
if err != nil {
|
||||
httpx.Fail(c, "获取失败")
|
||||
return
|
||||
@@ -66,7 +75,7 @@ func (h *Version) Export(c *gin.Context) {
|
||||
httpx.Fail(c, "创建发版失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "创建发版成功")
|
||||
}
|
||||
func (h *Version) Download(c *gin.Context) {
|
||||
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
|
||||
@@ -89,5 +98,5 @@ func (h *Version) Import(c *gin.Context) {
|
||||
httpx.Fail(c, "导入失败:"+err.Error())
|
||||
return
|
||||
}
|
||||
httpx.OK(c)
|
||||
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "导入成功")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user