更新小程序配置,切换 API 地址为本地开发环境。新增会员详情页面的头像逻辑,确保用户信息展示一致性。优化多个页面的交互提示,提升用户体验。调整图标组件,更新图标映射以支持新样式。

This commit is contained in:
Alex-larget
2026-03-20 10:58:25 +08:00
parent 181f092402
commit e79152c80b
21 changed files with 658 additions and 158 deletions

View File

@@ -13,7 +13,6 @@ import (
"soul-api/internal/config"
"soul-api/internal/database"
"soul-api/internal/model"
"soul-api/internal/redis"
"github.com/gin-gonic/gin"
)
@@ -92,6 +91,20 @@ func buildMiniprogramConfig() gin.H {
}
}
}
// 价格以管理端「站点与作者」site_settings 为准(运营唯一配置入口),无则用 chapter_config 或默认值
var siteRow model.SystemConfig
if err := db.Where("config_key = ?", "site_settings").First(&siteRow).Error; err == nil && len(siteRow.ConfigValue) > 0 {
var siteVal map[string]interface{}
if err := json.Unmarshal(siteRow.ConfigValue, &siteVal); err == nil {
cur := out["prices"].(gin.H)
if v, ok := siteVal["sectionPrice"].(float64); ok && v > 0 {
cur["section"] = v
}
if v, ok := siteVal["baseBookPrice"].(float64); ok && v > 0 {
cur["fullbook"] = v
}
}
}
// 好友优惠(用于 read 页展示优惠价)
var refRow model.SystemConfig
if err := db.Where("config_key = ?", "referral_config").First(&refRow).Error; err == nil {
@@ -159,14 +172,8 @@ func GetPublicDBConfig(c *gin.Context) {
// GetAuditMode GET /api/miniprogram/config/audit-mode 审核模式独立接口,管理端开关后快速生效
// 缓存未命中时仅查 mp_config 一条记录,避免 buildMiniprogramConfig 全量查询导致超时
// Redis 时直接返回数据库中的 auditMode 值,保证可
// Redis 不可用时 cache 包自动降级到内存备
func GetAuditMode(c *gin.Context) {
// 无 Redis 时跳过缓存,直接返回数据库值
if redis.Client() == nil {
auditMode := getAuditModeFromDB()
c.JSON(http.StatusOK, gin.H{"auditMode": auditMode})
return
}
var cached gin.H
if cache.Get(context.Background(), cache.KeyConfigAuditMode, &cached) && len(cached) > 0 {
c.JSON(http.StatusOK, cached)

View File

@@ -610,6 +610,38 @@ func DBBookAction(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"success": true, "message": "已移动", "count": len(body.SectionIds)})
return
}
// update-chapter-pricing按篇+章批量更新该章下所有「节」行的 price / is_free管理端章节统一定价
if body.Action == "update-chapter-pricing" {
if body.PartID == "" || body.ChapterID == "" {
c.JSON(http.StatusOK, gin.H{"success": false, "error": "缺少 partId 或 chapterId"})
return
}
p := 1.0
if body.Price != nil {
p = *body.Price
}
free := false
if body.IsFree != nil {
free = *body.IsFree
}
if free {
p = 0
}
up := map[string]interface{}{
"price": p,
"is_free": free,
}
res := db.Model(&model.Chapter{}).Where("part_id = ? AND chapter_id = ?", body.PartID, body.ChapterID).Updates(up)
if res.Error != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": res.Error.Error()})
return
}
cache.InvalidateBookParts()
InvalidateChaptersByPartCache()
cache.InvalidateBookCache()
c.JSON(http.StatusOK, gin.H{"success": true, "message": "已更新本章全部节的定价", "affected": res.RowsAffected})
return
}
if body.ID == "" {
c.JSON(http.StatusOK, gin.H{"success": false, "error": "缺少 id"})
return