更新文档,新增输入框样式最佳实践,强调在小程序和管理端开发中使用容器包裹输入框以避免布局问题。调整经验库,记录相关最佳实践和开发进度,确保团队共享经验的一致性和可追溯性。优化小程序页面,增加分享功能,提升用户体验。

This commit is contained in:
Alex-larget
2026-02-27 14:22:58 +08:00
parent 31f4e37345
commit 8655dca7b4
34 changed files with 514 additions and 142 deletions

View File

@@ -757,22 +757,17 @@ func MiniprogramUsers(c *gin.Context) {
var cnt int64
db.Model(&model.Order{}).Where("user_id = ? AND status = ? AND (product_type = ? OR product_type = ?)",
id, "paid", "fullbook", "vip").Count(&cnt)
nick := getStringValue(user.Nickname)
avatar := getStringValue(user.Avatar)
contact := getStringValue(user.Phone)
if contact == "" {
contact = getStringValue(user.WechatID)
}
// 用户信息nickname/avatar与会员资料vip*)区分,字段与 model 一致camelCase
item := gin.H{
"id": user.ID,
"nickname": nick,
"avatar": avatar,
"vip_name": nick,
"vip_avatar": avatar,
"vip_contact": contact,
"vip_project": "",
"vip_bio": "",
"is_vip": cnt > 0,
"id": user.ID,
"nickname": getStringValue(user.Nickname),
"avatar": getStringValue(user.Avatar),
"vipName": getStringValue(user.VipName),
"vipAvatar": getStringValue(user.VipAvatar),
"vipContact": getStringValue(user.VipContact),
"vipProject": getStringValue(user.VipProject),
"vipBio": getStringValue(user.VipBio),
"is_vip": cnt > 0,
}
c.JSON(http.StatusOK, gin.H{"success": true, "data": item})
return

View File

@@ -80,7 +80,7 @@ func VipStatus(c *gin.Context) {
"isVip": false,
"daysRemaining": 0,
"expireDate": "",
"profile": gin.H{"name": "", "project": "", "contact": "", "avatar": "", "bio": ""},
"profile": gin.H{"vipName": "", "vipProject": "", "vipContact": "", "vipAvatar": "", "vipBio": ""},
"price": float64(defaultVipPrice),
"rights": defaultVipRights,
},
@@ -117,36 +117,23 @@ func VipStatus(c *gin.Context) {
})
}
// buildVipProfile 仅从 vip_* 字段构建会员资料不混入用户信息nickname/avatar/phone/wechat_id
// 返回字段与 users 表 vip_* 对应,统一 vipName/vipProject/vipContact/vipAvatar/vipBio
func buildVipProfile(u *model.User) gin.H {
name, project, contact, avatar, bio := "", "", "", "", ""
if u.VipName != nil && *u.VipName != "" {
name = *u.VipName
return gin.H{
"vipName": getStr(u.VipName),
"vipProject": getStr(u.VipProject),
"vipContact": getStr(u.VipContact),
"vipAvatar": getStr(u.VipAvatar),
"vipBio": getStr(u.VipBio),
}
if name == "" && u.Nickname != nil {
name = *u.Nickname
}
func getStr(s *string) string {
if s == nil {
return ""
}
if u.VipProject != nil {
project = *u.VipProject
}
if u.VipContact != nil {
contact = *u.VipContact
}
if contact == "" && u.Phone != nil {
contact = *u.Phone
}
if contact == "" && u.WechatID != nil {
contact = *u.WechatID
}
if u.VipAvatar != nil && *u.VipAvatar != "" {
avatar = *u.VipAvatar
}
if avatar == "" && u.Avatar != nil {
avatar = *u.Avatar
}
if u.VipBio != nil {
bio = *u.VipBio
}
return gin.H{"name": name, "project": project, "contact": contact, "avatar": avatar, "bio": bio}
return *s
}
// VipProfileGet GET /api/miniprogram/vip/profile 小程序-获取 VIP 资料
@@ -159,7 +146,7 @@ func VipProfileGet(c *gin.Context) {
db := database.DB()
var user model.User
if err := db.Where("id = ?", userID).First(&user).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": true, "data": gin.H{"name": "", "project": "", "contact": "", "avatar": "", "bio": ""}})
c.JSON(http.StatusOK, gin.H{"success": true, "data": gin.H{"vipName": "", "vipProject": "", "vipContact": "", "vipAvatar": "", "vipBio": ""}})
return
}
c.JSON(http.StatusOK, gin.H{
@@ -169,15 +156,15 @@ func VipProfileGet(c *gin.Context) {
}
// VipProfilePost POST /api/miniprogram/vip/profile 小程序-更新 VIP 资料
// 仅 VIP 会员可更新,更新 vip_name/vip_avatar/vip_project/vip_contact/vip_bio
// 请求/响应字段与 users 表 vip_* 一致vipName/vipProject/vipContact/vipAvatar/vipBio
func VipProfilePost(c *gin.Context) {
var req struct {
UserID string `json:"userId" binding:"required"`
Name string `json:"name"`
Project string `json:"project"`
Contact string `json:"contact"`
Avatar string `json:"avatar"`
Bio string `json:"bio"`
UserID string `json:"userId" binding:"required"`
VipName string `json:"vipName"`
VipProject string `json:"vipProject"`
VipContact string `json:"vipContact"`
VipAvatar string `json:"vipAvatar"`
VipBio string `json:"vipBio"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": "请求体无效"})
@@ -196,20 +183,20 @@ func VipProfilePost(c *gin.Context) {
}
updates := map[string]interface{}{}
if req.Name != "" {
updates["vip_name"] = req.Name
if req.VipName != "" {
updates["vip_name"] = req.VipName
}
if req.Project != "" {
updates["vip_project"] = req.Project
if req.VipProject != "" {
updates["vip_project"] = req.VipProject
}
if req.Contact != "" {
updates["vip_contact"] = req.Contact
if req.VipContact != "" {
updates["vip_contact"] = req.VipContact
}
if req.Avatar != "" {
updates["vip_avatar"] = req.Avatar
if req.VipAvatar != "" {
updates["vip_avatar"] = req.VipAvatar
}
if req.Bio != "" {
updates["vip_bio"] = req.Bio
if req.VipBio != "" {
updates["vip_bio"] = req.VipBio
}
if len(updates) == 0 {
c.JSON(http.StatusOK, gin.H{"success": false, "error": "无更新内容"})
@@ -284,24 +271,20 @@ func VipMembers(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"success": true, "data": list, "total": len(list)})
}
// formatVipMember 仅从 vip_* 字段构建会员展示数据,不混入用户信息
// 用于创业老板排行等场景;未填会员资料时 name 显示「创业者」占位
func formatVipMember(u *model.User, isVip bool) gin.H {
name := ""
if u.VipName != nil && *u.VipName != "" {
if u.VipName != nil {
name = *u.VipName
}
if name == "" && u.Nickname != nil {
name = *u.Nickname
}
if name == "" {
name = "创业者"
}
avatar := ""
if u.VipAvatar != nil && *u.VipAvatar != "" {
if u.VipAvatar != nil {
avatar = *u.VipAvatar
}
if avatar == "" && u.Avatar != nil {
avatar = *u.Avatar
}
project := ""
if u.VipProject != nil {
project = *u.VipProject
@@ -314,28 +297,22 @@ func formatVipMember(u *model.User, isVip bool) gin.H {
if u.VipContact != nil {
contact = *u.VipContact
}
if contact == "" && u.Phone != nil {
contact = *u.Phone
}
if contact == "" && u.WechatID != nil {
contact = *u.WechatID
}
vipRole := ""
if u.VipRole != nil {
vipRole = *u.VipRole
}
return gin.H{
"id": u.ID,
"name": name,
"nickname": name,
"avatar": avatar,
"vip_name": name,
"vip_role": vipRole,
"vip_avatar": avatar,
"vip_project": project,
"vip_contact": contact,
"vip_bio": bio,
"is_vip": isVip,
"id": u.ID,
"name": name,
"nickname": name,
"avatar": avatar,
"vipName": name,
"vipRole": vipRole,
"vipAvatar": avatar,
"vipProject": project,
"vipContact": contact,
"vipBio": bio,
"is_vip": isVip,
}
}