chore: 以本地工作区为准全量快照同步 GitHub

包含小程序、管理端、soul-api、脚本与静态资源等当前本地全部已跟踪与新增文件(排除 .DS_Store 与 .obsidian)。

Made-with: Cursor
This commit is contained in:
卡若
2026-04-13 11:49:38 +08:00
parent 83375cc388
commit b5f5180654
142 changed files with 10684 additions and 2670 deletions

View File

@@ -169,7 +169,7 @@ func MiniprogramLogin(c *gin.Context) {
"id": user.ID,
"openId": getStringValue(user.OpenID),
"nickname": getStringValue(user.Nickname),
"avatar": resolveAvatarURL(getStringValue(user.Avatar)),
"avatar": resolveAvatarURLWithRequest(c, getStringValue(user.Avatar)),
"phone": getStringValue(user.Phone),
"wechatId": getStringValue(user.WechatID),
"referralCode": getStringValue(user.ReferralCode),
@@ -247,7 +247,7 @@ func MiniprogramDevLoginAs(c *gin.Context) {
"id": user.ID,
"openId": openID,
"nickname": getStringValue(user.Nickname),
"avatar": resolveAvatarURL(getStringValue(user.Avatar)),
"avatar": resolveAvatarURLWithRequest(c, getStringValue(user.Avatar)),
"phone": getStringValue(user.Phone),
"wechatId": getStringValue(user.WechatID),
"referralCode": getStringValue(user.ReferralCode),
@@ -329,7 +329,7 @@ func MiniprogramDevLoginByPhone(c *gin.Context) {
"id": user.ID,
"openId": openID,
"nickname": getStringValue(user.Nickname),
"avatar": resolveAvatarURL(getStringValue(user.Avatar)),
"avatar": resolveAvatarURLWithRequest(c, getStringValue(user.Avatar)),
"phone": getStringValue(user.Phone),
"wechatId": getStringValue(user.WechatID),
"referralCode": getStringValue(user.ReferralCode),
@@ -570,7 +570,7 @@ func miniprogramPayPost(c *gin.Context) {
case "balance_recharge":
description = fmt.Sprintf("余额充值 ¥%.2f", finalAmount)
case "fullbook":
description = "《一场Soul的创业实验》全书"
description = "加入读书会"
case "vip":
description = "卡若创业派对VIP年度会员365天"
case "match":
@@ -1236,22 +1236,18 @@ func MiniprogramUsers(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"success": true, "data": nil})
return
}
// V4.1 修复is_vip 同时校验过期时间is_vip=1 且 vip_expire_date>NOW而非仅凭订单数量
isVipActive, _ := isVipFromUsers(db, id)
if !isVipActive {
// 兜底orders 表有有效 VIP 订单
isVipActive, _ = isVipFromOrders(db, id)
}
// 与 /vip/status 一致:显式 is_vip=false 时不认订单兜底
isVipActive, _ := isVipEffective(db, id)
// 用户信息与会员资料vip*、P3 资料扩展,供会员详情页完整展示
item := gin.H{
"id": user.ID,
"ckbLeadToken": personLeadTokenByUserID(db, user.ID),
"nickname": getStringValue(user.Nickname),
"avatar": resolveAvatarURL(getStringValue(user.Avatar)),
"avatar": resolveAvatarURLWithRequest(c, getStringValue(user.Avatar)),
"phone": getStringValue(user.Phone),
"wechatId": getStringValue(user.WechatID),
"vipName": getStringValue(user.VipName),
"vipAvatar": resolveAvatarURL(getStringValue(user.VipAvatar)),
"vipAvatar": resolveAvatarURLWithRequest(c, getStringValue(user.VipAvatar)),
"vipContact": getStringValue(user.VipContact),
"vipProject": getStringValue(user.VipProject),
"vipBio": getStringValue(user.VipBio),
@@ -1278,15 +1274,11 @@ func MiniprogramUsers(c *gin.Context) {
list := make([]gin.H, 0, len(users))
for i := range users {
u := &users[i]
// V4.1is_vip 同时校验过期时间
uvip, _ := isVipFromUsers(db, u.ID)
if !uvip {
uvip, _ = isVipFromOrders(db, u.ID)
}
uvip, _ := isVipEffective(db, u.ID)
list = append(list, gin.H{
"id": u.ID,
"nickname": getStringValue(u.Nickname),
"avatar": resolveAvatarURL(getStringValue(u.Avatar)),
"avatar": resolveAvatarURLWithRequest(c, getStringValue(u.Avatar)),
"is_vip": uvip,
})
}
@@ -1694,8 +1686,19 @@ func getStandardPrice(db *gorm.DB, productType, productID string, tipSource ...s
}
switch productType {
case "fullbook", "vip", "match":
// 从 system_config 读取
// 价格来源要与对应前端配置端一致,防止小程序显示 1 元但后端用错价格。
// 价格来源要与小程序 buildMiniprogramConfig 一致fullbook 优先 site_settings.baseBookPrice管理端「站点与作者」
if productType == "fullbook" {
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 json.Unmarshal(siteRow.ConfigValue, &siteVal) == nil {
if v, ok := siteVal["baseBookPrice"].(float64); ok && v > 0 {
return v, nil
}
}
}
}
// 从 system_config 读取chapter_config / vip_config / match_config
configKey := "chapter_config"
if productType == "vip" {
configKey = "vip_config"
@@ -1742,7 +1745,7 @@ func getStandardPrice(db *gorm.DB, productType, productID string, tipSource ...s
}
}
// 兜底默认值
defaults := map[string]float64{"fullbook": 9.9, "vip": 1980, "match": 1}
defaults := map[string]float64{"fullbook": 365, "vip": 1980, "match": 1}
if p, ok := defaults[productType]; ok {
return p, nil
}