200 lines
7.7 KiB
Go
200 lines
7.7 KiB
Go
package repository
|
|
|
|
import (
|
|
"electricity_bill_calc/cache"
|
|
"electricity_bill_calc/global"
|
|
"electricity_bill_calc/logger"
|
|
"electricity_bill_calc/model"
|
|
"electricity_bill_calc/tools"
|
|
"electricity_bill_calc/tools/time"
|
|
"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
|
|
ds goqu.DialectWrapper
|
|
}
|
|
|
|
var UserRepository = _UserRepository{
|
|
log: logger.Named("Repository", "User"),
|
|
ds: goqu.Dialect("postgres"),
|
|
}
|
|
|
|
// 使用用户名查询指定用户的基本信息
|
|
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, _ := ur.ds.From("user").Where(goqu.Ex{"username": 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, _ := ur.ds.From("user").Where(goqu.Ex{"id": 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, _ := ur.ds.From("user_detail").Where(goqu.Ex{"id": 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, _ := ur.ds.
|
|
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.Ex{"u.id": 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, _ := ur.ds.From("user").Select(goqu.COUNT("*")).Where(goqu.Ex{"id": 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
|
|
}
|
|
|
|
// 创建一个新用户
|
|
func (ur _UserRepository) CreateUser(user model.User, detail model.UserDetail, operator *string) (bool, error) {
|
|
ctx, cancel := global.TimeoutContext()
|
|
defer cancel()
|
|
tx, err := global.DB.Begin(ctx)
|
|
if err != nil {
|
|
ur.log.Error("启动数据库事务失败。", zap.Error(err))
|
|
return false, err
|
|
}
|
|
|
|
createdTime := time.Now()
|
|
userSql, userParams, _ := ur.ds.
|
|
Insert("user").
|
|
Rows(
|
|
goqu.Record{
|
|
"id": user.Id, "username": user.Username, "password": user.Password,
|
|
"reset_needed": user.ResetNeeded, "type": user.UserType, "enabled": user.Enabled,
|
|
"created_at": createdTime,
|
|
},
|
|
).
|
|
Prepared(true).ToSQL()
|
|
userResult, err := tx.Exec(ctx, userSql, userParams...)
|
|
if err != nil {
|
|
ur.log.Error("向数据库插入新用户基本信息失败。", zap.Error(err))
|
|
tx.Rollback(ctx)
|
|
return false, err
|
|
}
|
|
userDetailSql, userDetailParams, _ := ur.ds.
|
|
Insert("user_detail").
|
|
Rows(
|
|
goqu.Record{
|
|
"id": user.Id, "name": detail.Name, "abbr": tools.PinyinAbbr(*detail.Name), "region": detail.Region,
|
|
"address": detail.Address, "contact": detail.Contact, "phone": detail.Phone,
|
|
"unit_service_fee": detail.UnitServiceFee, "service_expiration": detail.ServiceExpiration,
|
|
"created_at": createdTime, "created_by": operator,
|
|
"last_modified_at": createdTime, "last_modified_by": operator,
|
|
},
|
|
).
|
|
Prepared(true).ToSQL()
|
|
detailResult, err := tx.Exec(ctx, userDetailSql, userDetailParams...)
|
|
if err != nil {
|
|
ur.log.Error("向数据库插入新用户详细信息失败。", zap.Error(err))
|
|
tx.Rollback(ctx)
|
|
return false, err
|
|
}
|
|
|
|
err = tx.Commit(ctx)
|
|
if err != nil {
|
|
ur.log.Error("提交数据库事务失败。", zap.Error(err))
|
|
tx.Rollback(ctx)
|
|
return false, err
|
|
} else {
|
|
cache.AbolishRelation("user")
|
|
}
|
|
return userResult.RowsAffected() > 0 && detailResult.RowsAffected() > 0, nil
|
|
}
|