1
This commit is contained in:
46
controllers/app/sendVerifyCode.go
Normal file
46
controllers/app/sendVerifyCode.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-print/controllers"
|
||||||
|
"git.rosy.net.cn/jx-print/model"
|
||||||
|
"git.rosy.net.cn/jx-print/model/app_model"
|
||||||
|
"git.rosy.net.cn/jx-print/services/print_server/app_server"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Verification struct{}
|
||||||
|
|
||||||
|
var VerificationController = new(Verification)
|
||||||
|
|
||||||
|
// SendVerifyCode 获取短信验证码
|
||||||
|
// @Title 登录接口
|
||||||
|
// @Description 登录接口(微信与公众号登录不能直接调用此接口)
|
||||||
|
// @Param data body app_model.VerificationPhoneCode true "请求参数"
|
||||||
|
// @Success 200 {object} controllers.CallResult
|
||||||
|
// @Failure 200 {object} controllers.CallResult
|
||||||
|
// @router /sendVerifyCode [post]
|
||||||
|
func (a *Verification) SendVerifyCode(c *gin.Context) {
|
||||||
|
// 参数绑定
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
params *app_model.VerificationPhoneCode
|
||||||
|
service = app_server.SendVerifyCodeServer
|
||||||
|
)
|
||||||
|
|
||||||
|
if err = c.ShouldBind(¶ms); err != nil {
|
||||||
|
c.JSON(http.StatusOK, &model.CallBack{
|
||||||
|
Code: model.ErrCodeNormal,
|
||||||
|
Desc: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controllers.CallFunc(c, func() (retVal interface{}, errCode string, err error) {
|
||||||
|
bizId, err := service.SendCode(params.PhoneNumber)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
return map[string]interface{}{"bizId": bizId}, "", nil
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -16,15 +16,15 @@ var Auth2ControllerController = new(Auth2Controller)
|
|||||||
// Login 登录接口
|
// Login 登录接口
|
||||||
// @Title 登录接口
|
// @Title 登录接口
|
||||||
// @Description 登录接口(微信与公众号登录不能直接调用此接口)
|
// @Description 登录接口(微信与公众号登录不能直接调用此接口)
|
||||||
// @Param data body app_model.WeChatPhoneNumberParam true "请求参数"
|
// @Param data body app_model.WxLoginReq true "请求参数"
|
||||||
// @Success 200 {object} controllers.CallResult
|
// @Success 200 {object} controllers.CallResult
|
||||||
// @Failure 200 {object} controllers.CallResult
|
// @Failure 200 {object} controllers.CallResult
|
||||||
// @router /Login [post]
|
// @router /login [post]
|
||||||
func (a *Auth2Controller) Login(c *gin.Context) {
|
func (a *Auth2Controller) Login(c *gin.Context) {
|
||||||
// 参数绑定
|
// 参数绑定
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
params *app_model.WeChatPhoneNumberParam
|
params *app_model.WxLoginReq
|
||||||
service = app_server.UserLogin{}
|
service = app_server.UserLogin{}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,6 +51,44 @@ func (a *Auth2Controller) Login(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Login4Mobile 登录接口验证码登录
|
||||||
|
// @Title 登录接口验证码登录
|
||||||
|
// @Description 登录接口(验证码登录)
|
||||||
|
// @Param data body app_model.MobileLogin true "请求参数"
|
||||||
|
// @Success 200 {object} controllers.CallResult
|
||||||
|
// @Failure 200 {object} controllers.CallResult
|
||||||
|
// @router /loginMobile [post]
|
||||||
|
func (a *Auth2Controller) Login4Mobile(c *gin.Context) {
|
||||||
|
// 参数绑定
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
params *app_model.MobileLogin
|
||||||
|
service = app_server.UserLogin{}
|
||||||
|
)
|
||||||
|
|
||||||
|
if err = c.ShouldBind(¶ms); err != nil {
|
||||||
|
c.JSON(http.StatusOK, &model.CallBack{
|
||||||
|
Code: model.ErrCodeNormal,
|
||||||
|
Desc: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controllers.CallFunc(c, func() (retVal interface{}, errCode string, err error) {
|
||||||
|
user, err := service.MobileLogin(c, params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
// 获取token
|
||||||
|
token, err := controllers.SetToken(user)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return map[string]interface{}{"token": token, "user": user}, "", nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// GetUserPhoneByWeChat 获取用户电话号码
|
// GetUserPhoneByWeChat 获取用户电话号码
|
||||||
// @Title 获取用户电话号码
|
// @Title 获取用户电话号码
|
||||||
// @Description 获取用户电话号码
|
// @Description 获取用户电话号码
|
||||||
@@ -75,12 +113,12 @@ func (a *Auth2Controller) GetUserPhoneByWeChat(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
controllers.CallFunc(c, func() (retVal interface{}, errCode string, err error) {
|
controllers.CallFunc(c, func() (retVal interface{}, errCode string, err error) {
|
||||||
phone, err := service.GetUserPhoneNum(params)
|
phone, isRegister, err := service.GetUserPhoneNum(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return map[string]interface{}{"phone": phone}, "", nil
|
return map[string]interface{}{"phone": phone, "isRegister": isRegister}, "", nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ func (p *Print) AddPrinters(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
controllers.CallFunc(c, func() (retVal interface{}, errCode string, err error) {
|
controllers.CallFunc(c, func() (retVal interface{}, errCode string, err error) {
|
||||||
|
// 校验打印机绑定用户
|
||||||
|
if err := printServer.QueryPrintKeyIsExit(printInfo[0], param.Phone, param.BizId, param.Code, param.AppID); err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
// 添加打印机
|
// 添加打印机
|
||||||
if err := printServer.AddPrinters(tokenInfo, param.AppID, printInfo); err != nil {
|
if err := printServer.AddPrinters(tokenInfo, param.AppID, printInfo); err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
|
|||||||
@@ -154,6 +154,6 @@ func createToken(user *model.User) (token string) {
|
|||||||
user.UserID,
|
user.UserID,
|
||||||
time.Now().Format("20060102-150405"),
|
time.Now().Format("20060102-150405"),
|
||||||
utils.GetUUID(),
|
utils.GetUUID(),
|
||||||
user.Name,
|
user.Mobile,
|
||||||
}, wxConst.TokenTypeSep)
|
}, wxConst.TokenTypeSep)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,12 +96,12 @@ func GetMenuDetail(db *sqlx.DB, id int) (menu *model.MenuDetail, err error) {
|
|||||||
// CreateUserWx 创建微信用户
|
// CreateUserWx 创建微信用户
|
||||||
func CreateUserWx(user *model.User) error {
|
func CreateUserWx(user *model.User) error {
|
||||||
db := globals.GetDB()
|
db := globals.GetDB()
|
||||||
return Insert(db, &user)
|
return Insert(db, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUserWx 更新微信用户
|
// UpdateUserWx 更新微信用户
|
||||||
func UpdateUserWx(user *model.User, filed []string) error {
|
func UpdateUserWx(user *model.User, filed []string) error {
|
||||||
db := globals.GetDB()
|
db := globals.GetDB()
|
||||||
// 用户存在,判断用户
|
// 用户存在,判断用户
|
||||||
return Update(db, &user, filed...)
|
return Update(db, user, filed...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ var (
|
|||||||
SugarLogger *zap.SugaredLogger
|
SugarLogger *zap.SugaredLogger
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
err error
|
err error
|
||||||
|
AliKey = "LTAI4FwZN7pp4dACQHoapkZQ"
|
||||||
|
AliSecret = "NTegceUFX0FdfMovqCDzqcIKmhcoOu"
|
||||||
|
SmsSignName = "京西菜市"
|
||||||
|
SmsMobileVerifyTemplate = "SMS_175583158"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|||||||
1
main.go
1
main.go
@@ -21,7 +21,6 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
gin.DisableConsoleColor()
|
gin.DisableConsoleColor()
|
||||||
globals.SugarLogger.Debug("print--------------main")
|
|
||||||
r := gin.New()
|
r := gin.New()
|
||||||
//r.Use(session(model.SessionKey))
|
//r.Use(session(model.SessionKey))
|
||||||
f, _ := os.Create("jx-print.log")
|
f, _ := os.Create("jx-print.log")
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ package app_model
|
|||||||
type AddPrintReq struct {
|
type AddPrintReq struct {
|
||||||
AppID int `json:"app_id" form:"app_id" binding:"required"`
|
AppID int `json:"app_id" form:"app_id" binding:"required"`
|
||||||
Prints string `json:"prints" form:"prints" binding:"required"`
|
Prints string `json:"prints" form:"prints" binding:"required"`
|
||||||
|
|
||||||
|
Phone string `json:"phone" form:"phone" binding:"required"`
|
||||||
|
Code string `json:"code" form:"code" binding:"required"`
|
||||||
|
BizId string `json:"biz_id" form:"biz_id" binding:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueryPrintReq struct {
|
type QueryPrintReq struct {
|
||||||
|
|||||||
@@ -21,28 +21,33 @@ const (
|
|||||||
|
|
||||||
// WeChatPhoneNumberParam 微信登陆
|
// WeChatPhoneNumberParam 微信登陆
|
||||||
type WeChatPhoneNumberParam struct {
|
type WeChatPhoneNumberParam struct {
|
||||||
EncryptedData string `json:"encrypted_data" form:"encrypted_data" binding:"required"` // 加密信息
|
|
||||||
IV string `json:"iv" form:"iv" binding:"required"` // 加密算法初始量
|
|
||||||
NickName string `json:"nick_name" form:"nick_name" binding:"required"` // 昵称
|
|
||||||
HeadUrl string `json:"head_url" form:"head_url" binding:"required"` //头像图片地址
|
|
||||||
Code string `json:"code" form:"code" binding:"required"` //code
|
Code string `json:"code" form:"code" binding:"required"` //code
|
||||||
}
|
}
|
||||||
|
|
||||||
type WxLoginReq struct {
|
type WxLoginReq struct {
|
||||||
Code string `json:"code" form:"code"` // 微信授权登录使用
|
EncryptedData string `json:"encrypted_data" form:"encrypted_data" binding:"required"` // 加密信息
|
||||||
Phone string `json:"phone" form:"phone"` // 微信和电话登录使用
|
IV string `json:"iv" form:"iv" binding:"required"` // 加密算法初始量
|
||||||
Password string `json:"password" form:"password"` // 密码登录
|
NickName string `json:"nick_name" form:"nick_name"` // 昵称
|
||||||
|
HeadUrl string `json:"head_url" form:"head_url"` //头像图片地址
|
||||||
|
Code string `json:"code" form:"code" binding:"required"` // code
|
||||||
|
Phone string `json:"phone" form:"phone" binding:"required"` // 电话
|
||||||
}
|
}
|
||||||
|
|
||||||
// 微信小程序解密后 用户手机号结构体
|
type MobileLogin struct {
|
||||||
type UserPhone struct {
|
Phone string `json:"phone" form:"phone" binding:"required"` // 电话
|
||||||
PhoneNumber string `json:"phoneNumber,omitempty"`
|
BizId string `json:"biz_id" form:"biz_id" binding:"required"` // 短信id
|
||||||
PurePhoneNumber string `json:"purePhoneNumber,omitempty"`
|
Code string `json:"code" form:"code" binding:"required"` // code
|
||||||
CountryCode string `json:"countryCode,omitempty"`
|
|
||||||
Watermark *watermarkInfo `json:"watermark,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type watermarkInfo struct {
|
//// 微信小程序解密后 用户手机号结构体
|
||||||
Appid string `json:"appid,omitempty"`
|
//type UserPhone struct {
|
||||||
Timestamp int `json:"timestamp,omitempty"`
|
// PhoneNumber string `json:"phoneNumber,omitempty"`
|
||||||
}
|
// PurePhoneNumber string `json:"purePhoneNumber,omitempty"`
|
||||||
|
// CountryCode string `json:"countryCode,omitempty"`
|
||||||
|
// Watermark *watermarkInfo `json:"watermark,omitempty"`
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//type watermarkInfo struct {
|
||||||
|
// Appid string `json:"appid,omitempty"`
|
||||||
|
// Timestamp int `json:"timestamp,omitempty"`
|
||||||
|
//}
|
||||||
|
|||||||
5
model/app_model/verification_code.go
Normal file
5
model/app_model/verification_code.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package app_model
|
||||||
|
|
||||||
|
type VerificationPhoneCode struct {
|
||||||
|
PhoneNumber string `json:"phone_number" form:"phone_number" binding:"required"`
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ const (
|
|||||||
OrderTypeCardValid = "cardValid" //卡有效期
|
OrderTypeCardValid = "cardValid" //卡有效期
|
||||||
|
|
||||||
OrderOriginWxMini = "weixinmini"
|
OrderOriginWxMini = "weixinmini"
|
||||||
|
OrderOriginMobile = "mobile"
|
||||||
OrderOriginOpenAPI = "openAPI"
|
OrderOriginOpenAPI = "openAPI"
|
||||||
|
|
||||||
OrderStatusWaitPay = 0 //待支付
|
OrderStatusWaitPay = 0 //待支付
|
||||||
@@ -179,7 +180,7 @@ type Printer struct {
|
|||||||
DeletedAt *time.Time `json:"deleted_at" db:"deleted_at"`
|
DeletedAt *time.Time `json:"deleted_at" db:"deleted_at"`
|
||||||
AppID int `json:"app_id" db:"app_id"` //应用编号
|
AppID int `json:"app_id" db:"app_id"` //应用编号
|
||||||
PrintNo string `json:"print_no" db:"print_no"` //打印机编号
|
PrintNo string `json:"print_no" db:"print_no"` //打印机编号
|
||||||
PrintKey string `json:"print_key" db:"print_key"` //打印机识别码
|
PrintKey string `json:"print_key" db:"print_key"` //打印机识别码(目前是用户电话号码)
|
||||||
Name string `json:"name" db:"name"` //打印机备注名
|
Name string `json:"name" db:"name"` //打印机备注名
|
||||||
Status int `json:"status" db:"status"` //打印机状态
|
Status int `json:"status" db:"status"` //打印机状态
|
||||||
IsOnline int `json:"is_online" db:"is_online"` //1在线,0离线
|
IsOnline int `json:"is_online" db:"is_online"` //1在线,0离线
|
||||||
|
|||||||
@@ -6,9 +6,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// InitV3App 小程序端,不需要token
|
// InitV3App 小程序端,不需要token
|
||||||
func InitV3App(v2 *gin.RouterGroup) {
|
func InitV3App(v1 *gin.RouterGroup) {
|
||||||
appNo := v2.Group("/app_no")
|
appNo := v1.Group("/app_no")
|
||||||
|
|
||||||
appNo.POST("/getUserPhone", app.Auth2ControllerController.GetUserPhoneByWeChat) // 获取微信用户电话
|
appNo.POST("/getUserPhone", app.Auth2ControllerController.GetUserPhoneByWeChat) // 获取微信用户电话
|
||||||
appNo.POST("/login", app.Auth2ControllerController.Login) // 微信登录
|
appNo.POST("/login", app.Auth2ControllerController.Login) // 微信登录
|
||||||
|
appNo.POST("/loginMobile", app.Auth2ControllerController.Login4Mobile) // 短信登录
|
||||||
|
|
||||||
|
// 获取短信
|
||||||
|
appNo.POST("/sendVerifyCode", app.VerificationController.SendVerifyCode) // 获取短信验证码
|
||||||
}
|
}
|
||||||
|
|||||||
61
services/print_server/app_server/verify_code.go
Normal file
61
services/print_server/app_server/verify_code.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package app_server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-print/globals"
|
||||||
|
"git.rosy.net.cn/jx-print/putils"
|
||||||
|
"git.rosy.net.cn/jx-print/services/api"
|
||||||
|
aliyunsmsclient "github.com/KenmyZhang/aliyun-communicate"
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SendVerifyCode struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
var SendVerifyCodeServer = new(SendVerifyCode)
|
||||||
|
|
||||||
|
// SendCode 获取手机短信验证码
|
||||||
|
func (s *SendVerifyCode) SendCode(mobile string) (string, error) {
|
||||||
|
// 获取code
|
||||||
|
smsCode := ""
|
||||||
|
code := putils.GetKey(mobile)
|
||||||
|
if code != "" {
|
||||||
|
smsCode = code.(string)
|
||||||
|
} else {
|
||||||
|
smsCode = fmt.Sprintf("%06d", rand.Intn(1000000))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送短信
|
||||||
|
response, err := api.SMSClient.Execute(globals.AliKey, globals.AliSecret, mobile, globals.SmsSignName, globals.SmsMobileVerifyTemplate, string(utils.MustMarshal(map[string]interface{}{
|
||||||
|
"code": smsCode,
|
||||||
|
})))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if response.Code != aliyunsmsclient.ResponseCodeOk {
|
||||||
|
return "", fmt.Errorf("发送短信出错:%s", response.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := putils.SetKey(response.BizId+"_"+mobile, smsCode, 5*60); err != nil {
|
||||||
|
globals.SugarLogger.Debugf("redis set key err key[%s] value[%s]:", mobile, smsCode)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.BizId, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifySecret 检查验证码
|
||||||
|
func (s *SendVerifyCode) VerifySecret(mobile, bizId, code string) (bool, error) {
|
||||||
|
result := putils.GetKey(bizId + "_" + mobile)
|
||||||
|
if result != "" {
|
||||||
|
return false, errors.New("验证码过期")
|
||||||
|
}
|
||||||
|
if result.(string) != code {
|
||||||
|
return false, errors.New("验证码错误,重新确认")
|
||||||
|
}
|
||||||
|
putils.DelKey(bizId + "_" + mobile)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
package app_server
|
package app_server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -17,7 +14,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -27,14 +23,14 @@ type UserLogin struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WxLogin 授权登录
|
// WxLogin 授权登录
|
||||||
func (u *UserLogin) WxLogin(ctx *gin.Context, param *wxLogin.WeChatPhoneNumberParam) (*model.User, error) {
|
func (u *UserLogin) WxLogin(ctx *gin.Context, param *wxLogin.WxLoginReq) (*model.User, error) {
|
||||||
openObj, err := api.WeixinMiniAPI.SNSCode2Session(param.Code)
|
openObj, err := api.WeixinMiniAPI.SNSCode2Session(param.Code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查用户是否存在
|
// 检查用户是否存在
|
||||||
users, err := dao.GetUsers(globals.GetDB(), "", "", "", openObj.OpenID)
|
users, err := dao.GetUsers(globals.GetDB(), "", "", param.Phone, openObj.OpenID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -42,11 +38,6 @@ func (u *UserLogin) WxLogin(ctx *gin.Context, param *wxLogin.WeChatPhoneNumberPa
|
|||||||
return nil, errors.New("数据异常,用户电话不唯一,联系管理员")
|
return nil, errors.New("数据异常,用户电话不唯一,联系管理员")
|
||||||
}
|
}
|
||||||
|
|
||||||
weChatLogin := new(wxLogin.UserPhone)
|
|
||||||
if err := DecryptOpenDataToStruct(param.EncryptedData, param.IV, openObj.SessionKey, weChatLogin); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var userObj *model.User
|
var userObj *model.User
|
||||||
timeNow := time.Now()
|
timeNow := time.Now()
|
||||||
switch len(users) {
|
switch len(users) {
|
||||||
@@ -60,7 +51,7 @@ func (u *UserLogin) WxLogin(ctx *gin.Context, param *wxLogin.WeChatPhoneNumberPa
|
|||||||
UserID: utils.GetUUID(),
|
UserID: utils.GetUUID(),
|
||||||
Password: "",
|
Password: "",
|
||||||
Name: param.NickName,
|
Name: param.NickName,
|
||||||
Mobile: weChatLogin.PhoneNumber,
|
Mobile: param.Phone,
|
||||||
Email: "",
|
Email: "",
|
||||||
Avatar: param.HeadUrl,
|
Avatar: param.HeadUrl,
|
||||||
Status: 1,
|
Status: 1,
|
||||||
@@ -88,7 +79,6 @@ func (u *UserLogin) WxLogin(ctx *gin.Context, param *wxLogin.WeChatPhoneNumberPa
|
|||||||
users[0].Avatar = param.HeadUrl
|
users[0].Avatar = param.HeadUrl
|
||||||
users[0].OpenId = openObj.OpenID
|
users[0].OpenId = openObj.OpenID
|
||||||
users[0].UnionId = openObj.UnionID
|
users[0].UnionId = openObj.UnionID
|
||||||
}
|
|
||||||
// 用户存在,判断用户
|
// 用户存在,判断用户
|
||||||
users[0].UpdatedAt = &timeNow
|
users[0].UpdatedAt = &timeNow
|
||||||
users[0].LastOperator = users[0].Name
|
users[0].LastOperator = users[0].Name
|
||||||
@@ -96,71 +86,99 @@ func (u *UserLogin) WxLogin(ctx *gin.Context, param *wxLogin.WeChatPhoneNumberPa
|
|||||||
if err := dao.UpdateUserWx(users[0], []string{"updated_at", "last_operator", "last_login_ip", "name", "avatar", "open_id", "union_id"}); err != nil {
|
if err := dao.UpdateUserWx(users[0], []string{"updated_at", "last_operator", "last_login_ip", "name", "avatar", "open_id", "union_id"}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 用户存在,判断用户
|
||||||
|
users[0].UpdatedAt = &timeNow
|
||||||
|
users[0].LastOperator = users[0].Name
|
||||||
|
users[0].LastLoginIP = ctx.ClientIP()
|
||||||
|
if err := dao.UpdateUserWx(users[0], []string{"updated_at", "last_operator", "last_login_ip"}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
userObj = users[0]
|
userObj = users[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
return userObj, err
|
return userObj, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptOpenDataToStruct 解密开放数据到结构体
|
// MobileLogin 短信验证登录
|
||||||
// encryptedData:包括敏感数据在内的完整用户信息的加密数据,小程序获取到
|
func (u *UserLogin) MobileLogin(ctx *gin.Context, param *wxLogin.MobileLogin) (*model.User, error) {
|
||||||
// iv:加密算法的初始向量,小程序获取到
|
// 校验用户信息
|
||||||
// sessionKey:会话密钥,通过 gopay.Code2Session() 方法获取到
|
isHave, err := SendVerifyCodeServer.VerifySecret(param.Phone, param.BizId, param.Code)
|
||||||
// beanPtr:需要解析到的结构体指针,操作完后,声明的结构体会被赋值
|
if err != nil {
|
||||||
// 文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
|
return nil, err
|
||||||
func DecryptOpenDataToStruct(encryptedData, iv, sessionKey string, beanPtr interface{}) (err error) {
|
|
||||||
if encryptedData == "" || iv == "" || sessionKey == "" {
|
|
||||||
return errors.New("input params can not null")
|
|
||||||
}
|
}
|
||||||
var (
|
if !isHave {
|
||||||
cipherText, aesKey, ivKey, plainText []byte
|
return nil, errors.New("验证码错误")
|
||||||
block cipher.Block
|
|
||||||
blockMode cipher.BlockMode
|
|
||||||
)
|
|
||||||
beanValue := reflect.ValueOf(beanPtr)
|
|
||||||
if beanValue.Kind() != reflect.Ptr {
|
|
||||||
return errors.New("传入beanPtr类型必须是以指针形式")
|
|
||||||
}
|
}
|
||||||
if beanValue.Elem().Kind() != reflect.Struct {
|
// 检查用户是否存在
|
||||||
return errors.New("传入interface{}必须是结构体")
|
users, err := dao.GetUsers(globals.GetDB(), "", "", param.Phone, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
cipherText, _ = base64.StdEncoding.DecodeString(encryptedData)
|
|
||||||
aesKey, _ = base64.StdEncoding.DecodeString(sessionKey)
|
|
||||||
ivKey, _ = base64.StdEncoding.DecodeString(iv)
|
|
||||||
if len(cipherText)%len(aesKey) != 0 {
|
|
||||||
return errors.New("encryptedData is error")
|
|
||||||
}
|
|
||||||
if block, err = aes.NewCipher(aesKey); err != nil {
|
|
||||||
return fmt.Errorf("aes.NewCipher:%w", err)
|
|
||||||
}
|
|
||||||
blockMode = cipher.NewCBCDecrypter(block, ivKey)
|
|
||||||
plainText = make([]byte, len(cipherText))
|
|
||||||
blockMode.CryptBlocks(plainText, cipherText)
|
|
||||||
if len(plainText) > 0 {
|
|
||||||
plainText = PKCS7UnPadding(plainText)
|
|
||||||
}
|
|
||||||
if err = json.Unmarshal(plainText, beanPtr); err != nil {
|
|
||||||
return fmt.Errorf("json.Marshal(%s):%w", string(plainText), err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// PKCS7UnPadding 解密填充模式(去除补全码) PKCS7UnPadding
|
var userObj *model.User
|
||||||
// 解密时,需要在最后面去掉加密时添加的填充byte
|
timeNow := time.Now()
|
||||||
func PKCS7UnPadding(origData []byte) (bs []byte) {
|
switch len(users) {
|
||||||
length := len(origData)
|
case 1: // 用户存在
|
||||||
unPaddingNumber := int(origData[length-1]) // 找到Byte数组最后的填充byte 数字
|
userObj = users[0]
|
||||||
if unPaddingNumber <= 16 {
|
case 0: // 用户不存在
|
||||||
bs = origData[:(length - unPaddingNumber)] // 只截取返回有效数字内的byte数组
|
// 用户不存在,创建并返回用户
|
||||||
} else {
|
userBase := &model.User{
|
||||||
bs = origData
|
CreatedAt: &timeNow,
|
||||||
|
UpdatedAt: &timeNow,
|
||||||
|
LastOperator: "系统新增",
|
||||||
|
DeletedAt: &utils.DefaultTimeValue,
|
||||||
|
UserID: utils.GetUUID(),
|
||||||
|
Password: "",
|
||||||
|
Name: "手机用户_" + param.Phone,
|
||||||
|
Mobile: param.Phone,
|
||||||
|
Email: "",
|
||||||
|
Avatar: "",
|
||||||
|
Status: 1,
|
||||||
|
Type: 1,
|
||||||
|
Company: "",
|
||||||
|
CityCode: 0,
|
||||||
|
DistrictCode: 0,
|
||||||
|
Address: "",
|
||||||
|
IDCardNo: "",
|
||||||
|
Remark: "",
|
||||||
|
LastLoginAt: &timeNow,
|
||||||
|
LastLoginIP: ctx.ClientIP(),
|
||||||
|
LastLoginType: model.OrderOriginMobile,
|
||||||
|
OpenId: "",
|
||||||
|
UnionId: "",
|
||||||
}
|
}
|
||||||
return
|
if err := dao.CreateUserWx(userBase); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
userObj = userBase
|
||||||
|
}
|
||||||
|
return userObj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserPhoneNum 解密用户手机号
|
// GetUserPhoneNum 解密用户手机号
|
||||||
func (u *UserLogin) GetUserPhoneNum(param *wxLogin.WeChatPhoneNumberParam) (string, error) {
|
func (u *UserLogin) GetUserPhoneNum(param *wxLogin.WeChatPhoneNumberParam) (string, bool, error) {
|
||||||
return api.WeixinMiniAPI.SNSGetUserPhone(param.Code)
|
phone, err := api.WeixinMiniAPI.SNSGetUserPhone(param.Code)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
// 检查用户是否存在
|
||||||
|
users, err := dao.GetUsers(globals.GetDB(), "", "", phone, "")
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
if len(users) != 1 {
|
||||||
|
return phone, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
isRegion := false
|
||||||
|
if users[0].OpenId != "" {
|
||||||
|
isRegion = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return phone, isRegion, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Jxc4UserToken 全局变量,缓存菜市管理系统token
|
// Jxc4UserToken 全局变量,缓存菜市管理系统token
|
||||||
|
|||||||
@@ -10,6 +10,35 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// QueryPrintKeyIsExit 查询用户打印机以及绑定信息
|
||||||
|
func QueryPrintKeyIsExit(printInfo *model.PrintInfo, phone, bizId, code string, appId int) error {
|
||||||
|
var (
|
||||||
|
db = globals.GetDB()
|
||||||
|
)
|
||||||
|
// 电话号码校验
|
||||||
|
have, err := SendVerifyCodeServer.VerifySecret(phone, bizId, code)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !have {
|
||||||
|
return fmt.Errorf("验证码错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
if printInfo.PrintNo == "" {
|
||||||
|
return fmt.Errorf("请输入正确的打印机编号!print_no :%s 。", printInfo.PrintNo)
|
||||||
|
}
|
||||||
|
|
||||||
|
printers, _ := dao.GetPrinters(db, appId, printInfo.PrintNo, 0, 0, 0)
|
||||||
|
// 打印机已经被绑定
|
||||||
|
if len(printers) != 0 {
|
||||||
|
// 修改绑定
|
||||||
|
if printers[0].PrintKey != "" && printers[0].PrintKey != phone {
|
||||||
|
return fmt.Errorf("打印机已经被其他用户绑定,修改绑定请联系商家")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func AddPrinters(tokenInfo *model.TokenInfo, appID int, printInfo []*model.PrintInfo) (err error) {
|
func AddPrinters(tokenInfo *model.TokenInfo, appID int, printInfo []*model.PrintInfo) (err error) {
|
||||||
var (
|
var (
|
||||||
db = globals.GetDB()
|
db = globals.GetDB()
|
||||||
|
|||||||
Reference in New Issue
Block a user