package repository import ( "electricity_bill_calc/cache" "electricity_bill_calc/global" "electricity_bill_calc/logger" "electricity_bill_calc/model" "fmt" "github.com/doug-martin/goqu/v9" _ "github.com/doug-martin/goqu/v9/dialect/postgres" "github.com/georgysavva/scany/v2/pgxscan" "go.uber.org/zap" ) type _UserRepository struct { log *zap.Logger } var UserRepository = _UserRepository{ log: logger.Named("Repository", "User"), } // 使用用户名查询指定用户的基本信息 func (ur _UserRepository) FindUserByUsername(username string) (*model.User, error) { ur.log.Info("根据用户名查询指定用户的基本信息。", zap.String("username", username)) if cachedUser, _ := cache.RetreiveEntity[model.User]("user", username); cachedUser != nil { ur.log.Info("已经从缓存获取到了符合指定用户名条件的用户基本信息。", zap.String("username", username)) return cachedUser, nil } ctx, cancel := global.TimeoutContext() defer cancel() var user = new(model.User) sql, params, _ := goqu.From("user").Where(goqu.C("username").Eq(username)).Prepared(true).ToSQL() if err := pgxscan.Get(ctx, global.DB, &user, sql, params...); err != nil { ur.log.Error("从数据库查询指定用户名的用户基本信息失败。", zap.String("username", username), zap.Error(err)) return nil, err } cache.CacheEntity(user, []string{"user", fmt.Sprintf("user:%s", username)}, "user", username) return user, nil } // 使用用户唯一编号查询指定用户的基本信息 func (ur _UserRepository) FindUserById(uid string) (*model.User, error) { ur.log.Info("根据用户唯一编号查询指定用户的基本信息。", zap.String("user id", uid)) if cachedUser, _ := cache.RetreiveEntity[model.User]("user", uid); cachedUser != nil { ur.log.Info("已经从缓存获取到了符合指定用户唯一编号的用户基本信息。") return cachedUser, nil } ctx, cancel := global.TimeoutContext() defer cancel() var user = new(model.User) sql, params, _ := goqu.From("user").Where(goqu.C("id").Eq(uid)).Prepared(true).ToSQL() if err := pgxscan.Get(ctx, global.DB, &user, sql, params...); err != nil { ur.log.Error("从数据库查询指定用户唯一编号的用户基本信息失败。", zap.String("user id", uid), zap.Error(err)) return nil, err } cache.CacheEntity(user, []string{"user", fmt.Sprintf("user:%s", uid)}, "user", uid) return user, nil } // 使用用户的唯一编号获取用户的详细信息 func (ur _UserRepository) FindUserDetailById(uid string) (*model.UserDetail, error) { ur.log.Info("根据用户唯一编号查询指定用户的详细信息。", zap.String("user id", uid)) if cachedUser, _ := cache.RetreiveEntity[model.UserDetail]("user_detail", uid); cachedUser != nil { ur.log.Info("已经从缓存获取到了符合指定用户唯一编号的用户详细信息。") return cachedUser, nil } ctx, cancel := global.TimeoutContext() defer cancel() var user = new(model.UserDetail) sql, params, _ := goqu.From("user_detail").Where(goqu.C("id").Eq(uid)).Prepared(true).ToSQL() if err := pgxscan.Get(ctx, global.DB, &user, sql, params...); err != nil { ur.log.Error("从数据库查询指定用户唯一编号的用户详细信息失败。", zap.String("user id", uid), zap.Error(err)) return nil, err } cache.CacheEntity(user, []string{"user", fmt.Sprintf("user:%s", uid)}, "user_detail", uid) return user, nil } // 使用用户唯一编号获取用户的综合详细信息 func (ur _UserRepository) FindUserInformation(uid string) (*model.UserWithDetail, error) { ur.log.Info("根据用户唯一编号查询用户的综合详细信息", zap.String("user id", uid)) if cachedUser, _ := cache.RetreiveEntity[model.UserWithDetail]("user_information", uid); cachedUser != nil { ur.log.Info("已经从缓存获取到了符合指定用户唯一编号的用户综合详细信息。") return cachedUser, nil } ctx, cancel := global.TimeoutContext() defer cancel() var user = new(model.UserWithDetail) sql, params, _ := goqu. From("user").As("u"). Join( goqu.T("user_detail").As("ud"), goqu.On(goqu.Ex{ "ud.id": goqu.I("u.id"), })). Select( "u.id", "u.username", "u.reset_needed", "u.type", "u.enabled", "ud.name", "ud.abbr", "ud.region", "ud.address", "ud.contact", "ud.phone", "ud.unit_service_fee", "ud.service_expiration", "ud.created_at", "ud.created_by", "ud.last_modified_at", "ud.last_modified_by"). Where(goqu.C("u.id").Eq(uid)). Prepared(true).ToSQL() if err := pgxscan.Get( ctx, global.DB, &user, sql, params...); err != nil { ur.log.Error("从数据库查询指定用户唯一编号的用户详细信息失败。", zap.String("user id", uid), zap.Error(err)) return nil, err } cache.CacheEntity(user, []string{"user", fmt.Sprintf("user:%s", uid)}, "user_information", uid) return user, nil } // 检查指定用户唯一编号是否存在对应的用户 func (ur _UserRepository) IsUserExists(uid string) (bool, error) { ur.log.Info("检查指定用户唯一编号是否存在对应的用户。", zap.String("user id", uid)) if exists, _ := cache.CheckExists("user", uid); exists { ur.log.Info("已经从缓存获取到了符合指定用户唯一编号的用户基本信息。") return exists, nil } ctx, cancel := global.TimeoutContext() defer cancel() var userCount int sql, params, _ := goqu.From("user").Select(goqu.COUNT("*")).Where(goqu.C("id").Eq(uid)).Prepared(true).ToSQL() if err := pgxscan.Get(ctx, global.DB, &userCount, sql, params...); err != nil { ur.log.Error("从数据库查询指定用户唯一编号的用户基本信息失败。", zap.String("user id", uid), zap.Error(err)) return false, err } if userCount > 0 { cache.CacheExists([]string{"user", fmt.Sprintf("user:%s", uid)}, "user", uid) } return userCount > 0, nil }