Files
soul-yongping/soul-api/internal/handler/admin_user_rules.go

214 lines
6.9 KiB
Go
Raw Normal View History

package handler
import (
"encoding/json"
"net/http"
"strconv"
"soul-api/internal/database"
"soul-api/internal/model"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// MiniprogramUserRules GET /api/miniprogram/user-rules小程序端只返回启用的规则
func MiniprogramUserRules(c *gin.Context) {
db := database.DB()
var rules []model.UserRule
if err := db.Where("enabled = ?", true).Order("sort ASC, id ASC").Find(&rules).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
out := make([]gin.H, 0, len(rules))
for _, r := range rules {
out = append(out, gin.H{"id": r.ID, "title": r.Title, "description": r.Description, "trigger": r.Trigger, "sort": r.Sort})
}
c.JSON(http.StatusOK, gin.H{"success": true, "rules": out})
}
// DBUserRulesList GET /api/db/user-rules
func DBUserRulesList(c *gin.Context) {
db := database.DB()
var rules []model.UserRule
if err := db.Order("sort ASC, id ASC").Find(&rules).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "rules": rules})
2026-03-17 12:21:33 +08:00
}
// MiniprogramUserRulesGet GET /api/miniprogram/user-rules?userId=xxx
// 返回启用的规则,并标记当前用户已完成的规则
2026-03-17 12:21:33 +08:00
func MiniprogramUserRulesGet(c *gin.Context) {
db := database.DB()
var rules []model.UserRule
if err := db.Where("enabled = ?", true).Order("sort ASC, id ASC").Find(&rules).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
userId := c.Query("userId")
completedSet := make(map[uint]bool)
if userId != "" {
var completions []model.UserRuleCompletion
db.Where("user_id = ?", userId).Find(&completions)
for _, comp := range completions {
completedSet[comp.RuleID] = true
}
}
out := make([]gin.H, 0, len(rules))
for _, r := range rules {
out = append(out, gin.H{
"id": r.ID, "title": r.Title, "description": r.Description,
"trigger": r.Trigger, "sort": r.Sort, "completed": completedSet[r.ID],
})
}
c.JSON(http.StatusOK, gin.H{"success": true, "rules": out})
}
// MiniprogramUserRuleComplete POST /api/miniprogram/user-rules/complete
func MiniprogramUserRuleComplete(c *gin.Context) {
var body struct {
UserID string `json:"userId" binding:"required"`
RuleID uint `json:"ruleId" binding:"required"`
}
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "参数错误"})
return
}
db := database.DB()
comp := model.UserRuleCompletion{UserID: body.UserID, RuleID: body.RuleID}
result := db.Where("user_id = ? AND rule_id = ?", body.UserID, body.RuleID).FirstOrCreate(&comp)
if result.Error != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": result.Error.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "alreadyCompleted": result.RowsAffected == 0})
}
// DBUserRulesAction POST/PUT/DELETE /api/db/user-rules
func DBUserRulesAction(c *gin.Context) {
db := database.DB()
switch c.Request.Method {
case http.MethodPost:
var body struct {
Title string `json:"title" binding:"required"`
Description string `json:"description"`
Trigger string `json:"trigger"`
TriggerConditions interface{} `json:"triggerConditions"`
ActionType string `json:"actionType"`
ActionConfig interface{} `json:"actionConfig"`
Sort int `json:"sort"`
Enabled *bool `json:"enabled"`
}
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "参数错误"})
return
}
enabled := true
if body.Enabled != nil {
enabled = *body.Enabled
}
rule := model.UserRule{
Title: trimSpace(body.Title),
Description: body.Description,
Trigger: trimSpace(body.Trigger),
ActionType: trimSpace(body.ActionType),
Sort: body.Sort,
Enabled: enabled,
}
if body.TriggerConditions != nil {
if b, err := json.Marshal(body.TriggerConditions); err == nil {
rule.TriggerConditions = b
}
}
if body.ActionConfig != nil {
if b, err := json.Marshal(body.ActionConfig); err == nil {
rule.ActionConfig = b
}
}
if err := db.Create(&rule).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true, "rule": rule})
case http.MethodPut:
var body struct {
ID uint `json:"id" binding:"required"`
Title string `json:"title"`
Description string `json:"description"`
Trigger string `json:"trigger"`
TriggerConditions interface{} `json:"triggerConditions"`
ActionType string `json:"actionType"`
ActionConfig interface{} `json:"actionConfig"`
Sort *int `json:"sort"`
Enabled *bool `json:"enabled"`
}
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "参数错误"})
return
}
var rule model.UserRule
if err := db.First(&rule, body.ID).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"success": false, "error": "规则不存在"})
return
}
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
updates := make(map[string]interface{})
if body.Title != "" {
updates["title"] = trimSpace(body.Title)
}
updates["description"] = body.Description
updates["trigger"] = trimSpace(body.Trigger)
updates["action_type"] = trimSpace(body.ActionType)
if body.TriggerConditions != nil {
if b, err := json.Marshal(body.TriggerConditions); err == nil {
updates["trigger_conditions"] = string(b)
}
}
if body.ActionConfig != nil {
if b, err := json.Marshal(body.ActionConfig); err == nil {
updates["action_config"] = string(b)
}
}
if body.Sort != nil {
updates["sort"] = *body.Sort
}
if body.Enabled != nil {
updates["enabled"] = *body.Enabled
}
if err := db.Model(&rule).Updates(updates).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
var updated model.UserRule
_ = db.First(&updated, body.ID)
c.JSON(http.StatusOK, gin.H{"success": true, "rule": updated})
case http.MethodDelete:
idStr := c.Query("id")
if idStr == "" {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "缺少 id"})
return
}
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "id 无效"})
return
}
if err := db.Delete(&model.UserRule{}, uint(id)).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true})
default:
c.JSON(http.StatusMethodNotAllowed, gin.H{"success": false, "error": "方法不支持"})
}
}