Files
soul-yongping/soul-api/internal/handler/admin_user_rules.go
卡若 aca006e1b2 feat: 完成20260315用户管理3全部5个功能
1. 链接人和事:补充CKB_OPEN_API_KEY/ACCOUNT配置,新增fix-ckb批量创建获客计划API
2. 规则配置:打通DB规则与ruleEngine,新增/api/miniprogram/user-rules接口,
   ruleEngine改为从API动态加载规则并按enabled状态执行
3. 获客计划:修复获客数统计中personId/token不匹配导致永远为0的bug,
   管理端新增"修复CKB密钥"按钮
4. 支付问题:修复钱包充值和代付分享中openId缺失导致400错误,
   添加getOpenId()兜底逻辑
5. 朋友圈分享:shareToMoments改为复制文章前200字+省略号+手指箭头emoji

Made-with: Cursor
2026-03-15 23:00:42 +08:00

137 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handler
import (
"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})
}
// 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"`
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),
Sort: body.Sort,
Enabled: enabled,
}
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"`
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)
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": "方法不支持"})
}
}