Browse Source

用户信息加载正常

master
hejl 1 week ago
parent
commit
b0805ea0fd
  1. 12
      gofaster/app/dist/renderer/js/index.js
  2. 10
      gofaster/app/src/renderer/modules/user-management/views/UserManagement.vue
  3. 11
      gofaster/backend/internal/auth/controller/auth_controller.go
  4. 3
      gofaster/backend/internal/auth/module.go
  5. 20
      gofaster/backend/internal/auth/repository/captcha_repo.go
  6. 14
      gofaster/backend/internal/auth/repository/user_repo.go
  7. 3
      gofaster/backend/internal/auth/routes/auth_routes.go
  8. 26
      gofaster/backend/internal/auth/service/auth_service.go
  9. 4
      gofaster/backend/internal/auth/service/user_service.go
  10. 7
      gofaster/backend/main.go
  11. 2
      gofaster/backend/tmp/build-errors.log
  12. BIN
      gofaster/backend/tmp/main.exe

12
gofaster/app/dist/renderer/js/index.js vendored

@ -6162,8 +6162,14 @@ __webpack_require__.r(__webpack_exports__);
try { try {
loading.value = true loading.value = true
const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_1__.userService.getUsers(currentPage.value, pageSize.value) const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_1__.userService.getUsers(currentPage.value, pageSize.value)
users.value = response.data // 修复数据结构访问
total.value = response.total users.value = response.data.data
total.value = response.data.total
console.log('🔍 [前台] 加载用户数据:', {
users: users.value,
total: total.value,
response: response.data
})
} catch (error) { } catch (error) {
console.error('加载用户失败:', error) console.error('加载用户失败:', error)
} finally { } finally {
@ -12008,7 +12014,7 @@ __webpack_require__.r(__webpack_exports__);
/******/ /******/
/******/ /* webpack/runtime/getFullHash */ /******/ /* webpack/runtime/getFullHash */
/******/ (() => { /******/ (() => {
/******/ __webpack_require__.h = () => ("b63c6a5f105c650f") /******/ __webpack_require__.h = () => ("d15b4267db1069bb")
/******/ })(); /******/ })();
/******/ /******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ /* webpack/runtime/hasOwnProperty shorthand */

10
gofaster/app/src/renderer/modules/user-management/views/UserManagement.vue

@ -229,8 +229,14 @@ export default {
try { try {
loading.value = true loading.value = true
const response = await userService.getUsers(currentPage.value, pageSize.value) const response = await userService.getUsers(currentPage.value, pageSize.value)
users.value = response.data // 访
total.value = response.total users.value = response.data.data
total.value = response.data.total
console.log('🔍 [前台] 加载用户数据:', {
users: users.value,
total: total.value,
response: response.data
})
} catch (error) { } catch (error) {
console.error('加载用户失败:', error) console.error('加载用户失败:', error)
} finally { } finally {

11
gofaster/backend/internal/auth/controller/auth_controller.go

@ -8,6 +8,7 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
"time"
"gofaster/internal/auth/model" "gofaster/internal/auth/model"
"gofaster/internal/auth/service" "gofaster/internal/auth/service"
@ -47,7 +48,7 @@ func (c *AuthController) Login(ctx *gin.Context) {
} }
// 调用服务层处理登录 // 调用服务层处理登录
resp, err := c.authService.Login(ctx, req.Username, req.Password) resp, err := c.authService.Login(ctx, req.Username, req.Password, req.Captcha, req.CaptchaID)
if err != nil { if err != nil {
// 根据错误类型返回不同的状态码 // 根据错误类型返回不同的状态码
if isLockedError(err) { if isLockedError(err) {
@ -134,6 +135,14 @@ func (c *AuthController) GenerateCaptcha(ctx *gin.Context) {
captchaID := generateCaptchaID() captchaID := generateCaptchaID()
fmt.Printf("🔍 [验证码] 生成的验证码ID: %s\n", captchaID) fmt.Printf("🔍 [验证码] 生成的验证码ID: %s\n", captchaID)
// 存储验证码到数据库(5分钟过期)
expiresAt := time.Now().Add(5 * time.Minute)
if err := c.authService.GetCaptchaRepo().Create(ctx, captchaID, captchaText, expiresAt); err != nil {
fmt.Printf("🔍 [验证码] 存储验证码失败: %v\n", err)
response.Error(ctx, http.StatusInternalServerError, "验证码生成失败", "存储验证码失败")
return
}
// 生成验证码图片(SVG格式) // 生成验证码图片(SVG格式)
captchaImage := generateCaptchaSVG(captchaText) captchaImage := generateCaptchaSVG(captchaText)
fmt.Printf("🔍 [验证码] 生成的图片长度: %d\n", len(captchaImage)) fmt.Printf("🔍 [验证码] 生成的图片长度: %d\n", len(captchaImage))

3
gofaster/backend/internal/auth/module.go

@ -46,7 +46,8 @@ func (m *Module) Init(cfg *config.Config, logger *zap.Logger, db *gorm.DB, redis
// 初始化服务 // 初始化服务
userService := service.NewUserService(userRepo, db) userService := service.NewUserService(userRepo, db)
authService := service.NewAuthService(userRepo) captchaRepo := repository.NewCaptchaRepository(db)
authService := service.NewAuthService(userRepo, captchaRepo)
passwordService := service.NewPasswordService( passwordService := service.NewPasswordService(
userRepo, userRepo,
passwordPolicyRepo, passwordPolicyRepo,

20
gofaster/backend/internal/auth/repository/captcha_repo.go

@ -3,6 +3,7 @@ package repository
import ( import (
"context" "context"
"time" "time"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -18,10 +19,15 @@ type captchaRepository struct {
} }
type Captcha struct { type Captcha struct {
ID string `gorm:"primarykey;size:32" json:"id"` ID string `gorm:"primarykey;size:32;table:captchas" json:"id"`
Text string `gorm:"size:10;not null" json:"-"` Text string `gorm:"size:10;not null" json:"-"`
ExpiresAt time.Time `gorm:"not null;index" json:"expires_at"` ExpiresAt time.Time `gorm:"not null;index" json:"expires_at"`
CreatedAt time.Time `gorm:"not null" json:"created_at"` CreatedAt time.Time `gorm:"not null" json:"created_at"`
}
// TableName 指定表名
func (Captcha) TableName() string {
return "captchas"
} }
func NewCaptchaRepository(db *gorm.DB) CaptchaRepository { func NewCaptchaRepository(db *gorm.DB) CaptchaRepository {
@ -37,7 +43,7 @@ func (r *captchaRepository) Create(ctx context.Context, captchaID, captchaText s
ExpiresAt: expiresAt, ExpiresAt: expiresAt,
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
return r.db.WithContext(ctx).Create(captcha).Error return r.db.WithContext(ctx).Create(captcha).Error
} }
@ -47,10 +53,10 @@ func (r *captchaRepository) Get(ctx context.Context, captchaID string) (string,
if err != nil { if err != nil {
return "", err return "", err
} }
// 获取后立即删除,确保一次性使用 // 获取后立即删除,确保一次性使用
r.db.WithContext(ctx).Delete(&captcha) r.db.WithContext(ctx).Delete(&captcha)
return captcha.Text, nil return captcha.Text, nil
} }

14
gofaster/backend/internal/auth/repository/user_repo.go

@ -2,6 +2,7 @@ package repository
import ( import (
"context" "context"
"fmt"
"gofaster/internal/auth/model" "gofaster/internal/auth/model"
"gorm.io/gorm" "gorm.io/gorm"
@ -76,15 +77,28 @@ func (r *userRepository) List(ctx context.Context, offset, limit int) ([]*model.
var users []*model.User var users []*model.User
var total int64 var total int64
// 添加调试日志
fmt.Printf("🔍 [用户查询] 开始查询用户列表,offset=%d, limit=%d\n", offset, limit)
err := r.db.WithContext(ctx).Model(&model.User{}).Count(&total).Error err := r.db.WithContext(ctx).Model(&model.User{}).Count(&total).Error
if err != nil { if err != nil {
fmt.Printf("🔍 [用户查询] 统计总数失败: %v\n", err)
return nil, 0, err return nil, 0, err
} }
fmt.Printf("🔍 [用户查询] 数据库中共有 %d 条用户记录\n", total)
err = r.db.WithContext(ctx).Offset(offset).Limit(limit).Find(&users).Error err = r.db.WithContext(ctx).Offset(offset).Limit(limit).Find(&users).Error
if err != nil { if err != nil {
fmt.Printf("🔍 [用户查询] 查询用户列表失败: %v\n", err)
return nil, 0, err return nil, 0, err
} }
fmt.Printf("🔍 [用户查询] 查询到 %d 条用户记录\n", len(users))
// 打印查询到的用户信息
for i, user := range users {
fmt.Printf("🔍 [用户查询] 用户 %d: ID=%d, Username=%s, Email=%s, Status=%d\n",
i+1, user.ID, user.Username, user.Email, user.Status)
}
return users, total, nil return users, total, nil
} }

3
gofaster/backend/internal/auth/routes/auth_routes.go

@ -23,7 +23,8 @@ func RegisterAuthRoutes(router *gin.RouterGroup, db *gorm.DB) {
// 初始化服务 // 初始化服务
userService := service.NewUserService(userRepo, db) userService := service.NewUserService(userRepo, db)
authService := service.NewAuthService(userRepo) captchaRepo := repository.NewCaptchaRepository(db)
authService := service.NewAuthService(userRepo, captchaRepo)
passwordService := service.NewPasswordService( passwordService := service.NewPasswordService(
userRepo, userRepo,
passwordPolicyRepo, passwordPolicyRepo,

26
gofaster/backend/internal/auth/service/auth_service.go

@ -15,17 +15,30 @@ import (
) )
type AuthService struct { type AuthService struct {
userRepo repository.UserRepository userRepo repository.UserRepository
captchaRepo repository.CaptchaRepository
} }
func NewAuthService(userRepo repository.UserRepository) *AuthService { func NewAuthService(userRepo repository.UserRepository, captchaRepo repository.CaptchaRepository) *AuthService {
return &AuthService{ return &AuthService{
userRepo: userRepo, userRepo: userRepo,
captchaRepo: captchaRepo,
} }
} }
// Login 用户登录 // Login 用户登录
func (s *AuthService) Login(ctx context.Context, username, password string) (*model.LoginResponse, error) { func (s *AuthService) Login(ctx context.Context, username, password, captcha, captchaID string) (*model.LoginResponse, error) {
// 验证验证码
if captcha != "" && captchaID != "" {
expectedCaptcha, err := s.captchaRepo.Get(ctx, captchaID)
if err != nil {
return nil, errors.New("验证码错误或已过期")
}
if captcha != expectedCaptcha {
return nil, errors.New("验证码错误")
}
}
// 根据用户名查找用户 // 根据用户名查找用户
user, err := s.userRepo.GetByUsername(ctx, username) user, err := s.userRepo.GetByUsername(ctx, username)
if err != nil { if err != nil {
@ -84,6 +97,11 @@ func (s *AuthService) Login(ctx context.Context, username, password string) (*mo
}, nil }, nil
} }
// GetCaptchaRepo 获取验证码仓库
func (s *AuthService) GetCaptchaRepo() repository.CaptchaRepository {
return s.captchaRepo
}
// RefreshToken 刷新JWT token // RefreshToken 刷新JWT token
func (s *AuthService) RefreshToken(ctx context.Context, userID interface{}) (string, error) { func (s *AuthService) RefreshToken(ctx context.Context, userID interface{}) (string, error) {
// 安全地转换userID // 安全地转换userID

4
gofaster/backend/internal/auth/service/user_service.go

@ -37,7 +37,9 @@ func (s *UserService) DeleteUser(ctx context.Context, id uint) error {
} }
func (s *UserService) ListUsers(ctx context.Context, page, pageSize int) ([]*model.User, int64, error) { func (s *UserService) ListUsers(ctx context.Context, page, pageSize int) ([]*model.User, int64, error) {
return s.repo.List(ctx, page, pageSize) // 计算偏移量
offset := (page - 1) * pageSize
return s.repo.List(ctx, offset, pageSize)
} }
// GetByID 根据ID获取用户(无context版本,用于密码服务) // GetByID 根据ID获取用户(无context版本,用于密码服务)

7
gofaster/backend/main.go

@ -26,6 +26,7 @@ import (
// 导入各模块 // 导入各模块
_ "gofaster/internal/auth" _ "gofaster/internal/auth"
"gofaster/internal/auth/migration"
_ "gofaster/internal/workflow" _ "gofaster/internal/workflow"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -67,6 +68,12 @@ func main() {
log.Fatal("Failed to connect database", zap.Error(err)) log.Fatal("Failed to connect database", zap.Error(err))
} }
// 运行数据库迁移
if err := migration.RunMigrations(db); err != nil {
log.Fatal("Failed to run database migrations", zap.Error(err))
}
fmt.Printf("✅ 数据库迁移完成\n")
// 初始化Redis // 初始化Redis
redisClient := database.NewRedisClient(&cfg.Redis, log) redisClient := database.NewRedisClient(&cfg.Redis, log)
defer redisClient.Close() defer redisClient.Close()

2
gofaster/backend/tmp/build-errors.log

@ -1 +1 @@
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1

BIN
gofaster/backend/tmp/main.exe

Binary file not shown.
Loading…
Cancel
Save