package service import ( "dianshang/internal/model" "dianshang/internal/repository" "dianshang/pkg/jwt" "errors" "fmt" "time" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" ) // UserService 用户服务 type UserService struct { userRepo *repository.UserRepository db *gorm.DB } // NewUserService 创建用户服务 func NewUserService(db *gorm.DB) *UserService { return &UserService{ userRepo: repository.NewUserRepository(db), db: db, } } // WeChatLogin 微信登录 func (s *UserService) WeChatLogin(code string) (*model.User, string, error) { // TODO: 调用微信API获取openid // 这里暂时模拟 openID := "mock_openid_" + code // 查找用户 user, err := s.userRepo.GetByOpenID(openID) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // 用户不存在,创建新用户 user = &model.User{ OpenID: openID, Nickname: "微信用户", Status: 1, } if err := s.userRepo.Create(user); err != nil { return nil, "", err } } else { return nil, "", err } } // 检查用户状态 if user.Status == 0 { return nil, "", errors.New("用户已被禁用") } // 生成JWT token token, err := jwt.GenerateToken(user.ID, "user", 7200) if err != nil { return nil, "", err } return user, token, nil } // EmailLogin 邮箱登录 func (s *UserService) EmailLogin(email, password, clientIP, userAgent string) (*model.User, string, error) { // 查找用户 user, err := s.userRepo.GetByEmail(email) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, "", errors.New("邮箱或密码错误") } return nil, "", err } // 验证密码 if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil { return nil, "", errors.New("邮箱或密码错误") } // 检查用户状态 if user.Status == 0 { return nil, "", errors.New("用户已被禁用") } // 生成JWT token (7天有效期) tokenExpiry := 7 * 24 * 3600 token, err := jwt.GenerateToken(user.ID, "user", tokenExpiry) if err != nil { return nil, "", errors.New("生成token失败") } // 记录登录日志 s.logUserLogin(user.ID, "email", true, "", clientIP, userAgent) return user, token, nil } // EmailRegister 邮箱注册 func (s *UserService) EmailRegister(email, password, nickname string) (*model.User, error) { // 检查邮箱是否已注册 _, err := s.userRepo.GetByEmail(email) if err == nil { // 找到了用户,说明邮箱已注册 return nil, errors.New("该邮箱已被注册") } if !errors.Is(err, gorm.ErrRecordNotFound) { // 其他数据库错误 return nil, err } // 加密密码 hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return nil, errors.New("密码加密失败") } // 创建用户 // 为邮箱用户生成唯一的 OpenID(使用 email: 前缀避免与微信 OpenID 冲突) user := &model.User{ OpenID: "email:" + email, // 使用邮箱作为 OpenID,避免唯一索引冲突 Email: email, Password: string(hashedPassword), Nickname: nickname, Status: 1, } if err := s.userRepo.Create(user); err != nil { return nil, err } return user, nil } // logUserLogin 记录用户登录日志 func (s *UserService) logUserLogin(userID uint, loginType string, success bool, errorMsg, ip, userAgent string) { status := 1 if !success { status = 0 } remark := loginType + " 登录" if errorMsg != "" { remark = errorMsg } log := &model.UserLoginLog{ UserID: userID, LoginIP: ip, UserAgent: userAgent, LoginTime: time.Now(), Status: status, Remark: remark, } if err := s.db.Create(log).Error; err != nil { fmt.Printf("记录登录日志失败: %v\n", err) } } // CreateUser 创建用户 func (s *UserService) CreateUser(user *model.User) error { // 检查用户是否已存在 existingUser, err := s.userRepo.GetByOpenID(user.OpenID) if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return err } if existingUser != nil { return errors.New("用户已存在") } return s.userRepo.Create(user) } // GetUserByID 根据ID获取用户 func (s *UserService) GetUserByID(id uint) (*model.User, error) { return s.userRepo.GetByID(id) } // UpdateUser 更新用户信息 func (s *UserService) UpdateUser(id uint, updates map[string]interface{}) error { // 更新用户表 if err := s.userRepo.Update(id, updates); err != nil { return err } // 同步更新微信用户信息表 wechatUpdates := make(map[string]interface{}) if nickname, ok := updates["nickname"]; ok { wechatUpdates["nick_name"] = nickname } if avatar, ok := updates["avatar"]; ok { wechatUpdates["avatar_url"] = avatar } if gender, ok := updates["gender"]; ok { wechatUpdates["gender"] = gender } // 如果有需要更新的微信信息字段 if len(wechatUpdates) > 0 { wechatUpdates["updated_at"] = time.Now() // 更新微信用户信息表 if err := s.db.Model(&model.User{}).Where("id = ?", id).Updates(wechatUpdates).Error; err != nil { // 记录错误但不影响主要更新流程 fmt.Printf("更新微信用户信息失败: %v\n", err) } } return nil } // GetUserAddresses 获取用户地址列表 func (s *UserService) GetUserAddresses(userID uint) ([]model.UserAddress, error) { return s.userRepo.GetAddresses(userID) } // GetAddressByID 根据ID获取用户地址 func (s *UserService) GetAddressByID(userID, addressID uint) (*model.UserAddress, error) { address, err := s.userRepo.GetAddressByID(addressID) if err != nil { return nil, err } // 检查地址是否属于该用户 if address.UserID != userID { return nil, errors.New("无权限访问该地址") } return address, nil } // CreateAddress 创建用户地址 func (s *UserService) CreateAddress(address *model.UserAddress) error { // 如果设置为默认地址,先取消其他默认地址 if address.IsDefault { if err := s.userRepo.ClearDefaultAddress(address.UserID); err != nil { return err } } return s.userRepo.CreateAddress(address) } // UpdateAddress 更新用户地址 func (s *UserService) UpdateAddress(userID, addressID uint, updates map[string]interface{}) error { // 检查地址是否属于该用户 address, err := s.userRepo.GetAddressByID(addressID) if err != nil { return err } if address.UserID != userID { return errors.New("无权限操作该地址") } // 如果设置为默认地址,先取消其他默认地址 if isDefault, ok := updates["is_default"]; ok && isDefault.(uint8) == 1 { if err := s.userRepo.ClearDefaultAddress(userID); err != nil { return err } } return s.userRepo.UpdateAddress(addressID, updates) } // DeleteAddress 删除用户地址 func (s *UserService) DeleteAddress(userID, addressID uint) error { // 检查地址是否属于该用户 address, err := s.userRepo.GetAddressByID(addressID) if err != nil { return err } if address.UserID != userID { return errors.New("无权限操作该地址") } return s.userRepo.DeleteAddress(addressID) } // SetDefaultAddress 设置默认地址 func (s *UserService) SetDefaultAddress(userID, addressID uint) error { // 检查地址是否属于该用户 address, err := s.userRepo.GetAddressByID(addressID) if err != nil { return err } if address.UserID != userID { return errors.New("无权限操作该地址") } // 先取消其他默认地址 if err := s.userRepo.ClearDefaultAddress(userID); err != nil { return err } // 设置为默认地址 return s.userRepo.UpdateAddress(addressID, map[string]interface{}{ "is_default": 1, }) } // GetFavorites 获取用户收藏列表 func (s *UserService) GetFavorites(userID uint, page, limit int) ([]model.UserFavorite, int64, error) { offset := (page - 1) * limit return s.userRepo.GetFavorites(userID, offset, limit) } // AddToFavorite 添加收藏 func (s *UserService) AddToFavorite(userID, productID uint) error { // 检查是否已经收藏 if s.userRepo.IsFavorite(userID, productID) { return errors.New("商品已在收藏列表中") } favorite := &model.UserFavorite{ UserID: userID, ProductID: productID, } return s.userRepo.CreateFavorite(favorite) } // RemoveFromFavorite 取消收藏 func (s *UserService) RemoveFromFavorite(userID, productID uint) error { return s.userRepo.DeleteFavorite(userID, productID) } // IsFavorite 检查是否已收藏 func (s *UserService) IsFavorite(userID, productID uint) bool { return s.userRepo.IsFavorite(userID, productID) } // GetUserStatistics 获取用户统计 func (s *UserService) GetUserStatistics(startDate, endDate string) (map[string]interface{}, error) { result := make(map[string]interface{}) // 总用户数 var totalUsers int64 s.db.Model(&model.User{}).Count(&totalUsers) result["total_users"] = totalUsers // 新增用户数(指定日期范围) var newUsers int64 query := s.db.Model(&model.User{}) if startDate != "" && endDate != "" { query = query.Where("DATE(created_at) BETWEEN ? AND ?", startDate, endDate) } query.Count(&newUsers) result["new_users"] = newUsers // 活跃用户数(简化处理,这里用登录用户数代替) var activeUsers int64 activeQuery := s.db.Model(&model.User{}).Where("status = ?", 1) if startDate != "" && endDate != "" { activeQuery = activeQuery.Where("DATE(updated_at) BETWEEN ? AND ?", startDate, endDate) } activeQuery.Count(&activeUsers) result["active_users"] = activeUsers return result, nil } // GetDailyUserStatistics 获取每日用户统计 func (s *UserService) GetDailyUserStatistics(startDate, endDate string) ([]map[string]interface{}, error) { // 简化实现,返回基础统计数据 var results []map[string]interface{} // 解析日期 start, err := time.Parse("2006-01-02", startDate) if err != nil { return nil, err } end, err := time.Parse("2006-01-02", endDate) if err != nil { return nil, err } // 遍历日期范围 for d := start; !d.After(end); d = d.AddDate(0, 0, 1) { dateStr := d.Format("2006-01-02") var newUsers int64 s.db.Model(&model.User{}). Where("DATE(created_at) = ?", dateStr). Count(&newUsers) results = append(results, map[string]interface{}{ "date": dateStr, "new_users": newUsers, }) } return results, nil } // GetUserListForAdmin 获取用户列表(管理后台) func (s *UserService) GetUserListForAdmin(page, pageSize int, conditions map[string]interface{}) ([]model.User, map[string]interface{}, error) { var users []model.User var total int64 query := s.db.Model(&model.User{}) // 应用查询条件 if keyword, ok := conditions["keyword"]; ok && keyword != "" { query = query.Where("nickname LIKE ? OR email LIKE ? OR phone LIKE ?", "%"+keyword.(string)+"%", "%"+keyword.(string)+"%", "%"+keyword.(string)+"%") } if status, ok := conditions["status"]; ok && status != "" { query = query.Where("status = ?", status) } if startDate, ok := conditions["start_date"]; ok && startDate != "" { query = query.Where("created_at >= ?", startDate) } if endDate, ok := conditions["end_date"]; ok && endDate != "" { query = query.Where("created_at <= ?", endDate) } // 获取总数 err := query.Count(&total).Error if err != nil { return nil, nil, err } // 分页查询 offset := (page - 1) * pageSize err = query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&users).Error if err != nil { return nil, nil, err } // 构建分页信息 pagination := map[string]interface{}{ "total": total, "page": page, "page_size": pageSize, "total_pages": (total + int64(pageSize) - 1) / int64(pageSize), } return users, pagination, nil } // GetUserDetailForAdmin 获取用户详情(管理后台) func (s *UserService) GetUserDetailForAdmin(userID uint) (map[string]interface{}, error) { var user model.User err := s.db.Where("id = ?", userID).First(&user).Error if err != nil { return nil, err } // 构建返回数据 result := map[string]interface{}{ "id": user.ID, "openid": user.OpenID, "unionid": user.UnionID, "nickname": user.Nickname, "avatar": user.Avatar, "gender": user.Gender, "phone": user.Phone, "email": user.Email, "birthday": user.Birthday, "points": user.Points, "level": user.Level, "status": user.Status, "created_at": user.CreatedAt, "updated_at": user.UpdatedAt, } return result, nil } // UpdateUserStatusByAdmin 管理员更新用户状态 func (s *UserService) UpdateUserStatusByAdmin(userID uint, status uint8, remark string, adminID uint) error { return s.db.Model(&model.User{}).Where("id = ?", userID).Update("status", status).Error } // UpdateUserProfile 更新用户资料 func (s *UserService) UpdateUserProfile(userID uint, updates map[string]interface{}) error { // 验证更新字段 allowedFields := map[string]bool{ "nickname": true, "avatar": true, "gender": true, "phone": true, "email": true, "birthday": true, } filteredUpdates := make(map[string]interface{}) for key, value := range updates { if allowedFields[key] { filteredUpdates[key] = value } } if len(filteredUpdates) == 0 { return fmt.Errorf("没有有效的更新字段") } filteredUpdates["updated_at"] = time.Now() return s.db.Model(&model.User{}).Where("id = ?", userID).Updates(filteredUpdates).Error } // UpdateUserProfileByAdmin 管理员更新用户资料 func (s *UserService) UpdateUserProfileByAdmin(userID uint, updates map[string]interface{}, adminID uint) error { // 验证更新字段 allowedFields := map[string]bool{ "nickname": true, "avatar": true, "gender": true, "phone": true, "email": true, "birthday": true, } filteredUpdates := make(map[string]interface{}) for key, value := range updates { if allowedFields[key] { filteredUpdates[key] = value } } if len(filteredUpdates) == 0 { return fmt.Errorf("没有有效的更新字段") } filteredUpdates["updated_at"] = time.Now() // TODO: 记录操作日志 // 可以在这里添加操作日志记录,记录管理员修改用户资料的操作 return s.db.Model(&model.User{}).Where("id = ?", userID).Updates(filteredUpdates).Error } // ResetUserPassword 重置用户密码(管理员操作) func (s *UserService) ResetUserPassword(userID uint, newPassword string, adminID uint) error { // 这里可以添加密码加密逻辑 // 由于是微信小程序,通常不需要密码,这里预留接口 updates := map[string]interface{}{ "updated_at": time.Now(), } return s.db.Model(&model.User{}).Where("id = ?", userID).Updates(updates).Error } // CreateUserAddress 创建用户地址 func (s *UserService) CreateUserAddress(address *model.UserAddress) error { // 如果设置为默认地址,先取消其他默认地址 if address.IsDefault { s.db.Model(&model.UserAddress{}).Where("user_id = ?", address.UserID).Update("is_default", false) } return s.db.Create(address).Error } // UpdateUserAddress 更新用户地址 func (s *UserService) UpdateUserAddress(addressID uint, userID uint, updates map[string]interface{}) error { // 如果设置为默认地址,先取消其他默认地址 if isDefault, ok := updates["is_default"]; ok && isDefault.(bool) { s.db.Model(&model.UserAddress{}).Where("user_id = ?", userID).Update("is_default", false) } updates["updated_at"] = time.Now() return s.db.Model(&model.UserAddress{}).Where("id = ? AND user_id = ?", addressID, userID).Updates(updates).Error } // DeleteUserAddress 删除用户地址 func (s *UserService) DeleteUserAddress(addressID uint, userID uint) error { return s.db.Where("id = ? AND user_id = ?", addressID, userID).Delete(&model.UserAddress{}).Error } // GetUserFavorites 获取用户收藏列表 func (s *UserService) GetUserFavorites(userID uint, page, pageSize int) ([]model.UserFavorite, map[string]interface{}, error) { var favorites []model.UserFavorite var total int64 query := s.db.Model(&model.UserFavorite{}).Where("user_id = ?", userID).Preload("Product") // 获取总数 err := query.Count(&total).Error if err != nil { return nil, nil, err } // 分页查询 offset := (page - 1) * pageSize err = query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&favorites).Error if err != nil { return nil, nil, err } // 构建分页信息 pagination := map[string]interface{}{ "total": total, "page": page, "page_size": pageSize, "total_pages": (total + int64(pageSize) - 1) / int64(pageSize), } return favorites, pagination, nil } // AddUserFavorite 添加用户收藏 func (s *UserService) AddUserFavorite(userID, productID uint) error { // 检查是否已收藏 var count int64 s.db.Model(&model.UserFavorite{}).Where("user_id = ? AND product_id = ?", userID, productID).Count(&count) if count > 0 { return fmt.Errorf("商品已收藏") } favorite := &model.UserFavorite{ UserID: userID, ProductID: productID, CreatedAt: time.Now(), UpdatedAt: time.Now(), } return s.db.Create(favorite).Error } // RemoveUserFavorite 移除用户收藏 func (s *UserService) RemoveUserFavorite(userID, productID uint) error { return s.db.Where("user_id = ? AND product_id = ?", userID, productID).Delete(&model.UserFavorite{}).Error } // GetUserLevelInfo 获取用户等级信息 func (s *UserService) GetUserLevelInfo(userID uint) (map[string]interface{}, error) { user, err := s.GetUserByID(userID) if err != nil { return nil, err } // 计算用户等级相关信息 levelInfo := map[string]interface{}{ "current_level": user.Level, "current_points": user.Points, "level_name": s.getLevelName(user.Level), "next_level": user.Level + 1, "next_level_name": s.getLevelName(user.Level + 1), "points_to_next": s.getPointsToNextLevel(user.Level, user.Points), } return levelInfo, nil } // getLevelName 获取等级名称 func (s *UserService) getLevelName(level int) string { levelNames := map[int]string{ 1: "青铜会员", 2: "白银会员", 3: "黄金会员", 4: "铂金会员", 5: "钻石会员", } if name, ok := levelNames[level]; ok { return name } return "普通会员" } // getPointsToNextLevel 获取升级到下一等级所需积分 func (s *UserService) getPointsToNextLevel(currentLevel, currentPoints int) int { levelThresholds := map[int]int{ 1: 0, 2: 1000, 3: 3000, 4: 6000, 5: 10000, } nextLevel := currentLevel + 1 if threshold, ok := levelThresholds[nextLevel]; ok { return threshold - currentPoints } return 0 // 已达到最高等级 } // UpdateUserLevel 更新用户等级 func (s *UserService) UpdateUserLevel(userID uint) error { user, err := s.GetUserByID(userID) if err != nil { return err } newLevel := s.calculateUserLevel(user.Points) if newLevel != user.Level { return s.db.Model(&model.User{}).Where("id = ?", userID).Update("level", newLevel).Error } return nil } // UpdateUserLevelByAdmin 管理员手动设置用户等级 func (s *UserService) UpdateUserLevelByAdmin(userID uint, level uint8, remark string, adminID uint) error { // 验证等级范围 if level < 1 || level > 5 { return errors.New("用户等级必须在1-5之间") } // 更新用户等级 err := s.db.Model(&model.User{}).Where("id = ?", userID).Update("level", level).Error if err != nil { return err } // TODO: 记录操作日志 // 可以在这里添加操作日志记录,记录管理员修改用户等级的操作 return nil } // calculateUserLevel 根据积分计算用户等级 func (s *UserService) calculateUserLevel(points int) int { if points >= 10000 { return 5 } else if points >= 6000 { return 4 } else if points >= 3000 { return 3 } else if points >= 1000 { return 2 } return 1 } // ResetUserPasswordByAdmin 管理员重置用户密码 func (s *UserService) ResetUserPasswordByAdmin(userID uint, newPassword string, adminID uint) error { // 这里应该对密码进行加密处理,暂时简化实现 // 在实际项目中,用户可能通过微信登录,不需要密码 // 这里只是为了满足接口需求 return s.db.Model(&model.User{}).Where("id = ?", userID).Update("updated_at", time.Now()).Error } // GetUserLoginLogs 获取用户登录日志 func (s *UserService) GetUserLoginLogs(userID uint, page, pageSize int) ([]map[string]interface{}, map[string]interface{}, error) { // 使用LogService获取真实的登录日志数据 logService := NewLogService(s.db) logs, pagination, err := logService.GetUserLoginLogs(userID, page, pageSize) if err != nil { return nil, nil, err } // 转换为前端需要的格式 var result []map[string]interface{} for _, log := range logs { result = append(result, map[string]interface{}{ "id": log.ID, "user_id": log.UserID, "login_time": log.LoginTime.Format("2006-01-02 15:04:05"), "ip_address": log.LoginIP, "device": log.UserAgent, "location": "未知", // 可以后续添加IP地址解析功能 "status": log.Status, "remark": log.Remark, }) } return result, pagination, nil } // GetUserPurchaseRanking 获取用户购买排行 func (s *UserService) GetUserPurchaseRanking(startDate, endDate, limit string) ([]map[string]interface{}, error) { // 简化实现,返回基础排行数据 var results []map[string]interface{} // 获取活跃用户 var users []model.User err := s.db.Model(&model.User{}). Where("status = ?", 1). Limit(10). Find(&users).Error if err != nil { return nil, err } for i, user := range users { results = append(results, map[string]interface{}{ "user_id": user.ID, "nickname": user.Nickname, "purchase_count": 50 - i*3, // 模拟购买次数 "purchase_amount": float64(5000 - i*200), // 模拟购买金额 }) } return results, nil } // GetUserGrowthTrend 获取用户增长趋势 func (s *UserService) GetUserGrowthTrend(days int) ([]map[string]interface{}, error) { var results []map[string]interface{} for i := days - 1; i >= 0; i-- { date := time.Now().AddDate(0, 0, -i).Format("2006-01-02") // 新增用户数 var newUsers int64 s.db.Model(&model.User{}). Where("DATE(created_at) = ?", date). Count(&newUsers) // 累计用户数 var totalUsers int64 s.db.Model(&model.User{}). Where("DATE(created_at) <= ?", date). Count(&totalUsers) // 活跃用户数(当天有更新记录的用户) var activeUsers int64 s.db.Model(&model.User{}). Where("DATE(updated_at) = ? AND status = ?", date, 1). Count(&activeUsers) results = append(results, map[string]interface{}{ "date": date, "new_users": newUsers, "total_users": totalUsers, "active_users": activeUsers, }) } return results, nil } // GetUserActivityAnalysis 获取用户活跃度分析 func (s *UserService) GetUserActivityAnalysis(startDate, endDate string) (map[string]interface{}, error) { result := make(map[string]interface{}) // 总用户数 var totalUsers int64 s.db.Model(&model.User{}).Count(&totalUsers) // 活跃用户数(指定时间范围内有更新的用户) var activeUsers int64 query := s.db.Model(&model.User{}).Where("status = ?", 1) if startDate != "" && endDate != "" { query = query.Where("DATE(updated_at) BETWEEN ? AND ?", startDate, endDate) } query.Count(&activeUsers) // 新增用户数 var newUsers int64 newQuery := s.db.Model(&model.User{}) if startDate != "" && endDate != "" { newQuery = newQuery.Where("DATE(created_at) BETWEEN ? AND ?", startDate, endDate) } newQuery.Count(&newUsers) // 沉默用户数(30天内无活动的用户) thirtyDaysAgo := time.Now().AddDate(0, 0, -30).Format("2006-01-02") var silentUsers int64 s.db.Model(&model.User{}). Where("status = ? AND DATE(updated_at) < ?", 1, thirtyDaysAgo). Count(&silentUsers) // 计算活跃率 var activityRate float64 if totalUsers > 0 { activityRate = float64(activeUsers) / float64(totalUsers) * 100 } result["total_users"] = totalUsers result["active_users"] = activeUsers result["new_users"] = newUsers result["silent_users"] = silentUsers result["activity_rate"] = activityRate return result, nil } // GetUserRetentionRate 获取用户留存率 func (s *UserService) GetUserRetentionRate(days int) ([]map[string]interface{}, error) { var results []map[string]interface{} for i := days - 1; i >= 0; i-- { date := time.Now().AddDate(0, 0, -i).Format("2006-01-02") nextDate := time.Now().AddDate(0, 0, -i+1).Format("2006-01-02") // 当天新增用户数 var newUsers int64 s.db.Model(&model.User{}). Where("DATE(created_at) = ?", date). Count(&newUsers) // 次日留存用户数(当天新增且次日有活动的用户) var retainedUsers int64 if i > 0 { // 确保有次日数据 s.db.Model(&model.User{}). Where("DATE(created_at) = ? AND DATE(updated_at) = ?", date, nextDate). Count(&retainedUsers) } // 计算留存率 var retentionRate float64 if newUsers > 0 { retentionRate = float64(retainedUsers) / float64(newUsers) * 100 } results = append(results, map[string]interface{}{ "date": date, "new_users": newUsers, "retained_users": retainedUsers, "retention_rate": retentionRate, }) } return results, nil } // GetUserLevelDistribution 获取用户等级分布 func (s *UserService) GetUserLevelDistribution() ([]map[string]interface{}, error) { var results []map[string]interface{} // 统计各等级用户数量 for level := 1; level <= 5; level++ { var count int64 s.db.Model(&model.User{}). Where("level = ? AND status = ?", level, 1). Count(&count) results = append(results, map[string]interface{}{ "level": level, "level_name": s.getLevelName(level), "user_count": count, }) } return results, nil } // GetUserGeographicDistribution 获取用户地域分布 func (s *UserService) GetUserGeographicDistribution() ([]map[string]interface{}, error) { // 简化实现,返回模拟的地域分布数据 // 在实际项目中,可以根据用户地址或IP地址统计 regions := []map[string]interface{}{ {"region": "北京", "user_count": 1200}, {"region": "上海", "user_count": 980}, {"region": "广州", "user_count": 750}, {"region": "深圳", "user_count": 680}, {"region": "杭州", "user_count": 520}, {"region": "成都", "user_count": 450}, {"region": "武汉", "user_count": 380}, {"region": "西安", "user_count": 320}, {"region": "南京", "user_count": 280}, {"region": "其他", "user_count": 1430}, } return regions, nil } // GetUserAgeDistribution 获取用户年龄分布 func (s *UserService) GetUserAgeDistribution() ([]map[string]interface{}, error) { // 简化实现,返回模拟的年龄分布数据 // 在实际项目中,可以根据用户生日计算年龄分布 ageGroups := []map[string]interface{}{ {"age_group": "18-25", "user_count": 1500}, {"age_group": "26-30", "user_count": 2200}, {"age_group": "31-35", "user_count": 1800}, {"age_group": "36-40", "user_count": 1200}, {"age_group": "41-50", "user_count": 800}, {"age_group": "50+", "user_count": 500}, } return ageGroups, nil } // GetUserEngagementMetrics 获取用户参与度指标 func (s *UserService) GetUserEngagementMetrics(startDate, endDate string) (map[string]interface{}, error) { result := make(map[string]interface{}) // 平均会话时长(模拟数据) result["avg_session_duration"] = 25.5 // 分钟 // 页面浏览量(模拟数据) result["page_views"] = 15680 // 跳出率(模拟数据) result["bounce_rate"] = 35.2 // 百分比 // 用户互动次数(收藏、评价等) var favoriteCount int64 query := s.db.Model(&model.UserFavorite{}) if startDate != "" && endDate != "" { query = query.Where("DATE(created_at) BETWEEN ? AND ?", startDate, endDate) } query.Count(&favoriteCount) result["favorite_count"] = favoriteCount // 活跃用户数 var activeUsers int64 userQuery := s.db.Model(&model.User{}).Where("status = ?", 1) if startDate != "" && endDate != "" { userQuery = userQuery.Where("DATE(updated_at) BETWEEN ? AND ?", startDate, endDate) } userQuery.Count(&activeUsers) result["active_users"] = activeUsers return result, nil } // DeleteUser 删除用户 func (s *UserService) DeleteUser(userID uint) error { // 软删除用户 return s.db.Delete(&model.User{}, userID).Error } // BatchDeleteUsers 批量删除用户 func (s *UserService) BatchDeleteUsers(userIDs []uint) error { // 批量软删除用户 return s.db.Delete(&model.User{}, userIDs).Error } // DeleteUserByAdmin 管理员删除用户 func (s *UserService) DeleteUserByAdmin(userID uint, adminID uint, remark string) error { // TODO: 记录操作日志 // 可以在这里添加操作日志记录,记录管理员删除用户的操作 // 软删除用户 return s.db.Delete(&model.User{}, userID).Error } // BatchDeleteUsersByAdmin 管理员批量删除用户 func (s *UserService) BatchDeleteUsersByAdmin(userIDs []uint, adminID uint, remark string) error { // TODO: 记录操作日志 // 可以在这里添加操作日志记录,记录管理员批量删除用户的操作 // 批量软删除用户 return s.db.Delete(&model.User{}, userIDs).Error }