806 lines
22 KiB
Go
806 lines
22 KiB
Go
package developer
|
|
|
|
import (
|
|
"log"
|
|
"strings"
|
|
"time"
|
|
"unicode"
|
|
|
|
"verification-platform-backend/internal/database"
|
|
"verification-platform-backend/internal/model"
|
|
"verification-platform-backend/pkg/response"
|
|
|
|
"github.com/dop251/goja"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func normalizeKey(name string) string {
|
|
key := strings.ToLower(strings.TrimSpace(name))
|
|
key = strings.Map(func(r rune) rune {
|
|
if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' || r == '-' {
|
|
return r
|
|
}
|
|
return '_'
|
|
}, key)
|
|
return key
|
|
}
|
|
|
|
func validateDynamicCode(code string) error {
|
|
vm := goja.New()
|
|
vm.Set("params", vm.NewObject())
|
|
vm.Set("user", vm.NewObject())
|
|
vm.Set("app", vm.NewObject())
|
|
wrappedCode := "(function() { " + code + " })()"
|
|
_, err := vm.RunString(wrappedCode)
|
|
if err != nil {
|
|
errStr := err.Error()
|
|
if strings.Contains(errStr, "ReferenceError") || strings.Contains(errStr, "is not defined") {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func SetupDynamicRoutes(r *gin.RouterGroup) {
|
|
dynamicCodes := r.Group("/dynamic-codes")
|
|
{
|
|
dynamicCodes.GET("", handleListDynamicCodes)
|
|
dynamicCodes.GET("/:id", handleGetDynamicCode)
|
|
dynamicCodes.POST("", handleCreateDynamicCode)
|
|
dynamicCodes.PUT("/:id", handleUpdateDynamicCode)
|
|
dynamicCodes.DELETE("/:id", handleDeleteDynamicCode)
|
|
dynamicCodes.PUT("/:id/status", handleUpdateDynamicCodeStatus)
|
|
dynamicCodes.DELETE("/batch", handleBatchDeleteDynamicCodes)
|
|
dynamicCodes.PUT("/batch/status", handleBatchUpdateDynamicCodeStatus)
|
|
}
|
|
|
|
riskControl := r.Group("/risk-control")
|
|
{
|
|
riskControl.GET("/rules", handleGetRiskControlRules)
|
|
riskControl.POST("/rules", handleCreateRiskControlRule)
|
|
riskControl.PUT("/rules/:id", handleUpdateRiskControlRule)
|
|
riskControl.DELETE("/rules/:id", handleDeleteRiskControlRule)
|
|
riskControl.PUT("/rules/:id/status", handleUpdateRiskControlRuleStatus)
|
|
riskControl.DELETE("/rules/batch", handleBatchDeleteRiskControlRules)
|
|
riskControl.PUT("/rules/batch/status", handleBatchUpdateRiskControlRuleStatus)
|
|
}
|
|
}
|
|
|
|
func handleListDynamicCodes(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
var applications []model.Application
|
|
if err := database.DB.Where("user_id = ?", userID).Find(&applications).Error; err != nil {
|
|
response.Error(c, 500, "获取应用列表失败")
|
|
return
|
|
}
|
|
|
|
var applicationIDs []uint
|
|
for _, app := range applications {
|
|
applicationIDs = append(applicationIDs, app.ID)
|
|
}
|
|
|
|
var dynamicCodes []model.DynamicCode
|
|
if err := database.DB.Preload("Application").Preload("Creator").Where("application_id IN ?", applicationIDs).Find(&dynamicCodes).Error; err != nil {
|
|
response.Error(c, 500, "获取动态代码列表失败")
|
|
return
|
|
|
|
}
|
|
|
|
type DynamicCodeResponse struct {
|
|
ID uint `json:"id"`
|
|
Name string `json:"name"`
|
|
Code string `json:"code"`
|
|
Description string `json:"description"`
|
|
ApplicationID uint `json:"application_id"`
|
|
ApplicationName string `json:"application_name"`
|
|
Enabled bool `json:"enabled"`
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
Creator *struct {
|
|
ID uint `json:"id"`
|
|
Username string `json:"username"`
|
|
} `json:"creator,omitempty"`
|
|
}
|
|
|
|
var result []DynamicCodeResponse
|
|
for _, dc := range dynamicCodes {
|
|
var creator *struct {
|
|
ID uint `json:"id"`
|
|
Username string `json:"username"`
|
|
}
|
|
if dc.UserID != nil && dc.Creator.ID != 0 {
|
|
creator = &struct {
|
|
ID uint `json:"id"`
|
|
Username string `json:"username"`
|
|
}{
|
|
ID: dc.Creator.ID,
|
|
Username: dc.Creator.Username,
|
|
}
|
|
}
|
|
|
|
result = append(result, DynamicCodeResponse{
|
|
ID: dc.ID,
|
|
Name: dc.Name,
|
|
Code: dc.Code,
|
|
Description: dc.Description,
|
|
ApplicationID: dc.ApplicationID,
|
|
ApplicationName: dc.Application.Name,
|
|
Enabled: dc.Status == "active",
|
|
CreatedAt: dc.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
UpdatedAt: dc.UpdatedAt.Format("2006-01-02 15:04:05"),
|
|
Creator: creator,
|
|
})
|
|
}
|
|
|
|
response.Success(c, result)
|
|
}
|
|
|
|
func handleGetDynamicCode(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
id := c.Param("id")
|
|
|
|
var dynamicCode model.DynamicCode
|
|
if err := database.DB.Preload("Application").Preload("Creator").Where("id = ?", id).First(&dynamicCode).Error; err != nil {
|
|
response.Error(c, 404, "动态代码不存在")
|
|
return
|
|
}
|
|
|
|
var app model.Application
|
|
if err := database.DB.Where("id = ? AND user_id = ?", dynamicCode.ApplicationID, userID).First(&app).Error; err != nil {
|
|
response.Error(c, 403, "无权限访问此动态代码")
|
|
return
|
|
}
|
|
|
|
type DynamicCodeResponse struct {
|
|
ID uint `json:"id"`
|
|
Name string `json:"name"`
|
|
Code string `json:"code"`
|
|
Description string `json:"description"`
|
|
ApplicationID uint `json:"application_id"`
|
|
ApplicationName string `json:"application_name"`
|
|
Enabled bool `json:"enabled"`
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
Creator *struct {
|
|
ID uint `json:"id"`
|
|
Username string `json:"username"`
|
|
} `json:"creator,omitempty"`
|
|
}
|
|
|
|
var creator *struct {
|
|
ID uint `json:"id"`
|
|
Username string `json:"username"`
|
|
}
|
|
if dynamicCode.UserID != nil && dynamicCode.Creator.ID != 0 {
|
|
creator = &struct {
|
|
ID uint `json:"id"`
|
|
Username string `json:"username"`
|
|
}{
|
|
ID: dynamicCode.Creator.ID,
|
|
Username: dynamicCode.Creator.Username,
|
|
}
|
|
}
|
|
|
|
result := DynamicCodeResponse{
|
|
ID: dynamicCode.ID,
|
|
Name: dynamicCode.Name,
|
|
Code: dynamicCode.Code,
|
|
Description: dynamicCode.Description,
|
|
ApplicationID: dynamicCode.ApplicationID,
|
|
ApplicationName: dynamicCode.Application.Name,
|
|
Enabled: dynamicCode.Status == "active",
|
|
CreatedAt: dynamicCode.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
UpdatedAt: dynamicCode.UpdatedAt.Format("2006-01-02 15:04:05"),
|
|
Creator: creator,
|
|
}
|
|
|
|
response.Success(c, result)
|
|
}
|
|
|
|
func handleCreateDynamicCode(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
var req struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Code string `json:"code" binding:"required"`
|
|
Description string `json:"description"`
|
|
Enabled bool `json:"enabled"`
|
|
ApplicationID uint `json:"application_id" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误: "+err.Error())
|
|
return
|
|
}
|
|
|
|
if err := validateDynamicCode(req.Code); err != nil {
|
|
response.Error(c, 400, "代码语法错误: "+err.Error())
|
|
return
|
|
}
|
|
|
|
var app model.Application
|
|
if err := database.DB.Where("id = ? AND user_id = ?", req.ApplicationID, userID).First(&app).Error; err != nil {
|
|
response.Error(c, 404, "应用不存在")
|
|
return
|
|
}
|
|
|
|
status := "inactive"
|
|
if req.Enabled {
|
|
status = "active"
|
|
}
|
|
|
|
key := normalizeKey(req.Name)
|
|
|
|
var existingCode model.DynamicCode
|
|
err := database.DB.Unscoped().Where("key = ?", key).First(&existingCode).Error
|
|
if err == nil {
|
|
if existingCode.DeletedAt.Valid {
|
|
database.DB.Unscoped().Delete(&existingCode)
|
|
} else {
|
|
response.Error(c, 400, "该名称的动态代码已存在")
|
|
return
|
|
}
|
|
}
|
|
|
|
dynamicCode := model.DynamicCode{
|
|
UserID: &userID,
|
|
ApplicationID: req.ApplicationID,
|
|
Name: req.Name,
|
|
Key: key,
|
|
Code: req.Code,
|
|
Description: req.Description,
|
|
Status: status,
|
|
}
|
|
|
|
if err := database.DB.Create(&dynamicCode).Error; err != nil {
|
|
if strings.Contains(err.Error(), "UNIQUE constraint failed") || strings.Contains(err.Error(), "constraint failed") {
|
|
response.Error(c, 400, "该名称的动态代码已存在")
|
|
return
|
|
}
|
|
response.Error(c, 500, "创建失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
response.Success(c, dynamicCode)
|
|
}
|
|
|
|
func handleUpdateDynamicCode(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
id := c.Param("id")
|
|
|
|
var dynamicCode model.DynamicCode
|
|
if err := database.DB.Where("id = ?", id).First(&dynamicCode).Error; err != nil {
|
|
response.Error(c, 404, "动态代码不存在")
|
|
return
|
|
}
|
|
|
|
var app model.Application
|
|
if err := database.DB.Where("id = ? AND user_id = ?", dynamicCode.ApplicationID, userID).First(&app).Error; err != nil {
|
|
response.Error(c, 403, "无权限操作此动态代码")
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Code string `json:"code" binding:"required"`
|
|
Description string `json:"description"`
|
|
Enabled bool `json:"enabled"`
|
|
ApplicationID uint `json:"application_id" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
if err := validateDynamicCode(req.Code); err != nil {
|
|
response.Error(c, 400, "代码语法错误: "+err.Error())
|
|
return
|
|
}
|
|
|
|
if req.ApplicationID != dynamicCode.ApplicationID {
|
|
var newApp model.Application
|
|
if err := database.DB.Where("id = ? AND user_id = ?", req.ApplicationID, userID).First(&newApp).Error; err != nil {
|
|
response.Error(c, 403, "无权限操作此应用")
|
|
return
|
|
}
|
|
dynamicCode.ApplicationID = req.ApplicationID
|
|
}
|
|
|
|
status := "inactive"
|
|
if req.Enabled {
|
|
status = "active"
|
|
}
|
|
|
|
dynamicCode.Name = req.Name
|
|
dynamicCode.Key = normalizeKey(req.Name)
|
|
dynamicCode.Code = req.Code
|
|
dynamicCode.Description = req.Description
|
|
dynamicCode.Status = status
|
|
|
|
if err := database.DB.Save(&dynamicCode).Error; err != nil {
|
|
response.Error(c, 500, "更新失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, dynamicCode)
|
|
}
|
|
|
|
func handleDeleteDynamicCode(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
id := c.Param("id")
|
|
|
|
var dynamicCode model.DynamicCode
|
|
if err := database.DB.Where("id = ?", id).First(&dynamicCode).Error; err != nil {
|
|
response.Error(c, 404, "动态代码不存在")
|
|
return
|
|
}
|
|
|
|
var app model.Application
|
|
if err := database.DB.Where("id = ? AND user_id = ?", dynamicCode.ApplicationID, userID).First(&app).Error; err != nil {
|
|
response.Error(c, 403, "无权限操作此动态代码")
|
|
return
|
|
}
|
|
|
|
if err := database.DB.Delete(&dynamicCode).Error; err != nil {
|
|
response.Error(c, 500, "删除失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{"message": "删除成功"})
|
|
}
|
|
|
|
func handleUpdateDynamicCodeStatus(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
id := c.Param("id")
|
|
|
|
var dynamicCode model.DynamicCode
|
|
if err := database.DB.Where("id = ?", id).First(&dynamicCode).Error; err != nil {
|
|
response.Error(c, 404, "动态代码不存在")
|
|
return
|
|
}
|
|
|
|
var app model.Application
|
|
if err := database.DB.Where("id = ? AND user_id = ?", dynamicCode.ApplicationID, userID).First(&app).Error; err != nil {
|
|
response.Error(c, 403, "无权限操作此动态代码")
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
status := "inactive"
|
|
if req.Enabled {
|
|
status = "active"
|
|
}
|
|
|
|
dynamicCode.Status = status
|
|
|
|
if err := database.DB.Save(&dynamicCode).Error; err != nil {
|
|
response.Error(c, 500, "更新状态失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, dynamicCode)
|
|
}
|
|
|
|
func handleBatchDeleteDynamicCodes(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
var req struct {
|
|
IDs []uint `json:"ids" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
var applications []model.Application
|
|
if err := database.DB.Where("user_id = ?", userID).Find(&applications).Error; err != nil {
|
|
response.Error(c, 500, "获取应用列表失败")
|
|
return
|
|
}
|
|
|
|
var applicationIDs []uint
|
|
for _, app := range applications {
|
|
applicationIDs = append(applicationIDs, app.ID)
|
|
}
|
|
|
|
if err := database.DB.Where("id IN ? AND application_id IN ?", req.IDs, applicationIDs).Delete(&model.DynamicCode{}).Error; err != nil {
|
|
response.Error(c, 500, "批量删除失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{"message": "批量删除成功"})
|
|
}
|
|
|
|
func handleBatchUpdateDynamicCodeStatus(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
var req struct {
|
|
IDs []uint `json:"ids" binding:"required"`
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
var applications []model.Application
|
|
if err := database.DB.Where("user_id = ?", userID).Find(&applications).Error; err != nil {
|
|
response.Error(c, 500, "获取应用列表失败")
|
|
return
|
|
}
|
|
|
|
var applicationIDs []uint
|
|
for _, app := range applications {
|
|
applicationIDs = append(applicationIDs, app.ID)
|
|
}
|
|
|
|
status := "inactive"
|
|
if req.Enabled {
|
|
status = "active"
|
|
}
|
|
|
|
if err := database.DB.Model(&model.DynamicCode{}).Where("id IN ? AND application_id IN ?", req.IDs, applicationIDs).Update("status", status).Error; err != nil {
|
|
response.Error(c, 500, "批量更新状态失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{"message": "批量更新状态成功"})
|
|
}
|
|
|
|
type RiskControlRule struct {
|
|
ID uint `json:"id"`
|
|
Type string `json:"type"`
|
|
Value string `json:"value"`
|
|
Reason string `json:"reason"`
|
|
Status string `json:"status"`
|
|
ExpiresAt *string `json:"expires_at"`
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|
|
func handleGetRiskControlRules(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
var applications []model.Application
|
|
if err := database.DB.Where("user_id = ?", userID).Find(&applications).Error; err != nil {
|
|
response.Error(c, 500, "获取应用列表失败")
|
|
return
|
|
}
|
|
|
|
var applicationIDs []uint
|
|
for _, app := range applications {
|
|
applicationIDs = append(applicationIDs, app.ID)
|
|
}
|
|
|
|
var rules []model.RiskControlRule
|
|
if err := database.DB.Where("user_id = ? OR application_id IN ?", userID, applicationIDs).Order("created_at DESC").Find(&rules).Error; err != nil {
|
|
response.Error(c, 500, "获取风控规则失败")
|
|
return
|
|
}
|
|
|
|
var result []gin.H
|
|
for _, rule := range rules {
|
|
var expiresAt *string
|
|
if rule.ExpiresAt != nil {
|
|
t := rule.ExpiresAt.Format("2006-01-02 15:04:05")
|
|
expiresAt = &t
|
|
}
|
|
|
|
var appID *uint
|
|
if rule.ApplicationID != nil {
|
|
appID = rule.ApplicationID
|
|
}
|
|
|
|
result = append(result, gin.H{
|
|
"id": rule.ID,
|
|
"type": rule.Type,
|
|
"value": rule.Value,
|
|
"reason": rule.Reason,
|
|
"status": rule.Status,
|
|
"expires_at": expiresAt,
|
|
"application_id": appID,
|
|
"is_global": rule.ApplicationID == nil,
|
|
"created_at": rule.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
})
|
|
}
|
|
|
|
response.Success(c, result)
|
|
}
|
|
|
|
func handleCreateRiskControlRule(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
var req struct {
|
|
Type string `json:"type" binding:"required"`
|
|
Value string `json:"value" binding:"required"`
|
|
Reason string `json:"reason"`
|
|
ExpiresAt *string `json:"expires_at"`
|
|
ApplicationID *uint `json:"application_id"`
|
|
IsGlobal bool `json:"is_global"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
log.Printf("[ERROR] Failed to bind JSON: %v", err)
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
log.Printf("[DEBUG] Create risk control rule: type=%s, value=%s, is_global=%v, application_id=%v", req.Type, req.Value, req.IsGlobal, req.ApplicationID)
|
|
|
|
var appID *uint
|
|
switch req.Type {
|
|
case "user":
|
|
if req.ApplicationID == nil {
|
|
response.Error(c, 400, "用户封禁规则必须指定应用")
|
|
return
|
|
}
|
|
var application model.Application
|
|
if err := database.DB.Where("id = ? AND user_id = ?", *req.ApplicationID, userID).First(&application).Error; err != nil {
|
|
response.Error(c, 404, "应用不存在或无权限")
|
|
return
|
|
}
|
|
appID = req.ApplicationID
|
|
case "ip", "device", "region":
|
|
if !req.IsGlobal && req.ApplicationID != nil {
|
|
var application model.Application
|
|
if err := database.DB.Where("id = ? AND user_id = ?", *req.ApplicationID, userID).First(&application).Error; err != nil {
|
|
response.Error(c, 404, "应用不存在或无权限")
|
|
return
|
|
}
|
|
appID = req.ApplicationID
|
|
} else {
|
|
appID = nil
|
|
}
|
|
default:
|
|
response.Error(c, 400, "不支持的规则类型")
|
|
return
|
|
}
|
|
|
|
rule := model.RiskControlRule{
|
|
UserID: userID,
|
|
ApplicationID: appID,
|
|
Type: req.Type,
|
|
Value: req.Value,
|
|
Reason: req.Reason,
|
|
Status: "active",
|
|
}
|
|
|
|
if req.ExpiresAt != nil && *req.ExpiresAt != "" {
|
|
t, err := time.Parse("2006-01-02T15:04", *req.ExpiresAt)
|
|
if err == nil {
|
|
rule.ExpiresAt = &t
|
|
} else {
|
|
log.Printf("[WARN] Failed to parse expires_at: %v", err)
|
|
}
|
|
}
|
|
|
|
log.Printf("[DEBUG] Creating rule: %+v", rule)
|
|
|
|
if err := database.DB.Create(&rule).Error; err != nil {
|
|
log.Printf("[ERROR] Failed to create risk control rule: %v", err)
|
|
response.Error(c, 500, "创建风控规则失败")
|
|
return
|
|
}
|
|
|
|
var expiresAt *string
|
|
if rule.ExpiresAt != nil {
|
|
t := rule.ExpiresAt.Format("2006-01-02 15:04:05")
|
|
expiresAt = &t
|
|
}
|
|
|
|
var appIDResp *uint
|
|
if rule.ApplicationID != nil {
|
|
appIDResp = rule.ApplicationID
|
|
}
|
|
|
|
response.Success(c, gin.H{
|
|
"id": rule.ID,
|
|
"type": rule.Type,
|
|
"value": rule.Value,
|
|
"reason": rule.Reason,
|
|
"status": rule.Status,
|
|
"expires_at": expiresAt,
|
|
"application_id": appIDResp,
|
|
"is_global": rule.ApplicationID == nil,
|
|
"created_at": rule.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
})
|
|
}
|
|
|
|
func handleUpdateRiskControlRule(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
ruleID := c.Param("id")
|
|
|
|
var req struct {
|
|
Type string `json:"type" binding:"required"`
|
|
Value string `json:"value" binding:"required"`
|
|
Reason string `json:"reason"`
|
|
ExpiresAt *string `json:"expires_at"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
var applications []model.Application
|
|
if err := database.DB.Where("user_id = ?", userID).Find(&applications).Error; err != nil {
|
|
response.Error(c, 500, "获取应用列表失败")
|
|
return
|
|
}
|
|
|
|
var applicationIDs []uint
|
|
for _, app := range applications {
|
|
applicationIDs = append(applicationIDs, app.ID)
|
|
}
|
|
|
|
var rule model.RiskControlRule
|
|
if err := database.DB.Where("id = ? AND application_id IN ?", ruleID, applicationIDs).First(&rule).Error; err != nil {
|
|
response.Error(c, 404, "风控规则不存在")
|
|
return
|
|
}
|
|
|
|
rule.Type = req.Type
|
|
rule.Value = req.Value
|
|
rule.Reason = req.Reason
|
|
|
|
if req.ExpiresAt != nil && *req.ExpiresAt != "" {
|
|
t, err := time.Parse("2006-01-02T15:04", *req.ExpiresAt)
|
|
if err == nil {
|
|
rule.ExpiresAt = &t
|
|
}
|
|
} else {
|
|
rule.ExpiresAt = nil
|
|
}
|
|
|
|
if err := database.DB.Save(&rule).Error; err != nil {
|
|
response.Error(c, 500, "更新风控规则失败")
|
|
return
|
|
}
|
|
|
|
var expiresAt *string
|
|
if rule.ExpiresAt != nil {
|
|
t := rule.ExpiresAt.Format("2006-01-02 15:04:05")
|
|
expiresAt = &t
|
|
}
|
|
|
|
response.Success(c, RiskControlRule{
|
|
ID: rule.ID,
|
|
Type: rule.Type,
|
|
Value: rule.Value,
|
|
Reason: rule.Reason,
|
|
Status: rule.Status,
|
|
ExpiresAt: expiresAt,
|
|
CreatedAt: rule.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
})
|
|
}
|
|
|
|
func handleDeleteRiskControlRule(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
ruleID := c.Param("id")
|
|
|
|
var applications []model.Application
|
|
if err := database.DB.Where("user_id = ?", userID).Find(&applications).Error; err != nil {
|
|
response.Error(c, 500, "获取应用列表失败")
|
|
return
|
|
}
|
|
|
|
var applicationIDs []uint
|
|
for _, app := range applications {
|
|
applicationIDs = append(applicationIDs, app.ID)
|
|
}
|
|
|
|
if err := database.DB.Where("id = ? AND application_id IN ?", ruleID, applicationIDs).Delete(&model.RiskControlRule{}).Error; err != nil {
|
|
response.Error(c, 500, "删除风控规则失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{"message": "删除成功"})
|
|
}
|
|
|
|
func handleUpdateRiskControlRuleStatus(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
ruleID := c.Param("id")
|
|
|
|
var req struct {
|
|
Status string `json:"status" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
var applications []model.Application
|
|
if err := database.DB.Where("user_id = ?", userID).Find(&applications).Error; err != nil {
|
|
response.Error(c, 500, "获取应用列表失败")
|
|
return
|
|
}
|
|
|
|
var applicationIDs []uint
|
|
for _, app := range applications {
|
|
applicationIDs = append(applicationIDs, app.ID)
|
|
}
|
|
|
|
var rule model.RiskControlRule
|
|
if err := database.DB.Where("id = ? AND application_id IN ?", ruleID, applicationIDs).First(&rule).Error; err != nil {
|
|
response.Error(c, 404, "风控规则不存在")
|
|
return
|
|
}
|
|
|
|
rule.Status = req.Status
|
|
if err := database.DB.Save(&rule).Error; err != nil {
|
|
response.Error(c, 500, "更新状态失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{"message": "状态更新成功"})
|
|
}
|
|
|
|
func handleBatchDeleteRiskControlRules(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
var req struct {
|
|
IDs []uint `json:"ids" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
var applications []model.Application
|
|
if err := database.DB.Where("user_id = ?", userID).Find(&applications).Error; err != nil {
|
|
response.Error(c, 500, "获取应用列表失败")
|
|
return
|
|
}
|
|
|
|
var applicationIDs []uint
|
|
for _, app := range applications {
|
|
applicationIDs = append(applicationIDs, app.ID)
|
|
}
|
|
|
|
if err := database.DB.Where("id IN ? AND application_id IN ?", req.IDs, applicationIDs).Delete(&model.RiskControlRule{}).Error; err != nil {
|
|
response.Error(c, 500, "批量删除失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{"message": "批量删除成功"})
|
|
}
|
|
|
|
func handleBatchUpdateRiskControlRuleStatus(c *gin.Context) {
|
|
userID := c.GetUint("user_id")
|
|
|
|
var req struct {
|
|
IDs []uint `json:"ids" binding:"required"`
|
|
Status string `json:"status" binding:"required"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.Error(c, 400, "参数错误")
|
|
return
|
|
}
|
|
|
|
var applications []model.Application
|
|
if err := database.DB.Where("user_id = ?", userID).Find(&applications).Error; err != nil {
|
|
response.Error(c, 500, "获取应用列表失败")
|
|
return
|
|
}
|
|
|
|
var applicationIDs []uint
|
|
for _, app := range applications {
|
|
applicationIDs = append(applicationIDs, app.ID)
|
|
}
|
|
|
|
if err := database.DB.Model(&model.RiskControlRule{}).Where("id IN ? AND application_id IN ?", req.IDs, applicationIDs).Update("status", req.Status).Error; err != nil {
|
|
response.Error(c, 500, "批量更新状态失败")
|
|
return
|
|
}
|
|
|
|
response.Success(c, gin.H{"message": "批量更新状态成功"})
|
|
}
|