forked from free-lancers/electricity_bill_calc_service
		
	enhance(user):完成可运行的程序基本结构以及用户基本查询功能。
This commit is contained in:
		
							
								
								
									
										58
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								main.go
									
									
									
									
									
								
							| @@ -6,12 +6,12 @@ import ( | |||||||
| 	"electricity_bill_calc/global" | 	"electricity_bill_calc/global" | ||||||
| 	"electricity_bill_calc/logger" | 	"electricity_bill_calc/logger" | ||||||
| 	"electricity_bill_calc/model" | 	"electricity_bill_calc/model" | ||||||
|  | 	"electricity_bill_calc/repository" | ||||||
| 	"electricity_bill_calc/router" | 	"electricity_bill_calc/router" | ||||||
| 	"electricity_bill_calc/service" | 	"electricity_bill_calc/service" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/shopspring/decimal" |  | ||||||
| 	"go.uber.org/zap" | 	"go.uber.org/zap" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -43,52 +43,46 @@ func init() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func intializeSingularity() error { | func intializeSingularity() error { | ||||||
| 	singularityExists, err := service.UserService.IsUserExists("000") | 	l := logger.Named("Init", "Singularity") | ||||||
|  | 	singularityExists, err := repository.UserRepository.IsUserExists("000") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("singularity detect failed: %w", err) | 		l.Error("检测奇点账号失败。", zap.Error(err)) | ||||||
|  | 		return fmt.Errorf("检测奇点账号失败: %w", err) | ||||||
| 	} | 	} | ||||||
| 	if singularityExists { | 	if singularityExists { | ||||||
|  | 		l.Info("奇点账号已经存在,跳过剩余初始化步骤。") | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	singularity := &model.User{ | 	singularityId := "000" | ||||||
| 		Id:       "000", |  | ||||||
| 		Username: "singularity", |  | ||||||
| 		Type:     2, |  | ||||||
| 		Enabled:  true, |  | ||||||
| 	} |  | ||||||
| 	singularityName := "Singularity" |  | ||||||
| 	singularityExpires, err := model.ParseDate("2099-12-31") | 	singularityExpires, err := model.ParseDate("2099-12-31") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("singularity expires time parse failed: %w", err) | 		l.Error("奇点用户账号过期时间解析失败。", zap.Error(err)) | ||||||
|  | 		return fmt.Errorf("奇点用户账号过期时间解析失败: %w", err) | ||||||
| 	} | 	} | ||||||
| 	singularityDetail := &model.UserDetail{ | 	singularity := &model.ManagementAccountCreationForm{ | ||||||
| 		Name:              &singularityName, | 		Id:       &singularityId, | ||||||
| 		UnitServiceFee:    decimal.Zero, | 		Username: "singularity", | ||||||
| 		ServiceExpiration: singularityExpires, | 		Name:     "Singularity", | ||||||
|  | 		Type:     2, | ||||||
|  | 		Enabled:  true, | ||||||
|  | 		Expires:  singularityExpires, | ||||||
| 	} | 	} | ||||||
| 	verifyCode, err := service.UserService.CreateUser(singularity, singularityDetail) | 	verifyCode, err := service.UserService.CreateUserAccount( | ||||||
|  | 		singularity.IntoUser(), | ||||||
|  | 		singularity.IntoUserDetail()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("singularity account failed to create: %w", err) | 		l.Error("创建奇点账号失败。", zap.Error(err)) | ||||||
|  | 		return fmt.Errorf("创建奇点账号失败: %w", err) | ||||||
| 	} | 	} | ||||||
| 	logger.Info( | 	logger.Info( | ||||||
| 		fmt.Sprintf("Singularity account created, use %s as verify code to reset password.", verifyCode), | 		fmt.Sprintf("奇点账号已经完成创建, 首次登录需要使用验证码 [%s] 重置密码。", *verifyCode), | ||||||
| 		zap.String("account", "singularity"), | 		zap.String("账号名称", "singularity"), | ||||||
| 		zap.String("verifyCode", verifyCode), | 		zap.String("验证码", *verifyCode), | ||||||
| 	) | 	) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func DBConnectionKeepLive() { | // 清理Redis缓存中的孤儿键。 | ||||||
| 	for range time.Tick(30 * time.Second) { |  | ||||||
| 		ctx, cancel := global.TimeoutContext() |  | ||||||
| 		defer cancel() |  | ||||||
| 		err := global.DB.Ping(ctx) |  | ||||||
| 		if err != nil { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func RedisOrphanCleanup() { | func RedisOrphanCleanup() { | ||||||
| 	cleanLogger := logger.Named("Cache").With(zap.String("function", "Cleanup")) | 	cleanLogger := logger.Named("Cache").With(zap.String("function", "Cleanup")) | ||||||
| 	for range time.Tick(2 * time.Minute) { | 	for range time.Tick(2 * time.Minute) { | ||||||
| @@ -102,8 +96,6 @@ func RedisOrphanCleanup() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func main() { | func main() { | ||||||
| 	// 本次停用检测的原因是:使用Ping来保持数据库链接看起来没有什么用处。 |  | ||||||
| 	// go DBConnectionKeepLive() |  | ||||||
| 	go RedisOrphanCleanup() | 	go RedisOrphanCleanup() | ||||||
| 	app := router.App() | 	app := router.App() | ||||||
| 	app.Listen(fmt.Sprintf(":%d", config.ServerSettings.HttpPort)) | 	app.Listen(fmt.Sprintf(":%d", config.ServerSettings.HttpPort)) | ||||||
|   | |||||||
| @@ -23,6 +23,38 @@ type ManagementAccountCreationForm struct { | |||||||
| 	Expires  Date | 	Expires  Date | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (m ManagementAccountCreationForm) IntoUser() *User { | ||||||
|  | 	return &User{ | ||||||
|  | 		Id:          *m.Id, | ||||||
|  | 		Username:    m.Username, | ||||||
|  | 		Password:    "", | ||||||
|  | 		ResetNeeded: false, | ||||||
|  | 		UserType:    m.Type, | ||||||
|  | 		Enabled:     m.Enabled, | ||||||
|  | 		CreatedAt:   nil, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m ManagementAccountCreationForm) IntoUserDetail() *UserDetail { | ||||||
|  | 	return &UserDetail{ | ||||||
|  | 		Id:                *m.Id, | ||||||
|  | 		Name:              &m.Name, | ||||||
|  | 		Abbr:              nil, | ||||||
|  | 		Region:            nil, | ||||||
|  | 		Address:           nil, | ||||||
|  | 		Contact:           m.Contact, | ||||||
|  | 		Phone:             m.Phone, | ||||||
|  | 		UnitServiceFee:    decimal.Zero, | ||||||
|  | 		ServiceExpiration: m.Expires, | ||||||
|  | 		CreatedAt:         time.Now(), | ||||||
|  | 		CreatedBy:         nil, | ||||||
|  | 		LastModifiedAt:    time.Now(), | ||||||
|  | 		LastModifiedBy:    nil, | ||||||
|  | 		DeletedAt:         nil, | ||||||
|  | 		DeletedBy:         nil, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| type User struct { | type User struct { | ||||||
| 	Id          string | 	Id          string | ||||||
| 	Username    string | 	Username    string | ||||||
|   | |||||||
| @@ -5,6 +5,8 @@ import ( | |||||||
| 	"electricity_bill_calc/global" | 	"electricity_bill_calc/global" | ||||||
| 	"electricity_bill_calc/logger" | 	"electricity_bill_calc/logger" | ||||||
| 	"electricity_bill_calc/model" | 	"electricity_bill_calc/model" | ||||||
|  | 	"electricity_bill_calc/tools" | ||||||
|  | 	"electricity_bill_calc/tools/time" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"github.com/doug-martin/goqu/v9" | 	"github.com/doug-martin/goqu/v9" | ||||||
| @@ -15,10 +17,12 @@ import ( | |||||||
|  |  | ||||||
| type _UserRepository struct { | type _UserRepository struct { | ||||||
| 	log *zap.Logger | 	log *zap.Logger | ||||||
|  | 	ds  goqu.DialectWrapper | ||||||
| } | } | ||||||
|  |  | ||||||
| var UserRepository = _UserRepository{ | var UserRepository = _UserRepository{ | ||||||
| 	log: logger.Named("Repository", "User"), | 	log: logger.Named("Repository", "User"), | ||||||
|  | 	ds:  goqu.Dialect("postgres"), | ||||||
| } | } | ||||||
|  |  | ||||||
| // 使用用户名查询指定用户的基本信息 | // 使用用户名查询指定用户的基本信息 | ||||||
| @@ -32,7 +36,7 @@ func (ur _UserRepository) FindUserByUsername(username string) (*model.User, erro | |||||||
| 	defer cancel() | 	defer cancel() | ||||||
|  |  | ||||||
| 	var user = new(model.User) | 	var user = new(model.User) | ||||||
| 	sql, params, _ := goqu.From("user").Where(goqu.C("username").Eq(username)).Prepared(true).ToSQL() | 	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 { | 	if err := pgxscan.Get(ctx, global.DB, &user, sql, params...); err != nil { | ||||||
| 		ur.log.Error("从数据库查询指定用户名的用户基本信息失败。", zap.String("username", username), zap.Error(err)) | 		ur.log.Error("从数据库查询指定用户名的用户基本信息失败。", zap.String("username", username), zap.Error(err)) | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -52,7 +56,7 @@ func (ur _UserRepository) FindUserById(uid string) (*model.User, error) { | |||||||
| 	defer cancel() | 	defer cancel() | ||||||
|  |  | ||||||
| 	var user = new(model.User) | 	var user = new(model.User) | ||||||
| 	sql, params, _ := goqu.From("user").Where(goqu.C("id").Eq(uid)).Prepared(true).ToSQL() | 	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 { | 	if err := pgxscan.Get(ctx, global.DB, &user, sql, params...); err != nil { | ||||||
| 		ur.log.Error("从数据库查询指定用户唯一编号的用户基本信息失败。", zap.String("user id", uid), zap.Error(err)) | 		ur.log.Error("从数据库查询指定用户唯一编号的用户基本信息失败。", zap.String("user id", uid), zap.Error(err)) | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -72,7 +76,7 @@ func (ur _UserRepository) FindUserDetailById(uid string) (*model.UserDetail, err | |||||||
| 	defer cancel() | 	defer cancel() | ||||||
|  |  | ||||||
| 	var user = new(model.UserDetail) | 	var user = new(model.UserDetail) | ||||||
| 	sql, params, _ := goqu.From("user_detail").Where(goqu.C("id").Eq(uid)).Prepared(true).ToSQL() | 	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 { | 	if err := pgxscan.Get(ctx, global.DB, &user, sql, params...); err != nil { | ||||||
| 		ur.log.Error("从数据库查询指定用户唯一编号的用户详细信息失败。", zap.String("user id", uid), zap.Error(err)) | 		ur.log.Error("从数据库查询指定用户唯一编号的用户详细信息失败。", zap.String("user id", uid), zap.Error(err)) | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -92,7 +96,7 @@ func (ur _UserRepository) FindUserInformation(uid string) (*model.UserWithDetail | |||||||
| 	defer cancel() | 	defer cancel() | ||||||
|  |  | ||||||
| 	var user = new(model.UserWithDetail) | 	var user = new(model.UserWithDetail) | ||||||
| 	sql, params, _ := goqu. | 	sql, params, _ := ur.ds. | ||||||
| 		From("user").As("u"). | 		From("user").As("u"). | ||||||
| 		Join( | 		Join( | ||||||
| 			goqu.T("user_detail").As("ud"), | 			goqu.T("user_detail").As("ud"), | ||||||
| @@ -104,7 +108,7 @@ func (ur _UserRepository) FindUserInformation(uid string) (*model.UserWithDetail | |||||||
| 			"ud.name", "ud.abbr", "ud.region", "ud.address", "ud.contact", "ud.phone", | 			"ud.name", "ud.abbr", "ud.region", "ud.address", "ud.contact", "ud.phone", | ||||||
| 			"ud.unit_service_fee", "ud.service_expiration", | 			"ud.unit_service_fee", "ud.service_expiration", | ||||||
| 			"ud.created_at", "ud.created_by", "ud.last_modified_at", "ud.last_modified_by"). | 			"ud.created_at", "ud.created_by", "ud.last_modified_at", "ud.last_modified_by"). | ||||||
| 		Where(goqu.C("u.id").Eq(uid)). | 		Where(goqu.Ex{"u.id": uid}). | ||||||
| 		Prepared(true).ToSQL() | 		Prepared(true).ToSQL() | ||||||
| 	if err := pgxscan.Get( | 	if err := pgxscan.Get( | ||||||
| 		ctx, global.DB, &user, sql, params...); err != nil { | 		ctx, global.DB, &user, sql, params...); err != nil { | ||||||
| @@ -126,7 +130,7 @@ func (ur _UserRepository) IsUserExists(uid string) (bool, error) { | |||||||
| 	defer cancel() | 	defer cancel() | ||||||
|  |  | ||||||
| 	var userCount int | 	var userCount int | ||||||
| 	sql, params, _ := goqu.From("user").Select(goqu.COUNT("*")).Where(goqu.C("id").Eq(uid)).Prepared(true).ToSQL() | 	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 { | 	if err := pgxscan.Get(ctx, global.DB, &userCount, sql, params...); err != nil { | ||||||
| 		ur.log.Error("从数据库查询指定用户唯一编号的用户基本信息失败。", zap.String("user id", uid), zap.Error(err)) | 		ur.log.Error("从数据库查询指定用户唯一编号的用户基本信息失败。", zap.String("user id", uid), zap.Error(err)) | ||||||
| 		return false, err | 		return false, err | ||||||
| @@ -136,3 +140,60 @@ func (ur _UserRepository) IsUserExists(uid string) (bool, error) { | |||||||
| 	} | 	} | ||||||
| 	return userCount > 0, nil | 	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 | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										148
									
								
								service/user.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								service/user.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | |||||||
|  | package service | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"electricity_bill_calc/cache" | ||||||
|  | 	"electricity_bill_calc/config" | ||||||
|  | 	"electricity_bill_calc/exceptions" | ||||||
|  | 	"electricity_bill_calc/logger" | ||||||
|  | 	"electricity_bill_calc/model" | ||||||
|  | 	"electricity_bill_calc/repository" | ||||||
|  | 	"electricity_bill_calc/tools" | ||||||
|  | 	"electricity_bill_calc/tools/serial" | ||||||
|  | 	"electricity_bill_calc/tools/time" | ||||||
|  |  | ||||||
|  | 	"github.com/fufuok/utils" | ||||||
|  | 	"github.com/google/uuid" | ||||||
|  | 	"github.com/samber/lo" | ||||||
|  | 	"go.uber.org/zap" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type _UserService struct { | ||||||
|  | 	log *zap.Logger | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var UserService = _UserService{ | ||||||
|  | 	log: logger.Named("Service", "User"), | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func matchUserPassword(controlCode, testCode string) bool { | ||||||
|  | 	hashedCode := utils.Sha512Hex(testCode) | ||||||
|  | 	return controlCode == hashedCode | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 处理用户登录的通用过程。 | ||||||
|  | func (us _UserService) processUserLogin(username, password string, userType []int16) (*model.User, *model.UserDetail, error) { | ||||||
|  | 	us.log.Info("处理用户登录。", zap.String("username", username)) | ||||||
|  | 	user, err := repository.UserRepository.FindUserByUsername(username) | ||||||
|  | 	if err != nil { | ||||||
|  | 		us.log.Error("处理用户登录失败。", zap.String("username", username), zap.Error(err)) | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	if user == nil { | ||||||
|  | 		us.log.Warn("处理用户登录失败,用户不存在。", zap.String("username", username)) | ||||||
|  | 		return nil, nil, exceptions.NewAuthenticationError(404, "用户不存在。") | ||||||
|  | 	} | ||||||
|  | 	if !lo.Contains(userType, user.UserType) { | ||||||
|  | 		us.log.Warn("处理用户登录失败,用户类型错误。", zap.String("username", username), zap.Int16s("user type", userType)) | ||||||
|  | 		return nil, nil, exceptions.NewAuthenticationError(400, "用户类型不正确。") | ||||||
|  | 	} | ||||||
|  | 	if !user.Enabled { | ||||||
|  | 		us.log.Warn("处理用户登录失败,用户已被禁用。", zap.String("username", username)) | ||||||
|  | 		return nil, nil, exceptions.NewAuthenticationError(403, "用户已被禁用。") | ||||||
|  | 	} | ||||||
|  | 	if user.ResetNeeded { | ||||||
|  | 		us.log.Warn("处理用户登录失败,用户需要重置密码。", zap.String("username", username)) | ||||||
|  | 		authErr := exceptions.NewAuthenticationError(401, "用户凭据已失效。") | ||||||
|  | 		authErr.NeedReset = true | ||||||
|  | 		return nil, nil, authErr | ||||||
|  | 	} | ||||||
|  | 	if !matchUserPassword(user.Password, password) { | ||||||
|  | 		us.log.Warn("处理用户登录失败,密码错误。", zap.String("username", username)) | ||||||
|  | 		return nil, nil, exceptions.NewAuthenticationError(402, "用户凭据不正确。") | ||||||
|  | 	} | ||||||
|  | 	userDetail, err := repository.UserRepository.FindUserDetailById(user.Id) | ||||||
|  | 	if err != nil { | ||||||
|  | 		us.log.Error("处理企业用户登录失败,查询用户详细信息失败。", zap.String("username", username), zap.Error(err)) | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	if userDetail.ServiceExpiration.Before(time.Now()) { | ||||||
|  | 		us.log.Warn("处理企业用户登录失败,用户服务已过期。", zap.String("username", username)) | ||||||
|  | 		return nil, nil, exceptions.NewAuthenticationError(406, "用户服务期限已过。") | ||||||
|  | 	} | ||||||
|  | 	return user, userDetail, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 处理企业用户登录 | ||||||
|  | func (us _UserService) ProcessEnterpriseUserLogin(username, password string) (*model.Session, error) { | ||||||
|  | 	user, userDetail, err := us.processUserLogin(username, password, []int16{model.USER_TYPE_ENT}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		us.log.Error("处理企业用户登录失败。", zap.String("username", username), zap.Error(err)) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	token, _ := uuid.NewRandom() | ||||||
|  | 	userSession := &model.Session{ | ||||||
|  | 		Uid:       user.Id, | ||||||
|  | 		Name:      user.Username, | ||||||
|  | 		Type:      user.UserType, | ||||||
|  | 		Token:     token.String(), | ||||||
|  | 		ExpiresAt: time.Now().Add(config.ServiceSettings.MaxSessionLife), | ||||||
|  | 	} | ||||||
|  | 	if userDetail != nil && userDetail.Name != nil { | ||||||
|  | 		userSession.Name = *userDetail.Name | ||||||
|  | 	} | ||||||
|  | 	err = cache.CacheSession(userSession) | ||||||
|  | 	if err != nil { | ||||||
|  | 		us.log.Error("处理企业用户登录失败,缓存用户会话失败。", zap.String("username", username), zap.Error(err)) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return userSession, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 处理运维、监管用户登录 | ||||||
|  | func (us _UserService) ProcessManagementUserLogin(username, password string) (*model.Session, error) { | ||||||
|  | 	user, userDetail, err := us.processUserLogin(username, password, []int16{model.USER_TYPE_OPS, model.USER_TYPE_SUP}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		us.log.Error("处理运维、监管用户登录失败。", zap.String("username", username), zap.Error(err)) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	token, _ := uuid.NewRandom() | ||||||
|  | 	userSession := &model.Session{ | ||||||
|  | 		Uid:       user.Id, | ||||||
|  | 		Name:      user.Username, | ||||||
|  | 		Type:      user.UserType, | ||||||
|  | 		Token:     token.String(), | ||||||
|  | 		ExpiresAt: time.Now().Add(config.ServiceSettings.MaxSessionLife), | ||||||
|  | 	} | ||||||
|  | 	if userDetail != nil { | ||||||
|  | 		userSession.Name = *userDetail.Name | ||||||
|  | 	} | ||||||
|  | 	err = cache.CacheSession(userSession) | ||||||
|  | 	if err != nil { | ||||||
|  | 		us.log.Error("处理运维、监管用户登录失败,缓存用户会话失败。", zap.String("username", username), zap.Error(err)) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return userSession, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 创建用户账号的通用方法。 | ||||||
|  | func (us _UserService) CreateUserAccount(user *model.User, detail *model.UserDetail) (*string, error) { | ||||||
|  | 	if lo.IsEmpty(user.Id) { | ||||||
|  | 		var prefix string | ||||||
|  | 		if user.UserType == model.USER_TYPE_ENT { | ||||||
|  | 			prefix = "E" | ||||||
|  | 		} else { | ||||||
|  | 			prefix = "S" | ||||||
|  | 		} | ||||||
|  | 		user.Id = serial.GeneratePrefixedUniqueSerialString(prefix) | ||||||
|  | 		detail.Id = user.Id | ||||||
|  | 	} | ||||||
|  | 	verifyCode := tools.RandStr(10) | ||||||
|  | 	user.Password = utils.Sha512Hex(verifyCode) | ||||||
|  | 	user.ResetNeeded = true | ||||||
|  | 	res, err := repository.UserRepository.CreateUser(*user, *detail, nil) | ||||||
|  | 	if err != nil || !res { | ||||||
|  | 		us.log.Error("创建用户账号失败。", zap.String("username", user.Username), zap.Error(err)) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return &verifyCode, nil | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user