feat: 云账号创建表单 — 修复凭证反序列化bug + 添加账号弹窗

- 后端: 重构 CreateCloudAccount 用独立 createCloudAccountRequest struct,
  修复 AccessKey/SecretKey 因 json:"-" 导致反序列化被跳过、凭证永远为空的 bug (Go Pitfall #8)
- 前端: 添加账号按钮接入 Dialog 表单 (名称/云平台/AccessKey/SecretKey/月费用/状态),
  移除无 handler 的刷新/编辑按钮,新增名称必填校验
This commit is contained in:
attacker committed 2026-06-14 07:05:19 +08:00
1 parent 5db69e8abc
commit 01a9bebb0c
3 files changed
+223 -14

No files matched your search

+36 -3
View File
@@ -3,6 +3,7 @@ package handlers
import (
"net/http"
"strconv"
"strings"
"ezops/internal/models"
@@ -401,6 +402,16 @@ func (h *CloudAccountHandler) ListCloudAccounts(c *gin.Context) {
})
}
// createCloudAccountRequest 创建云账号请求(独立 request struct,避免 CloudAccount.AccessKey/SecretKey 的 json:"-" 导致无法反序列化)
type createCloudAccountRequest struct {
Name string `json:"name"`
Provider string `json:"provider"`
AccessKey string `json:"access_key"`
SecretKey string `json:"secret_key"`
MonthlyCost float64 `json:"monthly_cost"`
Status string `json:"status"`
}
// CreateCloudAccount 创建云账号
// @Summary 创建云账号
// @Description 创建新云账号
@@ -408,12 +419,12 @@ func (h *CloudAccountHandler) ListCloudAccounts(c *gin.Context) {
// @Accept json
// @Produce json
// @Security Bearer
// @Param request body models.CloudAccount true "创建请求"
// @Param request body createCloudAccountRequest true "创建请求"
// @Success 200 {object} models.Response{data=models.CloudAccount}
// @Router /cloud-accounts [post]
func (h *CloudAccountHandler) CreateCloudAccount(c *gin.Context) {
var account models.CloudAccount
if err := c.ShouldBindJSON(&account); err != nil {
var req createCloudAccountRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, models.Response{
Code: 400,
Message: "请求参数错误: " + err.Error(),
@@ -421,6 +432,28 @@ func (h *CloudAccountHandler) CreateCloudAccount(c *gin.Context) {
return
}
if strings.TrimSpace(req.Name) == "" || strings.TrimSpace(req.Provider) == "" {
c.JSON(http.StatusBadRequest, models.Response{
Code: 400,
Message: "账号名称和云平台不能为空",
})
return
}
status := strings.TrimSpace(req.Status)
if status == "" {
status = "active"
}
account := models.CloudAccount{
Name: strings.TrimSpace(req.Name),
Provider: strings.TrimSpace(req.Provider),
AccessKey: req.AccessKey,
SecretKey: req.SecretKey,
MonthlyCost: req.MonthlyCost,
Status: status,
}
if err := h.db.Create(&account).Error; err != nil {
c.JSON(http.StatusInternalServerError, models.Response{
Code: 500,