refactor: change agent cloud data permission to cloud variables only

- Rename permission from '查看云端数据' to '查看云端变量'
- Remove cloud constants API and page for agents
- Add cloud variable records API for agents (stream type)
- Add agent cloud-variables page with full variable details
- Add agent cloud-variable records page (read-only)
- Update navigation from cloud-data to cloud-variables
- Update i18n keys: cloudData -> cloudVariables
- Backend returns var_type, default_value, max_records etc.
- Records page supports dynamic columns and date filtering
This commit is contained in:
2026-05-11 08:05:40 +08:00
parent 6dcb5cde02
commit 3cea807353
8 changed files with 871 additions and 406 deletions
+89 -51
View File
@@ -1,6 +1,7 @@
package agent
import (
"encoding/json"
"fmt"
"math/rand"
"sort"
@@ -26,7 +27,7 @@ func SetupAgentRoutes(r *gin.RouterGroup) {
r.PUT("/profile", handleUpdateProfile)
r.GET("/cards/export", handleExportCards)
r.GET("/cloud-variables", handleGetCloudVariables)
r.GET("/cloud-constants", handleGetCloudConstants)
r.GET("/cloud-variables/:id/records", handleGetCloudVariableRecords)
}
func handleGetStats(c *gin.Context) {
@@ -778,7 +779,7 @@ func handleGetCloudVariables(c *gin.Context) {
}
if !agent.CanViewCloudData {
response.Error(c, 403, "无权查看云端数据")
response.Error(c, 403, "无权查看云端变量")
return
}
@@ -821,14 +822,18 @@ func handleGetCloudVariables(c *gin.Context) {
appName = appMap[*v.AppID]
}
result = append(result, gin.H{
"id": v.ID,
"name": v.Key,
"app_id": v.AppID,
"app_name": appName,
"scope": v.Scope,
"status": v.Status,
"description": v.Description,
"created_at": v.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
"id": v.ID,
"key": v.Key,
"app_id": v.AppID,
"application_name": appName,
"default_value": v.DefaultValue,
"var_type": v.VarType,
"max_records": v.MaxRecords,
"scope": v.Scope,
"write_permission": v.WritePermission,
"status": v.Status,
"description": v.Description,
"created_at": v.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
})
}
@@ -838,7 +843,7 @@ func handleGetCloudVariables(c *gin.Context) {
})
}
func handleGetCloudConstants(c *gin.Context) {
func handleGetCloudVariableRecords(c *gin.Context) {
userID := c.GetUint("user_id")
var agent model.User
@@ -848,62 +853,95 @@ func handleGetCloudConstants(c *gin.Context) {
}
if !agent.CanViewCloudData {
response.Error(c, 403, "无权查看云端数据")
response.Error(c, 403, "无权查看云端变量")
return
}
variableID := c.Param("id")
var variable model.CloudVariable
if err := database.DB.First(&variable, variableID).Error; err != nil {
response.Error(c, 404, "云端变量不存在")
return
}
var agentApps []model.AgentApplication
database.DB.Where("agent_id = ?", userID).Find(&agentApps)
appIDs := make([]uint, 0)
appIDs := make(map[uint]bool)
for _, app := range agentApps {
appIDs = append(appIDs, app.ApplicationID)
appIDs[app.ApplicationID] = true
}
if len(appIDs) == 0 {
response.Success(c, gin.H{
"constants": []interface{}{},
"total": 0,
})
if variable.AppID == nil || !appIDs[*variable.AppID] {
response.Error(c, 403, "无权查看该变量的记录")
return
}
appIDFilter := c.Query("app_id")
var constants []model.CloudConstant
query := database.DB.Where("app_id IN ?", appIDs)
if appIDFilter != "" {
if aid, err := strconv.ParseUint(appIDFilter, 10, 32); err == nil {
query = database.DB.Where("app_id = ?", uint(aid))
}
}
query.Find(&constants)
appMap := make(map[uint]string)
var apps []model.Application
database.DB.Where("id IN ?", appIDs).Find(&apps)
for _, app := range apps {
appMap[app.ID] = app.Name
if variable.VarType != "stream" {
response.Error(c, 400, "该变量不是记录类型")
return
}
result := make([]gin.H, 0)
for _, c := range constants {
appName := ""
if c.AppID != nil {
appName = appMap[*c.AppID]
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 20
}
startDate := c.Query("start_date")
endDate := c.Query("end_date")
var total int64
query := database.DB.Model(&model.CloudVariableRecord{}).Where("cloud_variable_id = ?", variable.ID)
if startDate != "" {
query = query.Where("created_at >= ?", startDate+" 00:00:00")
}
if endDate != "" {
query = query.Where("created_at <= ?", endDate+" 23:59:59")
}
query.Count(&total)
var records []model.CloudVariableRecord
offset := (page - 1) * pageSize
if err := query.Order("created_at DESC").Limit(pageSize).Offset(offset).Find(&records).Error; err != nil {
response.Error(c, 500, "获取记录失败")
return
}
result := make([]gin.H, len(records))
for i, r := range records {
var parsedData interface{}
if r.Data != "" {
json.Unmarshal([]byte(r.Data), &parsedData)
}
result = append(result, gin.H{
"id": c.ID,
"name": c.Key,
"app_id": c.AppID,
"app_name": appName,
"value": c.Value,
"status": c.Status,
"description": c.Description,
"created_at": c.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
})
if parsedData == nil && r.Data != "" {
parsedData = r.Data
}
record := gin.H{
"id": r.ID,
"data": parsedData,
"created_at": r.CreatedAt,
}
if r.AppUserID != nil {
record["user_id"] = r.AppUserID
var appUser model.AppUser
if err := database.DB.Select("id, username").First(&appUser, *r.AppUserID).Error; err == nil {
record["user"] = gin.H{
"id": appUser.ID,
"username": appUser.Username,
}
}
}
result[i] = record
}
response.Success(c, gin.H{
"constants": result,
"total": len(result),
"records": result,
"total": total,
"page": page,
"page_size": pageSize,
"total_pages": (total + int64(pageSize) - 1) / int64(pageSize),
})
}