3
This commit is contained in:
parent
ec88138888
commit
dfda2e2425
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,3 +18,4 @@
|
||||
.idea/
|
||||
.git/
|
||||
.DS_Store/
|
||||
.tmp/
|
||||
@ -1,12 +1,18 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"hepa-calc-api/api/dao"
|
||||
"hepa-calc-api/api/model"
|
||||
"hepa-calc-api/api/requests"
|
||||
"hepa-calc-api/api/responses"
|
||||
"hepa-calc-api/api/service"
|
||||
"hepa-calc-api/extend/weChat"
|
||||
"hepa-calc-api/global"
|
||||
"hepa-calc-api/utils"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Login struct{}
|
||||
@ -29,6 +35,18 @@ func (r *Login) LoginPhone(c *gin.Context) {
|
||||
|
||||
// LoginWx 微信授权登录
|
||||
func (r *Login) LoginWx(c *gin.Context) {
|
||||
userService := service.UserService{}
|
||||
// 处理用户头像
|
||||
avatar, err := userService.HandleUserAvatar("https://thirdwx.qlogo.cn/mmopen/vi_32/dzhWq43iaB5GyJJUbajibSQtIt6d4Y9QPk5ImB1C14fPk6AOtcgaPztUzjKwb9kmPtqNpyCal5cEyw0YyTr1QEbdtHiaOViay4RgSpdm2XaduXA/132")
|
||||
if err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(avatar)
|
||||
responses.Ok(c)
|
||||
return
|
||||
|
||||
loginRequest := requests.LoginRequest{}
|
||||
req := loginRequest.LoginWx
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
@ -42,5 +60,88 @@ func (r *Login) LoginWx(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
responses.Ok(c)
|
||||
// 获取微信网页授权access_token
|
||||
webAccessToken, err := weChat.GetWebAccessToken(req.Code)
|
||||
if err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
fmt.Println(webAccessToken)
|
||||
|
||||
// 网页授权拉取用户信息
|
||||
userInfo, err := weChat.GetUserInfo(webAccessToken.AccessToken, webAccessToken.OpenId)
|
||||
if err != nil {
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
fmt.Println(userInfo)
|
||||
|
||||
// 检测用户信息
|
||||
userDao := dao.UserDao{}
|
||||
maps := make(map[string]interface{})
|
||||
maps["open_id"] = webAccessToken.OpenId
|
||||
user, _ := userDao.GetUser(maps)
|
||||
// 新用户处理方式
|
||||
if user == nil {
|
||||
// 开始事务
|
||||
tx := global.Db.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
userService := service.UserService{}
|
||||
// 处理用户头像
|
||||
avatar, err := userService.HandleUserAvatar(userInfo.HeadImgUrl)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 新增用户
|
||||
user := &model.User{
|
||||
UserName: userInfo.Nickname,
|
||||
Mobile: "",
|
||||
RegisterSource: req.Source,
|
||||
OpenId: userInfo.OpenId,
|
||||
UnionId: userInfo.UnionId,
|
||||
Age: nil,
|
||||
Sex: userInfo.Sex,
|
||||
Avatar: avatar,
|
||||
IsMember: 0,
|
||||
MemberExpireDate: nil,
|
||||
LoginAt: model.LocalTime(time.Now()),
|
||||
LoginIp: req.LoginIp,
|
||||
}
|
||||
user, err = userDao.AddUser(tx, user)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
responses.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取app用户信息
|
||||
var result *string
|
||||
if result == nil {
|
||||
// 新增app用户信息
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
}
|
||||
|
||||
// 下发token
|
||||
token := &utils.Token{
|
||||
UserId: fmt.Sprintf("%d", user.UserId),
|
||||
}
|
||||
|
||||
// 生成jwt
|
||||
jwt, err := token.NewJWT()
|
||||
if err != nil {
|
||||
responses.FailWithMessage("登陆失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
responses.OkWithData(jwt, c)
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"hepa-calc-api/api/model"
|
||||
"hepa-calc-api/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
// UserDto 用户表
|
||||
@ -19,7 +20,7 @@ type UserDto struct {
|
||||
Sex uint `json:"sex"` // 性别(0:未知 1:男 2:女)
|
||||
Avatar string `json:"avatar"` // 头像
|
||||
IsMember int `json:"is_member"` // 是否会员(0:否 1:是)
|
||||
MemberExpireDate model.LocalTime `json:"member_expire_date"` // 会员到期时间(非会员时为null)
|
||||
MemberExpireDate *time.Time `json:"member_expire_date"` // 会员到期时间(非会员时为null)
|
||||
LoginAt model.LocalTime `json:"login_at"` // 登陆时间
|
||||
LoginIp string `json:"login_ip"` // 登陆ip
|
||||
CreatedAt model.LocalTime `json:"created_at"` // 创建时间
|
||||
@ -34,8 +35,8 @@ func GetUserDto(m *model.User) *UserDto {
|
||||
Mobile: m.Mobile,
|
||||
UserStatus: m.UserStatus,
|
||||
RegisterSource: m.RegisterSource,
|
||||
Age: m.Age,
|
||||
Sex: m.Sex,
|
||||
Age: *m.Age,
|
||||
Sex: uint(m.Sex),
|
||||
Avatar: utils.AddOssDomain(m.Avatar),
|
||||
IsMember: m.IsMember,
|
||||
MemberExpireDate: m.MemberExpireDate,
|
||||
|
||||
@ -8,20 +8,20 @@ import (
|
||||
|
||||
// User 用户表
|
||||
type User struct {
|
||||
UserId int64 `gorm:"column:user_id;type:bigint(19);primary_key;comment:用户id" json:"user_id"`
|
||||
UserName string `gorm:"column:user_name;type:varchar(200);comment:用户名称" json:"user_name"`
|
||||
Mobile string `gorm:"column:mobile;type:varchar(20);comment:手机号;NOT NULL" json:"mobile"`
|
||||
UserStatus int `gorm:"column:user_status;type:tinyint(1);default:1;comment:状态(1:正常 2:禁用)" json:"user_status"`
|
||||
RegisterSource int `gorm:"column:register_source;type:tinyint(1);default:1;comment:注册来源(1:app注册 2:公众号注册)" json:"register_source"`
|
||||
OpenId string `gorm:"column:open_id;type:varchar(100);comment:用户微信标识" json:"open_id"`
|
||||
UnionId string `gorm:"column:union_id;type:varchar(100);comment:微信开放平台标识" json:"union_id"`
|
||||
Age uint `gorm:"column:age;type:int(10) unsigned;comment:年龄" json:"age"`
|
||||
Sex uint `gorm:"column:sex;type:tinyint(1) unsigned;default:0;comment:性别(0:未知 1:男 2:女)" json:"sex"`
|
||||
Avatar string `gorm:"column:avatar;type:varchar(255);comment:头像" json:"avatar"`
|
||||
IsMember int `gorm:"column:is_member;type:tinyint(1);default:0;comment:是否会员(0:否 1:是)" json:"is_member"`
|
||||
MemberExpireDate LocalTime `gorm:"column:member_expire_date;type:datetime;comment:会员到期时间(非会员时为null)" json:"member_expire_date"`
|
||||
LoginAt LocalTime `gorm:"column:login_at;type:datetime;comment:登陆时间" json:"login_at"`
|
||||
LoginIp string `gorm:"column:login_ip;type:varchar(255);comment:登陆ip" json:"login_ip"`
|
||||
UserId int64 `gorm:"column:user_id;type:bigint(19);primary_key;comment:用户id" json:"user_id"`
|
||||
UserName string `gorm:"column:user_name;type:varchar(200);comment:用户名称" json:"user_name"`
|
||||
Mobile string `gorm:"column:mobile;type:varchar(20);comment:手机号;NOT NULL" json:"mobile"`
|
||||
UserStatus int `gorm:"column:user_status;type:tinyint(1);default:1;comment:状态(1:正常 2:禁用)" json:"user_status"`
|
||||
RegisterSource int `gorm:"column:register_source;type:tinyint(1);default:1;comment:注册来源(1:app注册 2:公众号注册)" json:"register_source"`
|
||||
OpenId string `gorm:"column:open_id;type:varchar(100);comment:用户微信标识" json:"open_id"`
|
||||
UnionId string `gorm:"column:union_id;type:varchar(100);comment:微信开放平台标识" json:"union_id"`
|
||||
Age *uint `gorm:"column:age;type:int(10) unsigned;comment:年龄" json:"age"`
|
||||
Sex int `gorm:"column:sex;type:tinyint(1) unsigned;default:0;comment:性别(0:未知 1:男 2:女)" json:"sex"`
|
||||
Avatar string `gorm:"column:avatar;type:varchar(255);comment:头像" json:"avatar"`
|
||||
IsMember int `gorm:"column:is_member;type:tinyint(1);default:0;comment:是否会员(0:否 1:是)" json:"is_member"`
|
||||
MemberExpireDate *time.Time `gorm:"column:member_expire_date;type:datetime;comment:会员到期时间(非会员时为null)" json:"member_expire_date"`
|
||||
LoginAt LocalTime `gorm:"column:login_at;type:datetime;comment:登陆时间" json:"login_at"`
|
||||
LoginIp string `gorm:"column:login_ip;type:varchar(255);comment:登陆ip" json:"login_ip"`
|
||||
Model
|
||||
}
|
||||
|
||||
|
||||
@ -6,5 +6,7 @@ type LoginRequest struct {
|
||||
|
||||
// LoginWx 微信授权登录
|
||||
type LoginWx struct {
|
||||
Code string `json:"code" form:"code" label:"授权码"`
|
||||
Code string `json:"code" form:"code" label:"授权码"`
|
||||
Source int `json:"source" form:"source" label:"来源(1:app 2:公众号)"`
|
||||
LoginIp string `json:"login_ip" form:"login_ip" label:"登录ip"`
|
||||
}
|
||||
|
||||
@ -78,11 +78,8 @@ func publicRouter(r *gin.Engine, api controller.Api) {
|
||||
// 手机号登录
|
||||
loginGroup.POST("/phone", api.Login.LoginPhone)
|
||||
|
||||
wxGroup := loginGroup.Group("/wx")
|
||||
{
|
||||
// 微信授权登录
|
||||
wxGroup.POST("", api.Login.LoginWx)
|
||||
}
|
||||
// 微信授权登录
|
||||
loginGroup.POST("/wx", api.Login.LoginWx)
|
||||
}
|
||||
|
||||
// 验证码
|
||||
|
||||
@ -1,4 +1,41 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hepa-calc-api/extend/aliyun"
|
||||
"hepa-calc-api/utils"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserService struct {
|
||||
}
|
||||
|
||||
// HandleUserAvatar 处理用户头像
|
||||
func (r *UserService) HandleUserAvatar(wxAvatar string) (avatar string, err error) {
|
||||
if wxAvatar == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// 下载文件到内存
|
||||
ram, err := aliyun.GetObjectToRAM(wxAvatar)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 设置文件名字
|
||||
now := time.Now()
|
||||
dateTimeString := now.Format("20060102150405") // 当前时间字符串
|
||||
rand.New(rand.NewSource(time.Now().UnixNano())) // 设置随机数
|
||||
ossPath := "/test/医生账户" + dateTimeString + fmt.Sprintf("%d", rand.Intn(9000)+1000) + ".png"
|
||||
|
||||
// 上传oss
|
||||
_, err = aliyun.PutObjectByte(ossPath, []byte(ram))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ossPath = utils.AddOssDomain("/" + ossPath)
|
||||
|
||||
return ossPath, nil
|
||||
}
|
||||
|
||||
@ -47,8 +47,8 @@ dysms:
|
||||
|
||||
# [微信]
|
||||
wechat:
|
||||
app-id: wxa2ab38f49998a990
|
||||
app-secret: 2671d2f4285180ddec5a5a2b16ed50f2
|
||||
app-id: wxc8ac5051745bc795
|
||||
app-secret: 678b63a8a7541e528abc3040c3cea809
|
||||
pay-notify-url: callback/wxpay/inquiry/success
|
||||
refund-notify-url: callback/wxpay/inquiry/refund
|
||||
refund-notify-domain: https://dev.hospital.applets.igandanyiyuan.com/
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package config
|
||||
|
||||
type Wechat struct {
|
||||
AppId string `mapstructure:"patient-app-id" json:"patient-app-id" yaml:"patient-app-id"`
|
||||
AppSecret string `mapstructure:"patient-app-secret" json:"patient-app-secret" yaml:"patient-app-secret"`
|
||||
PayNotifyUrl string `mapstructure:"patient-inquiry-pay-notify-url" json:"patient-inquiry-pay-notify-url" yaml:"patient-inquiry-pay-notify-url"`
|
||||
RefundNotifyUrl string `mapstructure:"patient-inquiry-refund-notify-url" json:"patient-inquiry-refund-notify-url" yaml:"patient-inquiry-refund-notify-url"`
|
||||
AppId string `mapstructure:"app-id" json:"app-id" yaml:"patient-app-id"`
|
||||
AppSecret string `mapstructure:"app-secret" json:"app-secret" yaml:"app-secret"`
|
||||
PayNotifyUrl string `mapstructure:"pay-notify-url" json:"pay-notify-url" yaml:"pay-notify-url"`
|
||||
RefundNotifyUrl string `mapstructure:"refund-notify-url" json:"refund-notify-url" yaml:"refund-notify-url"`
|
||||
Pay1636644248 Pay1636644248 `mapstructure:"pay-1636644248" json:"pay-1636644248" yaml:"pay-1636644248"`
|
||||
}
|
||||
|
||||
|
||||
76
extend/weChat/userInfo.go
Normal file
76
extend/weChat/userInfo.go
Normal file
@ -0,0 +1,76 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GetUserInfoResponse 网页授权拉取用户信息返回值
|
||||
type GetUserInfoResponse struct {
|
||||
OpenId string `json:"openid" form:"openid" label:"openid"`
|
||||
Nickname string `json:"nickname" form:"nickname" label:"用户昵称"`
|
||||
Sex int `json:"sex" form:"sex" label:"性别"` // 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
|
||||
Province string `json:"province" form:"province" label:"省份"`
|
||||
City string `json:"city" form:"city" label:"城市"`
|
||||
Country string `json:"country" form:"country" label:"国家"`
|
||||
HeadImgUrl string `json:"headimgurl" form:"headimgurl" label:"头像"`
|
||||
UnionId string `json:"unionid" form:"unionid" label:"unionid"`
|
||||
Errcode *int `json:"errcode" form:"errcode" label:"errcode"`
|
||||
Errmsg string `json:"errmsg" form:"errmsg" label:"errmsg"`
|
||||
}
|
||||
|
||||
// GetUserInfo 网页授权拉取用户信息
|
||||
func GetUserInfo(accessToken, openId string) (r *GetUserInfoResponse, err error) {
|
||||
if accessToken == "" {
|
||||
return nil, errors.New("授权失败")
|
||||
}
|
||||
|
||||
if openId == "" {
|
||||
return nil, errors.New("授权失败")
|
||||
}
|
||||
|
||||
// 拼接请求数据
|
||||
requestUrl := "https://api.weixin.qq.com/sns/userinfo?" +
|
||||
"access_token=" + accessToken +
|
||||
"&openid=" + openId +
|
||||
"&lang=zh_CN"
|
||||
|
||||
// 发送GET请求
|
||||
resp, err := http.Get(requestUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, errors.New("请求失败")
|
||||
}
|
||||
|
||||
// 读取响应体
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response GetUserInfoResponse
|
||||
err = json.Unmarshal([]byte(respBody), &response)
|
||||
if err != nil {
|
||||
// json解析失败
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if response.Errcode != nil {
|
||||
if response.Errmsg != "" {
|
||||
return nil, errors.New(response.Errmsg)
|
||||
} else {
|
||||
return nil, errors.New("请求失败")
|
||||
}
|
||||
}
|
||||
|
||||
return &response, err
|
||||
}
|
||||
68
extend/weChat/webAccessToken.go
Normal file
68
extend/weChat/webAccessToken.go
Normal file
@ -0,0 +1,68 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"hepa-calc-api/config"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GetWebAccessTokenResponse 获取网页授权access_token返回值
|
||||
type GetWebAccessTokenResponse struct {
|
||||
AccessToken string `json:"access_token" form:"access_token" label:"网页授权接口调用凭证"`
|
||||
ExpiresIn int `json:"expires_in" form:"expires_in" label:"access_token接口调用凭证超时时间"`
|
||||
RefreshToken string `json:"refresh_token" form:"refresh_token" label:"用户刷新access_token"`
|
||||
OpenId string `json:"openid" form:"openid" label:"openid"`
|
||||
Scope string `json:"scope" form:"scope" label:"scope"`
|
||||
UnionId string `json:"unionid" form:"unionid" label:"unionid"`
|
||||
Errcode *int `json:"errcode" form:"errcode" label:"errcode"`
|
||||
Errmsg string `json:"errmsg" form:"errmsg" label:"errmsg"`
|
||||
}
|
||||
|
||||
// GetWebAccessToken 获取网页授权access_token
|
||||
func GetWebAccessToken(code string) (r *GetWebAccessTokenResponse, err error) {
|
||||
// 拼接请求数据
|
||||
requestUrl := "https://api.weixin.qq.com/sns/oauth2/access_token?" +
|
||||
"appid=" + config.C.Wechat.AppId +
|
||||
"&secret=" + config.C.Wechat.AppSecret +
|
||||
"&code=" + code +
|
||||
"&grant_type=authorization_code"
|
||||
|
||||
// 发送GET请求
|
||||
resp, err := http.Get(requestUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, errors.New("请求失败")
|
||||
}
|
||||
|
||||
// 读取响应体
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response GetWebAccessTokenResponse
|
||||
err = json.Unmarshal([]byte(respBody), &response)
|
||||
if err != nil {
|
||||
// json解析失败
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if response.Errcode != nil {
|
||||
if response.Errmsg != "" {
|
||||
return nil, errors.New(response.Errmsg)
|
||||
} else {
|
||||
return nil, errors.New("请求失败")
|
||||
}
|
||||
}
|
||||
|
||||
return &response, err
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user