Files
goodBaby/api/account/account.go
T

282 lines
6.8 KiB
Go
Raw Normal View History

2026-04-05 10:36:22 +08:00
package account
import (
2026-07-26 22:19:41 +08:00
"time"
2026-04-05 22:46:11 +08:00
2026-04-05 10:36:22 +08:00
"github.com/gin-gonic/gin"
2026-07-26 22:19:41 +08:00
"github.com/ssdomei232/goodBaby/api/response"
2026-04-05 22:46:11 +08:00
"github.com/ssdomei232/goodBaby/api/rule"
2026-04-05 10:36:22 +08:00
"github.com/ssdomei232/goodBaby/api/user"
"github.com/ssdomei232/goodBaby/handler/db"
2026-07-26 22:19:41 +08:00
"github.com/ssdomei232/goodBaby/internal/accountConfigChecker"
"github.com/ssdomei232/goodBaby/internal/meta"
2026-04-05 10:36:22 +08:00
"github.com/ssdomei232/goodBaby/model"
)
2026-07-26 22:19:41 +08:00
// HandleAddAccount 添加账号
2026-04-05 10:36:22 +08:00
func HandleAddAccount(c *gin.Context) {
userInfo, err := user.GetUserInfoByGinCtx(c)
if err != nil {
2026-07-26 22:19:41 +08:00
response.Unauthorized(c, "获取用户信息失败")
2026-04-05 10:36:22 +08:00
return
}
2026-07-26 22:19:41 +08:00
var req model.AccountRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "输入参数错误")
2026-04-05 10:36:22 +08:00
return
}
2026-07-26 22:19:41 +08:00
if err := req.Validate(); err != nil {
response.FromError(c, err, "添加账号失败")
2026-04-05 10:36:22 +08:00
return
}
2026-07-26 22:19:41 +08:00
// 之前这里完全没有走校验器,任何 JSON 都能存进去,直到规则触发才暴露问题
registry := accountConfigChecker.InitValidatorRegistry()
if err := registry.Validate(req.Type, req.Config); err != nil {
response.BadRequest(c, err.Error())
return
}
gormDB, err := db.GetGormDB()
if err != nil {
response.ServerError(c, "服务器内部错误")
return
}
newAccount := model.Account{
UID: userInfo.ID,
Name: req.Name,
Type: req.Type,
Config: req.Config,
CreateAt: time.Now().Unix(),
}
if err := gormDB.Create(&newAccount).Error; err != nil {
response.ServerError(c, "添加账号失败")
return
}
response.OK(c, maskAccount(newAccount))
2026-04-05 10:36:22 +08:00
}
2026-07-26 22:19:41 +08:00
// HandleGetAllAccounts 获取用户的所有账号
2026-04-05 10:36:22 +08:00
func HandleGetAllAccounts(c *gin.Context) {
userInfo, err := user.GetUserInfoByGinCtx(c)
if err != nil {
2026-07-26 22:19:41 +08:00
response.Unauthorized(c, "获取用户信息失败")
2026-04-05 10:36:22 +08:00
return
}
2026-07-26 22:19:41 +08:00
gormDB, err := db.GetGormDB()
if err != nil {
response.ServerError(c, "服务器内部错误")
2026-04-05 10:36:22 +08:00
return
}
2026-07-26 22:19:41 +08:00
query := gormDB.Where("uid = ?", userInfo.ID)
if accountType := c.Query("type"); accountType != "" {
query = query.Where("type = ?", accountType)
}
accounts := []model.Account{}
if err := query.Order("id DESC").Find(&accounts).Error; err != nil {
response.ServerError(c, "获取账号失败")
return
}
response.OK(c, maskAccounts(accounts))
2026-04-05 10:36:22 +08:00
}
2026-04-05 22:46:11 +08:00
2026-07-26 22:19:41 +08:00
// HandleEditAccount 编辑账号
func HandleEditAccount(c *gin.Context) {
userInfo, err := user.GetUserInfoByGinCtx(c)
if err != nil {
response.Unauthorized(c, "获取用户信息失败")
return
}
accountID, err := parseID(c.Param("accountID"))
if err != nil {
response.BadRequest(c, "账号ID格式错误")
return
}
existing, err := findAccount(accountID, userInfo.ID)
if err != nil {
response.NotFound(c, "账号不存在")
return
}
var req model.AccountRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "输入参数错误")
return
}
if err := req.Validate(); err != nil {
response.FromError(c, err, "更新账号失败")
return
}
if req.Type != existing.Type {
response.BadRequest(c, "不支持修改账号类型,请新建账号")
return
}
registry := accountConfigChecker.InitValidatorRegistry()
// 前端提交的密码等字段可能是掩码占位符,用旧配置补回
config := meta.Unmask(req.Config, existing.Config, registry.FieldsOf(req.Type))
if err := registry.Validate(req.Type, config); err != nil {
response.BadRequest(c, err.Error())
return
}
gormDB, err := db.GetGormDB()
if err != nil {
response.ServerError(c, "服务器内部错误")
return
}
existing.Name = req.Name
existing.Config = config
if err := gormDB.Save(existing).Error; err != nil {
response.ServerError(c, "更新账号失败")
return
}
response.OK(c, maskAccount(*existing))
}
// HandleTestAccount 测试账号凭据是否可用
func HandleTestAccount(c *gin.Context) {
userInfo, err := user.GetUserInfoByGinCtx(c)
if err != nil {
response.Unauthorized(c, "获取用户信息失败")
return
}
accountID, err := parseID(c.Param("accountID"))
if err != nil {
response.BadRequest(c, "账号ID格式错误")
return
}
existing, err := findAccount(accountID, userInfo.ID)
if err != nil {
response.NotFound(c, "账号不存在")
return
}
registry := accountConfigChecker.InitValidatorRegistry()
if err := registry.Test(existing.Type, existing.Config); err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, "账号可用")
}
// HandleCheckDeleteAccount 检查删除账号请求
2026-04-05 22:46:11 +08:00
//
2026-09-12 15:32:27 +08:00
// 删除账号会同时删除相关规则(含消息网关规则),先请求该接口获取受影响的规则
2026-04-05 22:46:11 +08:00
func HandleCheckDeleteAccount(c *gin.Context) {
userInfo, err := user.GetUserInfoByGinCtx(c)
if err != nil {
2026-07-26 22:19:41 +08:00
response.Unauthorized(c, "获取用户信息失败")
2026-04-05 22:46:11 +08:00
return
}
2026-07-26 22:19:41 +08:00
accountID, err := parseID(c.Param("accountID"))
2026-04-05 22:46:11 +08:00
if err != nil {
2026-07-26 22:19:41 +08:00
response.BadRequest(c, "账号ID格式错误")
2026-04-05 22:46:11 +08:00
return
}
2026-07-26 22:19:41 +08:00
rules, err := getRulesByAccountID(accountID, userInfo.ID)
if err != nil {
response.ServerError(c, "获取相关规则失败")
return
}
2026-09-12 15:32:27 +08:00
gatewayRules, err := getGatewayRulesByAccountID(accountID, userInfo.ID)
if err != nil {
response.ServerError(c, "获取相关网关规则失败")
return
}
response.OK(c, gin.H{
"rules": rules,
"gateway_rules": gatewayRules,
})
2026-04-05 22:46:11 +08:00
}
2026-07-26 22:19:41 +08:00
// HandleDeleteAccount 删除账号及其关联规则
2026-04-05 22:46:11 +08:00
func HandleDeleteAccount(c *gin.Context) {
userInfo, err := user.GetUserInfoByGinCtx(c)
if err != nil {
2026-07-26 22:19:41 +08:00
response.Unauthorized(c, "获取用户信息失败")
2026-04-05 22:46:11 +08:00
return
}
2026-07-26 22:19:41 +08:00
accountID, err := parseID(c.Param("accountID"))
2026-04-05 22:46:11 +08:00
if err != nil {
2026-07-26 22:19:41 +08:00
response.BadRequest(c, "账号ID格式错误")
2026-04-05 22:46:11 +08:00
return
}
// 检查账号是否归属请求用户
ownerUID, err := getAccountOwnerUID(accountID)
if err != nil {
response.ServerError(c, "获取账号所属用户失败")
return
}
if ownerUID != userInfo.ID {
response.Forbidden(c, "无权限操作该账号")
return
}
2026-04-06 10:10:31 +08:00
// 删除相关规则
2026-07-26 22:19:41 +08:00
rules, err := getRulesByAccountID(accountID, userInfo.ID)
2026-04-05 22:46:11 +08:00
if err != nil {
2026-07-26 22:19:41 +08:00
response.ServerError(c, "获取相关规则失败")
2026-04-05 22:46:11 +08:00
return
}
for _, oneRule := range rules {
2026-07-26 22:19:41 +08:00
if err := rule.DeleteRuleByID(oneRule.ID, userInfo.ID); err != nil {
response.ServerError(c, "删除相关规则失败")
2026-04-05 22:46:11 +08:00
return
}
}
2026-09-12 15:32:27 +08:00
// 删除相关的消息网关规则
gatewayRules, err := getGatewayRulesByAccountID(accountID, userInfo.ID)
if err != nil {
response.ServerError(c, "获取相关网关规则失败")
return
}
for _, oneRule := range gatewayRules {
if err := rule.DeleteGatewayRuleByID(oneRule.ID, userInfo.ID); err != nil {
response.ServerError(c, "删除相关网关规则失败")
return
}
}
2026-04-06 10:10:31 +08:00
// 删除账号
2026-04-05 22:46:11 +08:00
gormDB, err := db.GetGormDB()
if err != nil {
2026-07-26 22:19:41 +08:00
response.ServerError(c, "服务器内部错误")
2026-04-05 22:46:11 +08:00
return
}
2026-07-26 22:19:41 +08:00
if err := gormDB.Where("id = ? AND uid = ?", accountID, userInfo.ID).
Delete(&model.Account{}).Error; err != nil {
response.ServerError(c, "删除账号失败")
2026-04-05 22:46:11 +08:00
return
}
2026-07-26 22:19:41 +08:00
response.OK(c, "删除账号成功")
2026-04-05 22:46:11 +08:00
}