func unbindQQ(userId int64) (err error) { para := struct { UserId int64 `sqlx:"user_id"` NotBindType BindType `sqlx:"not_bind_type"` }{ UserId: userId, NotBindType: BindTypeMask &^ BindTypeQQ, } tx, err := db.GetDB().Beginx() if err != nil { return } // user_qq 表删除一个 item stmt1, err := tx.Prepare("delete from user_qq where user_id=? and verified=1") if err != nil { tx.Rollback() return } rslt1, err := stmt1.Exec(para.UserId) if err != nil { tx.Rollback() return } rowsAffected1, err := rslt1.RowsAffected() if err != nil { tx.Rollback() return } // user 更新 item stmt2, err := tx.PrepareNamed("update user set bind_types = bind_types&:not_bind_type where id=:user_id and verified=1 and bind_types&:not_bind_type<>0") if err != nil { tx.Rollback() return } rslt2, err := stmt2.Exec(para) if err != nil { tx.Rollback() return } rowsAffected2, err := rslt2.RowsAffected() if err != nil { tx.Rollback() return } if rowsAffected1 != rowsAffected2 { err = fmt.Errorf("用户 %d 解绑QQ失败", para.UserId) tx.Rollback() return } err = tx.Commit() return }
func bindWeibo(userId int64, openid string) (err error) { para := struct { UserId int64 `sqlx:"user_id"` OpenId string `sqlx:"openid"` BindType BindType `sqlx:"bind_type"` }{ UserId: userId, OpenId: openid, BindType: BindTypeWeibo, } tx, err := db.GetDB().Beginx() if err != nil { return } // user_weibo 表增加一个 item stmt1, err := tx.Prepare("insert into user_weibo(user_id, openid, verified) values(?, ?, 1)") if err != nil { tx.Rollback() return } if _, err = stmt1.Exec(para.UserId, para.OpenId); err != nil { tx.Rollback() return } // user 更新 item stmt2, err := tx.PrepareNamed("update user set bind_types = bind_types|:bind_type where id=:user_id and verified=1 and bind_types&:bind_type=0") if err != nil { tx.Rollback() return } rslt2, err := stmt2.Exec(para) if err != nil { tx.Rollback() return } rowsAffected2, err := rslt2.RowsAffected() if err != nil { tx.Rollback() return } if rowsAffected2 != 1 { err = fmt.Errorf("绑定微博 %s 到用户 %d 失败", para.OpenId, para.UserId) tx.Rollback() return } err = tx.Commit() return }
// 通过 邮箱 注册一个账户. // 如果 nickname 为空, 则默认为 email // 验证码注册时, password, salt 可以为 nil // 如果 timestamp == 0 则默认使用当前时间 func AddByEmail(email, nickname string, password, salt []byte, timestamp int64) (userId int64, err error) { userId, err = userid.GetId() if err != nil { return } if nickname == "" { nickname = email } if password == nil { password = emptyByteSlice } if salt == nil { salt = emptyByteSlice } if timestamp == 0 { timestamp = time.Now().Unix() } para := struct { UserId int64 `sqlx:"user_id"` BindType BindType `sqlx:"bind_type"` Email string `sqlx:"email"` Nickname string `sqlx:"nickname"` Password []byte `sqlx:"password"` PasswordTag []byte `sqlx:"password_tag"` Salt []byte `sqlx:"salt"` CreateTime int64 `sqlx:"create_time"` }{ UserId: userId, BindType: BindTypeEmail, Email: email, Nickname: nickname, Password: password, PasswordTag: random.NewRandomEx(), Salt: salt, CreateTime: timestamp, } tx, err := db.GetDB().Beginx() if err != nil { return } // user_email 表增加一个 item stmt1, err := tx.Prepare("insert into user_email(user_id, email, verified) values(?, ?, 0)") if err != nil { tx.Rollback() return } if _, err = stmt1.Exec(para.UserId, para.Email); err != nil { tx.Rollback() return } // user 表增加一个 item stmt2, err := tx.PrepareNamed("insert into user(id, nickname, bind_types, password, password_tag, salt, create_time, verified) values(:user_id, :nickname, :bind_type, :password, :password_tag, :salt, :create_time, 0)") if err != nil { tx.Rollback() return } if _, err = stmt2.Exec(para); err != nil { tx.Rollback() return } err = tx.Commit() return }
func bindEmailUserTo(toUserId, userId int64) (err error) { if toUserId == userId { return errors.New("toUserId 不能等于 userId") } para := struct { ToUserId int64 `sqlx:"to_user_id"` UserId int64 `sqlx:"user_id"` BindType BindType `sqlx:"bind_type"` }{ ToUserId: toUserId, UserId: userId, BindType: BindTypeEmail, } tx, err := db.GetDB().Beginx() if err != nil { return } // user 更新 ToUserId stmt1, err := tx.PrepareNamed("update user set bind_types = bind_types|:bind_type where id=:to_user_id and verified=1 and bind_types&:bind_type=0") if err != nil { tx.Rollback() return } rslt1, err := stmt1.Exec(para) if err != nil { tx.Rollback() return } rowsAffected1, err := rslt1.RowsAffected() if err != nil { tx.Rollback() return } // user 删除 UserId stmt2, err := tx.PrepareNamed("delete from user where id=:user_id and verified=0 and bind_types=:bind_type") if err != nil { tx.Rollback() return } rslt2, err := stmt2.Exec(para) if err != nil { tx.Rollback() return } rowsAffected2, err := rslt2.RowsAffected() if err != nil { tx.Rollback() return } // user_email 更新 item stmt3, err := tx.PrepareNamed("update user_email set user_id=:to_user_id, verified=1 where user_id=:user_id and verified=0") if err != nil { tx.Rollback() return } rslt3, err := stmt3.Exec(para) if err != nil { tx.Rollback() return } rowsAffected3, err := rslt3.RowsAffected() if err != nil { tx.Rollback() return } if rowsAffected1 != rowsAffected2 || rowsAffected1 != rowsAffected3 { err = fmt.Errorf("绑定用户 %d 到用户 %d 失败", para.UserId, para.ToUserId) tx.Rollback() return } err = tx.Commit() return }
// 通过 微信 注册一个账户. // 如果 nickname 为空, 则默认为 openid // 如果 timestamp == 0 则默认使用当前时间 func AddByWechat(openid, nickname string, timestamp int64) (userId int64, err error) { userId, err = userid.GetId() if err != nil { return } if nickname == "" { nickname = openid } if timestamp == 0 { timestamp = time.Now().Unix() } para := struct { UserId int64 `sqlx:"user_id"` BindType BindType `sqlx:"bind_type"` OpenId string `sqlx:"openid"` Nickname string `sqlx:"nickname"` Password []byte `sqlx:"password"` PasswordTag []byte `sqlx:"password_tag"` Salt []byte `sqlx:"salt"` CreateTime int64 `sqlx:"create_time"` }{ UserId: userId, BindType: BindTypeWechat, OpenId: openid, Nickname: nickname, Password: emptyByteSlice, PasswordTag: random.NewRandomEx(), Salt: emptyByteSlice, CreateTime: timestamp, } tx, err := db.GetDB().Beginx() if err != nil { return } // user_wechat 表增加一个 item stmt1, err := tx.Prepare("insert into user_wechat(user_id, openid, verified) values(?, ?, 0)") if err != nil { tx.Rollback() return } if _, err = stmt1.Exec(para.UserId, para.OpenId); err != nil { tx.Rollback() return } // user 表增加一个 item stmt2, err := tx.PrepareNamed("insert into user(id, nickname, bind_types, password, password_tag, salt, create_time, verified) values(:user_id, :nickname, :bind_type, :password, :password_tag, :salt, :create_time, 0)") if err != nil { tx.Rollback() return } if _, err = stmt2.Exec(para); err != nil { tx.Rollback() return } err = tx.Commit() return }
// 通过 微博 注册一个账户. // 如果 nickname 为空, 则默认为 openid // 如果 timestamp == 0 则默认使用当前时间 func AddByWeibo(openid, nickname string, timestamp int64) (user *User, err error) { userId, err := userid.GetId() if err != nil { return } if nickname == "" { nickname = openid } if timestamp == 0 { timestamp = time.Now().Unix() } para := struct { UserId int64 `sqlx:"user_id"` BindType BindType `sqlx:"bind_type"` OpenId string `sqlx:"openid"` Nickname string `sqlx:"nickname"` Password []byte `sqlx:"password"` PasswordTag string `sqlx:"password_tag"` Salt []byte `sqlx:"salt"` CreateTime int64 `sqlx:"create_time"` Verified bool `sqlx:"verified"` }{ UserId: userId, BindType: BindTypeWeibo, OpenId: openid, Nickname: nickname, Password: emptyByteSlice, PasswordTag: NewPasswordTag(), Salt: emptyByteSlice, CreateTime: timestamp, Verified: defaultVerified, } tx, err := db.GetDB().Beginx() if err != nil { return } // user_weibo 表增加一个 item stmt1, err := tx.Prepare("insert into user_weibo(user_id, openid, verified) values(?, ?, ?)") if err != nil { tx.Rollback() return } if _, err = stmt1.Exec(para.UserId, para.OpenId, para.Verified); err != nil { tx.Rollback() return } // user 表增加一个 item stmt2, err := tx.PrepareNamed("insert into user(id, nickname, bind_types, password, password_tag, salt, create_time, verified) values(:user_id, :nickname, :bind_type, :password, :password_tag, :salt, :create_time, :verified)") if err != nil { tx.Rollback() return } if _, err = stmt2.Exec(para); err != nil { tx.Rollback() return } if err = tx.Commit(); err != nil { return } user = &User{ Id: para.UserId, Nickname: para.Nickname, BindTypes: para.BindType, Password: para.Password, PasswordTag: para.PasswordTag, Salt: para.Salt, CreateTime: para.CreateTime, Verified: para.Verified, } return }