user-login

This commit is contained in:
tcq 2024-01-31 17:32:39 +08:00
parent 39d4a0ce92
commit c7eadfb5c9
8 changed files with 331 additions and 6 deletions

21
Service/rpc-service.go Normal file
View File

@ -0,0 +1,21 @@
package service
import (
"net/rpc"
"user-srv/config"
"github.com/sirupsen/logrus"
)
func wechatRpcClient() (*rpc.Client, error) {
// dsn:="dingtalk:9090"
dsn := config.WECHAT_DSN
client, err := rpc.Dial("tcp", dsn)
if err != nil {
logrus.WithFields(logrus.Fields{
"func": "rpcClient",
}).Warnf("rpc.Dial: %s", err.Error())
return nil, err
}
return client, nil
}

View File

@ -2,19 +2,137 @@ package service
import (
"context"
"errors"
"fmt"
"net/url"
"os"
pb "user-srv/pb/api"
"user-srv/mysql"
"user-srv/redis"
"github.com/sirupsen/logrus"
"myschools.me/home-care/homecare-base/wechat"
"myschools.me/tcq/user-base/utils"
)
type UserService struct {
pb.UnimplementedUserServiceServer
}
// 用户登录
// 用户关注扫码登录
func (u *UserService) Login(ctx context.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) {
//ToDo
//ToDo 通过获取微信二维码获取的uuid 来获取微信事件中的
//通过 code 获取 用户openid
client, err := wechatRpcClient()
if err != nil {
return nil, err
}
wechatUserInfoReq := &wechat.OauthUserInfoRequest{
ID: req.Code,
}
wechatUserInfoResp := new(wechat.OauthUserInfoResponse)
if err := client.Call("Oauth.UserInfo", wechatUserInfoReq, wechatUserInfoResp); err != nil {
logrus.WithFields(logrus.Fields{
"func": "UserLogin",
}).Warnf("client.Call[Oauth.UserInfo]: %s", err.Error())
return nil, err
}
//openid 不存在
if wechatUserInfoResp.OpenID == "" {
return nil, nil
}
//
// 通过openid查找用户信息
user, err := mysql.UserDetailByOpenId(&wechatUserInfoResp.OpenID)
if err != nil {
logrus.WithFields(logrus.Fields{
"func": "UserLogin",
}).Warnf("mysql.UserDetail: %s", err.Error())
return nil, err
}
if user.ID == 0 {
go UserSendUnBindMsg(&wechatUserInfoResp.OpenID, nil)
return nil, errors.New("用户未注册,请前往公众号注册")
}
//生成用户token
token := utils.GenIDStr()
if err := redis.UserTokenSet(&token, user); err != nil {
logrus.WithFields(logrus.Fields{
"func": "UserLogin",
}).Warnf("redis.UserTokenSet: %s", err.Error())
return nil, err
}
//返回结果
// result := struct {
// Token string
// Expire int64
// User *model.User
// }{
// Token: token,
// Expire: 7200,
// User: user,
// }
return &pb.LoginResponse{
Token: "12345678",
Token: token,
Orgid: "1",
}, nil
}
func UserSendUnBindMsg(openid, reqid *string) {
// rpc调用发送公众号消息
client, err := wechatRpcClient()
if err != nil {
return
}
child := make(map[string]*wechat.TemplateDataItem)
child["thing2"] = &wechat.TemplateDataItem{
Value: "尊敬的用户",
Color: "",
}
child["thing9"] = &wechat.TemplateDataItem{
Value: "节能助手",
Color: "",
}
child["short_thing7"] = &wechat.TemplateDataItem{
Value: "前往绑定",
Color: "",
}
child["character_string13"] = &wechat.TemplateDataItem{
Value: (*reqid)[0:8],
Color: "",
}
appid := os.Getenv("WECHAT_APPID")
if appid == "" {
appid = "wxd69449ebd878fa6d"
}
redirect_uri := os.Getenv("WECHAT_REDIRECT_URI")
if redirect_uri == "" {
redirect_uri = "http://live.yyjishu.com/wechat#/bind"
}
Url := fmt.Sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=", appid) + url.QueryEscape(redirect_uri) + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"
req := &wechat.MessageTemplateSendRequest{
ToUser: *openid,
TemplateID: "P54vXL4yOpmyMzk4x3-VpIDMSq4u5sBM-IDApMXP_WE",
URL: Url,
Color: "",
Data: child,
}
resp := new(wechat.MessageTemplateSendResponse)
if err := client.Call("Message.TemplateSend", req, resp); err != nil {
logrus.WithFields(logrus.Fields{
"func": "UserSendUnBindMsg",
"reqid": *reqid,
}).Warnf("client.Call[Message.TemplateSend]: %s", err.Error())
return
}
}

View File

@ -18,6 +18,7 @@ var (
RedisHost string
RedisPassword string
RedisDB int
WECHAT_DSN string
)
func ConfigInit() {
@ -90,7 +91,7 @@ func ConfigInit() {
MYSQL_HOST = func() string {
host := os.Getenv("MYSQL_HOST")
if host == "" {
host = "root:123456@tcp(127.0.0.1:3306)/ceshi?charset=utf8mb4&parseTime=True&loc=Local"
host = "root:123456@tcp(127.0.0.1:3306)/grpc?charset=utf8mb4&parseTime=True&loc=Local"
}
return host
}()
@ -118,4 +119,13 @@ func ConfigInit() {
return db
}()
//微信
WECHAT_DSN = func() string {
dsn := os.Getenv("WECHAT_DSN")
if dsn == "" {
dsn = "127.0.0.1:9091"
}
return dsn
}()
}

12
go.mod
View File

@ -1,6 +1,8 @@
module user-srv
go 1.21.1
go 1.21.4
toolchain go1.21.6
require (
github.com/gomodule/redigo v1.8.9
@ -17,6 +19,11 @@ require (
gorm.io/plugin/dbresolver v1.5.0
)
require (
github.com/bwmarrin/snowflake v0.3.0 // indirect
myschools.me/home-care/homecare-base v0.0.0-20240117071311-7c63d4cc0d29 // indirect
)
require (
github.com/armon/go-metrics v0.4.1 // indirect
github.com/fatih/color v1.14.1 // indirect
@ -35,7 +42,7 @@ require (
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/lestrrat-go/strftime v1.0.6 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
@ -45,4 +52,5 @@ require (
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect
myschools.me/tcq/user-base v0.0.0-20240131081333-dd818f008c5f
)

9
go.sum
View File

@ -13,6 +13,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
@ -133,6 +135,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
@ -232,6 +236,7 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -277,3 +282,7 @@ gorm.io/gorm v1.25.6 h1:V92+vVda1wEISSOMtodHVRcUIOPYa2tgQtyF+DfFx+A=
gorm.io/gorm v1.25.6/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/plugin/dbresolver v1.5.0 h1:XVHLxh775eP0CqVh3vcfJtYqja3uFl5Wr3cKlY8jgDY=
gorm.io/plugin/dbresolver v1.5.0/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0=
myschools.me/home-care/homecare-base v0.0.0-20240117071311-7c63d4cc0d29 h1:/EuDrMBkasENuc4DAyUEvJMNXC0QYVLyH9SiJWHu4Jk=
myschools.me/home-care/homecare-base v0.0.0-20240117071311-7c63d4cc0d29/go.mod h1:70trCTlFSgoggPL1S0i1yDRfvVxOHqNwU9Bu9guPJkI=
myschools.me/tcq/user-base v0.0.0-20240131081333-dd818f008c5f h1:2Z0FSZHBBVzek2KYPbowRYcnINI7cqGMRQSaQeVGknM=
myschools.me/tcq/user-base v0.0.0-20240131081333-dd818f008c5f/go.mod h1:oq0aFBhUz53bA7nOL1kkmUAzCnf49PlcU13qXChqPfI=

View File

@ -1,10 +1,17 @@
package mysql
import (
model "myschools.me/tcq/user-base/model"
)
func InitTable() error {
//不初始化表时返回
if !_conf.InitTable {
return nil
}
//初始表
db, _ := New()
db.AutoMigrate(&model.User{})
//成功初始化后返回
return nil

111
mysql/user-mysql.go Normal file
View File

@ -0,0 +1,111 @@
package mysql
import (
"gorm.io/gorm"
model "myschools.me/tcq/user-base/model"
)
func UserDetailByOpenId(openid *string) (user *model.User, err error) {
db, _ := New()
user = &model.User{}
if err := db.Where("openid = ?", *openid).First(user).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return nil, err
}
}
return user, nil
}
func UserDetailById(id *uint, db *gorm.DB) (user *model.User, err error) {
if db == nil {
db, _ = New()
}
user = &model.User{}
if err := db.Where("id = ?", *id).First(user).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return nil, err
}
}
return user, nil
}
func UserDetailByMobile(mobile *string, db *gorm.DB) (user *model.User, err error) {
if db == nil {
db, _ = New()
}
user = &model.User{}
if err := db.Where("mobile = ?", *mobile).First(user).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return nil, err
}
}
return user, nil
}
func UserCreate(username, mobile, role, projectid *string, db *gorm.DB) (*model.User, error) {
if db == nil {
db, _ = New()
}
user := &model.User{
UserName: *username,
Mobile: *mobile,
Role: *role,
ProjectID: *projectid,
}
if err := db.Create(user).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return nil, err
}
}
return user, nil
}
func UserUpdate(user *model.User, db *gorm.DB) error {
if db == nil {
db, _ = New()
}
if err := db.Model(&model.User{}).Where("id=?", user.ID).Updates(user).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return err
}
}
return nil
}
func UserDelete(userid *uint) error {
db, _ := New()
if err := db.Where("id=?", *userid).Delete(&model.User{}).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return err
}
}
return nil
}
func UserList(index, size int, name, role string) ([]*model.User, int64, error) {
db, _ := New()
users := make([]*model.User, 0)
var count int64
query := db.Model(&model.User{})
if name != "" {
query.Where("user_name like ?", "%"+name+"%")
}
if role != "" {
query.Where("role = ?", role)
}
if err := query.Count(&count).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return nil, 0, err
}
}
if err := query.Offset((index - 1) * size).Limit(size).Find(&users).Error; err != nil {
if err != gorm.ErrRecordNotFound {
return nil, 0, err
}
}
return users, count, nil
}

41
redis/user-redis.go Normal file
View File

@ -0,0 +1,41 @@
package redis
import (
"encoding/json"
"errors"
"time"
"github.com/sirupsen/logrus"
"myschools.me/tcq/user-base/model"
)
// 存储用户的Token
func UserTokenSet(key *string, usr *model.User) error {
err := Set(*key, usr, 7210*time.Second)
if err != nil {
logrus.WithFields(logrus.Fields{
"func": "UserTokenSet",
}).Warnf("Set: %s", err.Error())
return err
}
return nil
}
// 从redis中获取用户信息最佳实践经验建议把此代码放service层
func UserTokenGet(token *string) (*model.User, error) {
b, err := GetBytes(token)
if err != nil {
return nil, err
}
if b == nil {
return nil, errors.New("无效token,请重新登录!")
}
var user *model.User
if err := json.Unmarshal(*b, &user); err != nil {
return nil, err
}
return user, nil
}