瀏覽代碼

7.21存档。实现达人登录

Yankun168 9 月之前
父節點
當前提交
fd8baac2d2

+ 11 - 1
app/api/youngee_talent_api/talent_post_api.go

@@ -20,8 +20,18 @@ func (*talentPostApi) Login(r *ghttp.Request) {
 	}
 }
 
+// 获取手机号码接口测试
+//func (*talentPostApi) GetPhoneNum(r *ghttp.Request) {
+//	// 向微信服务端校验登录凭证
+//	res := youngee_talent_service.GetPhoneNum1(r)
+//	err := r.Response.WriteJson(res)
+//	if err != nil {
+//		panic("write response error")
+//	}
+//}
+
 // Login 达人端手机号登录
-func (*talentPostApi) LoginFromSms(r *ghttp.Request) {
+func (*talentPostApi) SmsLogin(r *ghttp.Request) {
 	// 向微信服务端校验登录凭证
 	res := youngee_talent_service.LoginFromSms(r)
 	err := r.Response.WriteJson(res)

+ 6 - 4
app/model/youngee_talent_model/wx_login_info.go

@@ -2,10 +2,11 @@ package youngee_talent_model
 
 // WxLoginInfo 达人端微信登录后传给服务端的信息
 type WxLoginInfo struct {
-	Code     string `json:"code" v:"required#code must not be null"`
-	Nickname string `json:"nickname" v:"required#nickname must not be null"`
-	Avatar   string `json:"avatar" v:"required#avatar must not be null"`
-	Gender   int    `json:"gender" v:"required#gender must not be null"`
+	Code         string `json:"code" v:"required#code must not be null"`
+	Nickname     string `json:"nickname" v:"required#nickname must not be null"`
+	Avatar       string `json:"avatar" v:"required#avatar must not be null"`
+	Gender       int    `json:"gender" v:"required#gender must not be null"`
+	GetPhoneCode string `json:"getPhoneCode"`
 }
 
 // LoginResultData 服务端处理完达人登录流程后返回给达人端的信息
@@ -13,4 +14,5 @@ type LoginResultData struct {
 	Token    string `json:"token"`
 	Nickname string `json:"nickname"`
 	Avatar   string `json:"avatar"`
+	Phone    string `json:"phone"`
 }

+ 117 - 9
app/service/youngee_talent_service/LoginFromSms.go

@@ -1,11 +1,21 @@
 package youngee_talent_service
 
 import (
+	"encoding/json"
 	"fmt"
+	"github.com/gogf/gf/crypto/gmd5"
+	"github.com/gogf/gf/frame/g"
 	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/os/gtime"
+	"net/http"
+	"youngmini_server/app/dao"
+	"youngmini_server/app/model"
+	"youngmini_server/app/model/youngee_talent_model"
+	"youngmini_server/app/utils"
 )
 
 type LoginReq struct {
+	Code  string `json:"code"` //来自uni.login返回的code
 	Phone string `json:"phone"`
 	Vcode string `json:"vcode"`
 }
@@ -17,16 +27,114 @@ func LoginFromSms(r *ghttp.Request) *TalentHttpResult {
 	if err != nil {
 		fmt.Printf("前端数据解析错误")
 	}
-	vcode := GetCode()
-	fmt.Println("验证码为=====>", vcode)
+	//通过手机号和验证码构造出key。
+	VcodeKey := fmt.Sprintf("%s%s", "c_user:", l.Phone)
+	//viewCount, err := g.Redis().DoVar("GET", projectViewKey)
+	Vcode, err := g.Redis().DoVar("GET", VcodeKey)
+	//验证码正确
+	if Vcode.String() == l.Vcode {
+		//进行微信登录
+		appId := g.Config().GetString("miniapp.appid")
+		secret := g.Config().GetString("miniapp.appsecret")
+		url := fmt.Sprintf(urlformat, appId, secret, l.Code)
+		//通过前端uni.login获得了code用于拼接url
+		resp, err := http.Get(url)
+		if err != nil {
+			return &TalentHttpResult{Code: -2, Msg: err.Error()}
+		}
+		//http.Get(url)之后要关闭
+		defer resp.Body.Close()
 
-	err = SendCode(l.Phone, vcode)
-	if err != nil {
-		return &TalentHttpResult{Code: -1, Msg: "短信发送失败"}
-	}
+		// 解码微信服务端传来的信息
+		wxResp := WxLoginResult{}
+		decoder := json.NewDecoder(resp.Body)
+		if err = decoder.Decode(&wxResp); err != nil {
+			return &TalentHttpResult{Code: -3, Msg: "decode json from wx fail"}
+		}
+
+		if wxResp.ErrCode != 0 {
+			fmt.Printf("错误码:%d, 错误信息:%s", wxResp.ErrCode, wxResp.ErrMsg)
+			return &TalentHttpResult{Code: -4, Msg: fmt.Sprintf("errCode:%d, errmsg:%s", wxResp.ErrCode, wxResp.ErrMsg)}
+		}
+
+		// 根据电话号码,查询达人信息。达人与电话号码一一对应
+		rec, err := g.DB().Model("youngee_talent_info").One("talent_phone_number", l.Phone)
+		if err != nil {
+			return &TalentHttpResult{Code: -5, Msg: "get talent info failed"}
+		}
+
+		// 如果达人被拉黑,则返回
+		if rec != nil && rec[dao.YoungeeTalentInfo.Columns.InBlacklist].Int() > 0 {
+			return &TalentHttpResult{Code: -6, Msg: "in black list"}
+		}
+
+		//手机号登录使用默认名称和头像
+		//获得登录后的返回结果对象
+		res := youngee_talent_model.LoginResultData{}
+		var newTalentId string
+		var defaultAvatar = "https://horastar.obs.cn-east-3.myhuaweicloud.com/talent/logoxin01.png"
+		if rec == nil {
+			// 如果数据库中不存在此达人,则插入新的达人信息
+			// 首先生成达人唯一id
+			newTalentId = utils.GetUuid.GetTalentId()
+			talentInfo := model.YoungeeTalentInfo{
+				Id:                newTalentId,
+				TalentWxOpenid:    wxResp.OpenId,
+				Avatar:            defaultAvatar,        //使用默认头像
+				TalentWxNickname:  "样叽用户" + newTalentId, //使用默认名称
+				TalentPhoneNumber: l.Phone,              //达人电话
+				Canwithdraw:       0,
+				Income:            0,
+				Withdrawing:       0,
+				Withdrawed:        0,
+				LastLoginDate:     gtime.Now(),
+				CreateDate:        gtime.Now(),
+			}
 
-	//验证码存redis
-	_ = SetRedis(l.Phone, vcode)
+			res.Avatar = defaultAvatar
+			res.Nickname = "样叽用户" + newTalentId
 
-	return &TalentHttpResult{Code: 1, Msg: "sendSmsCodeSuccess"}
+			_, err = g.DB().Model(dao.YoungeeTalentInfo.Table).Data(talentInfo).Insert()
+			if err != nil {
+				return &TalentHttpResult{Code: -7, Msg: "get talentId failed"}
+			}
+		} else { //已存在达人,则读取达人id
+			newTalentId = rec["id"].String()
+			res.Avatar = rec["avatar"].String()
+			res.Nickname = rec["talent_wx_nickname"].String()
+			// 更新达人最近登录时间
+			_, err = g.DB().Model(dao.YoungeeTalentInfo.Table).Data(
+				g.Map{
+					"last_login_date": gtime.Now(),
+				}).Where("id", newTalentId).Update()
+			if err != nil {
+				return &TalentHttpResult{Code: -8, Msg: "update talent last login date failed"}
+			}
+		}
+		// 用微信的openid和SessionKey的md5做为token。会一直生效
+		token, err := gmd5.EncryptString(wxResp.OpenId + wxResp.SessionKey)
+		fmt.Println("token is " + token)
+		if err != nil {
+			return &TalentHttpResult{Code: -9, Msg: "generate key failed"}
+		}
+		res.Token = token
+
+		// 以token为键保存session 存储在服务器中
+		//自动生成一个 session ID 并通过 Cookie 将其发送给客户端,以便在后续请求中识别该客户端的会话
+		//自动生成一个 session ID,并通过 `Set-Cookie` 头将其发送给客户端,前端可以通过r.header['Set-Cookie']获取cookie
+		err = r.Session.Set(token, g.Map{
+			"talentId":     newTalentId,
+			"wxOpenId":     wxResp.OpenId,
+			"wxSessionKey": wxResp.SessionKey,
+		})
+
+		if err != nil {
+			return &TalentHttpResult{Code: -10, Msg: "set session failed"}
+		}
+
+		return &TalentHttpResult{Code: 0, Msg: "SmsLoginSuccess", Data: res}
+
+	} else { //验证码不正确
+		return &TalentHttpResult{Code: -1, Msg: "验证码错误"}
+	}
 }

+ 86 - 13
app/service/youngee_talent_service/wxlogin.go

@@ -1,8 +1,10 @@
 package youngee_talent_service
 
 import (
+	"bytes"
 	"encoding/json"
 	"fmt"
+	"github.com/gogf/gf/encoding/gjson"
 	"net/http"
 	"youngmini_server/app/dao"
 	"youngmini_server/app/model"
@@ -23,10 +25,36 @@ type WxLoginResult struct {
 	ErrMsg     string `json:"errmsg"`
 }
 
+// 定义 Watermark 结构体
+type Watermark struct {
+	Timestamp int    `json:"timestamp"`
+	AppID     string `json:"appid"`
+}
+
+// 定义 PhoneInfo 结构体
+type PhoneInfo struct {
+	PhoneNumber     string    `json:"phoneNumber"`
+	PurePhoneNumber string    `json:"purePhoneNumber"`
+	CountryCode     string    `json:"countryCode"`
+	Watermark       Watermark `json:"watermark"`
+}
+
+// 定义响应结构体 GetPhoneRes
+type GetPhoneRes struct {
+	ErrCode   int       `json:"errcode"`
+	ErrMsg    string    `json:"errmsg"`
+	PhoneInfo PhoneInfo `json:"phone_info"`
+}
+
 const (
-	urlformat = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
+	urlgetphone = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s"
+	urlformat   = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
 )
 
+type GetPhoneRequestBody struct {
+	Code string `json:"code"`
+}
+
 func WxLogin(r *ghttp.Request) *TalentHttpResult {
 
 	l := youngee_talent_model.WxLoginInfo{}
@@ -59,8 +87,11 @@ func WxLogin(r *ghttp.Request) *TalentHttpResult {
 		return &TalentHttpResult{Code: -4, Msg: fmt.Sprintf("errCode:%d, errmsg:%s", wxResp.ErrCode, wxResp.ErrMsg)}
 	}
 
+	//为了获得手机号
+	phoneNum := getPhoneNum(l.GetPhoneCode)
+
 	// 根据openid查询达人信息
-	rec, err := g.DB().Model("youngee_talent_info").One("talent_wx_openid", wxResp.OpenId)
+	rec, err := g.DB().Model("youngee_talent_info").One("talent_phone_number", phoneNum)
 	if err != nil {
 		return &TalentHttpResult{Code: -5, Msg: "get talent info failed"}
 	}
@@ -69,6 +100,7 @@ func WxLogin(r *ghttp.Request) *TalentHttpResult {
 	if rec != nil && rec[dao.YoungeeTalentInfo.Columns.InBlacklist].Int() > 0 {
 		return &TalentHttpResult{Code: -6, Msg: "in black list"}
 	}
+
 	//获得登录后的返回结果对象
 	res := youngee_talent_model.LoginResultData{}
 	var newTalentId string
@@ -77,19 +109,21 @@ func WxLogin(r *ghttp.Request) *TalentHttpResult {
 		// 首先生成达人唯一id
 		newTalentId = utils.GetUuid.GetTalentId()
 		talentInfo := model.YoungeeTalentInfo{
-			Id:               newTalentId,
-			TalentWxOpenid:   wxResp.OpenId,
-			Avatar:           l.Avatar,
-			TalentWxNickname: l.Nickname,
-			Canwithdraw:      0,
-			Income:           0,
-			Withdrawing:      0,
-			Withdrawed:       0,
-			LastLoginDate:    gtime.Now(),
-			CreateDate:       gtime.Now(),
+			Id:                newTalentId,
+			TalentWxOpenid:    wxResp.OpenId,
+			Avatar:            l.Avatar,
+			TalentWxNickname:  l.Nickname,
+			TalentPhoneNumber: phoneNum, //插入手机号
+			Canwithdraw:       0,
+			Income:            0,
+			Withdrawing:       0,
+			Withdrawed:        0,
+			LastLoginDate:     gtime.Now(),
+			CreateDate:        gtime.Now(),
 		}
 		res.Avatar = l.Avatar
 		res.Nickname = l.Nickname
+		res.Phone = phoneNum //接口返回手机号
 		_, err = g.DB().Model(dao.YoungeeTalentInfo.Table).Data(talentInfo).Insert()
 		if err != nil {
 			return &TalentHttpResult{Code: -7, Msg: "get talentId failed"}
@@ -99,6 +133,7 @@ func WxLogin(r *ghttp.Request) *TalentHttpResult {
 		newTalentId = rec["id"].String()
 		res.Avatar = rec["avatar"].String()
 		res.Nickname = rec["talent_wx_nickname"].String()
+		res.Phone = rec["talent_phone_number"].String()
 		// 更新达人最近登录时间
 		_, err = g.DB().Model(dao.YoungeeTalentInfo.Table).Data(
 			g.Map{
@@ -134,7 +169,45 @@ func WxLogin(r *ghttp.Request) *TalentHttpResult {
 	return &TalentHttpResult{Code: 0, Msg: "success", Data: res}
 }
 
-func IsLogin(r *ghttp.Request) *TalentHttpResult {
+func getPhoneNum(code string) string {
+	//获取access_token
+	accessToken, err := getAndCacheWxAccessToken()
+	fmt.Println("accesstoken===>", accessToken)
+	//post获取电话号码
+	url := fmt.Sprintf(urlgetphone, accessToken)
+	fmt.Println("url   ", url)
+
+	getPhoneRequest := GetPhoneRequestBody{
+		Code: code,
+	}
+	jsonBody, err := gjson.Encode(getPhoneRequest)
 
+	// 发送 POST 请求
+	response, err := http.Post(url, "application/json", bytes.NewBuffer(jsonBody))
+	if err != nil {
+		fmt.Printf("post getphoneNum failed")
+	}
+	defer response.Body.Close()
+
+	// 解码微信服务端传来的信息
+	var getphoneResp = GetPhoneRes{}
+	decoder := json.NewDecoder(response.Body)
+	if err = decoder.Decode(&getphoneResp); err != nil {
+		fmt.Printf("decode json from wx fail")
+	}
+
+	if getphoneResp.ErrCode != 0 {
+		fmt.Printf("错误码:%d, 错误信息:%s", getphoneResp.ErrCode, getphoneResp.ErrMsg)
+		fmt.Sprintf("errCode:%d, errmsg:%s", getphoneResp.ErrCode, getphoneResp.ErrMsg)
+	}
+
+	// 打印解析后的结构体内容
+	fmt.Println("获取号码接口响应====》", getphoneResp.PhoneInfo.PhoneNumber)
+
+	return getphoneResp.PhoneInfo.PhoneNumber
+
+}
+
+func IsLogin(r *ghttp.Request) *TalentHttpResult {
 	return &TalentHttpResult{Code: 0, Msg: "success!"}
 }

二進制
bin/main.exe


二進制
bin/main.exe~