|
- package svc
-
- import (
- "applet/app/db"
- "applet/app/db/model"
- "applet/app/e"
- "applet/app/lib/mob"
- "applet/app/lib/sms"
- "applet/app/lib/zhimeng"
- "applet/app/md"
- "applet/app/svc"
- "applet/app/utils"
- "applet/app/utils/cache"
- "applet/app/utils/logx"
- sms2 "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/sms"
- "encoding/json"
- "errors"
- "fmt"
- "github.com/gin-gonic/gin"
- "github.com/syyongx/php2go"
- "github.com/tidwall/gjson"
- "math/rand"
- "time"
- "xorm.io/xorm"
- )
-
- func Login(c *gin.Context) {
- r := new(md.LoginResponse)
- requestBody := new(md.FastLoginRequestBody)
- if err := c.ShouldBindJSON(&requestBody); err != nil {
- e.OutErr(c, e.ERR_INVALID_ARGS, err)
- return
- }
- user, _ := db.UserFindByMobileAll(svc.MasterDb(c), requestBody.Mobile)
- if user == nil {
- e.OutErr(c, 400, e.NewErr(400, "账号不存在"))
- return
- }
- if user.Password != utils.Md5(requestBody.Password) {
- e.OutErr(c, 400, e.NewErr(400, "密码不正确"))
- return
- }
- if err := svc.FastLoginUserExist(c, r, requestBody); err != nil {
- if e.ErrorIsAccountBan(err) {
- e.OutErr(c, e.ERR_USER_IS_BAN, err)
- return
- }
- e.OutErr(c, 400, err)
- return
- }
- e.OutSuc(c, r, nil)
- return
- }
- func LoginFastIn(c *gin.Context) {
- var req map[string]string
- if err := c.ShouldBindJSON(&req); err != nil {
- e.OutErr(c, e.ERR_INVALID_ARGS, err)
- return
- }
- if req["phone"] == "" {
- e.OutErr(c, 400, e.NewErr(400, "手机号不能为空"))
- return
- }
- if req["captcha"] == "" {
- e.OutErr(c, 400, e.NewErr(400, "验证码不能为空"))
- return
- }
- mob1, errr := mob.GetMobSDK(c.GetString("mid"))
- if errr != nil {
- e.OutErr(c, e.ERR_MOB_CONFIG, errr)
- return
- }
- if req["zone"] == "" {
- req["zone"] = "86"
- }
- send := map[string]interface{}{
- "phone": req["phone"],
- "zone": req["zone"],
- "code": req["captcha"],
- }
-
- var ok bool
- var err error
- // h5(wap) 登录
- smsPlatform := sms.GetSmsPlatform(c)
- key := fmt.Sprintf("%s_SMS_FastLogin_%s", db.SysCfgGet(c, "app_name"), req["phone"])
- if smsPlatform == "ljioe" {
- b, err := cache.GetBytes(key)
- if err != nil {
- e.OutErr(c, e.ERR_MOB_SMS_NO_EXISTS, err)
- return
- }
- if req["captcha"] != gjson.GetBytes(b, "data.captcha").String() {
- e.OutErr(c, e.ERR_MOB_SMS_NO_SAME, err)
- return
- }
- ok = true
- } else {
- c.Set("not_deduction_doing", "1")
- ok, err = mob1.MobSMS(c, send)
- if err != nil {
- e.OutErr(c, 400, err.Error())
- return
- }
- }
-
- r := new(md.LoginResponse)
- requestBody := &md.FastLoginRequestBody{
- Mobile: req["phone"],
- }
- if ok {
- // 短信验证通过
- user, isExist, err := db.UserGetByMobileIgnoreDelete(db.DBs[c.GetString("mid")], req["phone"], req["zone"])
- if err != nil {
- e.OutErr(c, e.ERR, err)
- return
- }
- //用户已注册过,获取用户信息并返回
- if isExist {
- if user.DeleteAt != 0 {
- e.OutErr(c, e.ERR_USER_IS_BAN)
- return
- }
- if err := svc.FastLoginUserExist(c, r, requestBody); err != nil {
- if e.ErrorIsAccountBan(err) {
- e.OutErr(c, e.ERR_USER_IS_BAN, err)
- return
- }
- e.OutErr(c, 400, err)
- return
- }
- e.OutSuc(c, r, nil)
- return
- }
-
- if err := FastLoginUserNoExist(c, r, requestBody); err != nil {
- // 创建失败时清空用户
- if r.UserID != "" {
- UserDeleteOne(c, r.UserID)
- }
- e.OutErr(c, e.ERR, err)
- return
- }
- cache.Del(key)
- // 返回登陆响应
- e.OutSuc(c, r, nil)
- return
- }
- // 验证码无效或者过期,验证码错误
- e.OutErr(c, e.ERR_SMS_AUTH, err)
- return
- }
- func FastLoginUserNoExist(c *gin.Context, r *md.LoginResponse, requestBody *md.FastLoginRequestBody) error {
- user := new(model.User)
- user.Username = requestBody.Mobile
- user.Password = utils.Md5(requestBody.Mobile)
- if requestBody.Password != "" {
- user.Password = utils.Md5(requestBody.Password)
- }
- user.Platform = c.GetHeader("platform")
- user.Phone = requestBody.Mobile
- appNameCn := db.SysCfgGet(c, "app_name_cn")
- user.Nickname = appNameCn + requestBody.Mobile[len(requestBody.Mobile)-4:len(requestBody.Mobile)]
- user.Zone = "86"
- lvs, err := db.UserLevlAll(c, db.DBs[c.GetString("mid")])
- if err != nil || len(lvs) == 0 {
- return errors.New("会员等级不存在")
- }
-
- user.Level = lvs[0].Id
- user.State = 1
- user.CreateAt = time.Now()
- user.UpdateAt = time.Now()
- // ---- 插入用户-----!
- exist, err := userCheck(c, user, db.UserInsert)
- if err != nil {
- return err
- }
- if exist {
- return errors.New("Register user is exist")
- }
- r.UserID = utils.IntToStr(user.Uid)
- // 生成jwt
- appName := db.SysCfgGet(c, "app_name")
- token, err := utils.GenToken(user.Uid, user.Username, user.Phone, appName, "", "")
- if err != nil {
- return logx.Warn(err)
- }
- // Insert user profile
- userProfile := new(model.UserProfile)
- userProfile.ArkidToken = token
- userProfile.Uid = user.Uid
- if userProfile.AvatarUrl == "" {
- userProfile.AvatarUrl = db.SysCfgGet(c, "app_user_default_avatar")
- }
- userProfile.IsNew = 1
- exist, err = userProfileCheck(c, userProfile, db.UserProfileInsert)
- if err != nil {
- return err
- }
- if exist {
- return errors.New("user Profile is exist")
- }
- //debug
- //生成邀请码 防止卡死
- GetInviteCode(c, user, userProfile)
- // 异步处理 有效会员和新会员
- // 写入缓存
- key := fmt.Sprintf("%s:token:%s", c.GetString("mid"), user.Username)
- _, err = cache.SetEx(key, token, 39528000) // 半年
- if err != nil {
- return logx.Warn(err)
- }
- r.Token = token
- r.UserID = utils.IntToStr(user.Uid)
- return nil
- }
- func GetInviteCode(c *gin.Context, user *model.User, userProfile *model.UserProfile) {
- if userProfile.InviteCode != "" {
- return
- }
- cc := c.Copy() // 传递上下文给 goroutine 的话 一定要使用副本,这样才能保证上下文的输出安全
- //生成邀请码的线程 直接访问怕慢
- go UserInviteCode(cc, &md.User{
- Info: user,
- Profile: userProfile,
- })
-
- return
- }
-
- func userCheck(c *gin.Context, user *model.User, f func(*xorm.Engine, *model.User) (int64, error)) (bool, error) {
- fmt.Println("user in userCheck is ", utils.SerializeStr(user))
- isExist, err := db.UserIsExistByMobile(db.DBs[c.GetString("mid")], user.Username)
- if isExist {
- return isExist, nil
- }
- _, err = f(db.DBs[c.GetString("mid")], user)
-
- return false, err
- }
-
- func userProfileCheck(c *gin.Context, userProfile *model.UserProfile, f func(*xorm.Engine, *model.UserProfile) (int64, error)) (bool, error) {
- isExist, err := db.UserProfileIsExistByUserID(db.DBs[c.GetString("mid")], userProfile.Uid)
- if isExist {
- return isExist, nil
- }
- _, err = f(db.DBs[c.GetString("mid")], userProfile)
-
- return false, err
- }
- func UserDeleteOne(c *gin.Context, id interface{}) (int64, error) {
-
- _, err := db.UserDelete(db.DBs[c.GetString("mid")], id)
- if err != nil {
- return 0, err
- }
- // 删除用户
- _, err = db.UserProfileDelete(db.DBs[c.GetString("mid")], id)
- if err != nil {
- return 0, err
- }
- // 删除用户关系
- _, err = db.UserRelateDelete(db.DBs[c.GetString("mid")], id)
- if err != nil {
- return 0, err
- }
- // 将他的下级pid清零
- us, err := db.UserProfileByPuid(db.DBs[c.GetString("mid")], id)
- if err != nil {
- return 0, err
- }
- for _, item := range *us {
- item.ParentUid = 0
- _, err = db.UserProfileUpdate(db.DBs[c.GetString("mid")], item.Uid, &item, "parent_uid")
- if err != nil {
- continue
- }
- }
-
- return 1, nil
- }
-
- func LoginSendSms(c *gin.Context) {
- var req map[string]string
- if err := c.ShouldBindJSON(&req); err != nil {
- e.OutErr(c, e.ERR_INVALID_ARGS, err)
- return
- }
- if req["phone"] == "" {
- e.OutErr(c, 400, e.NewErr(400, "手机号不能为空"))
- return
- }
- isExist, err := db.UserisExistByMobile(db.DBs[c.GetString("mid")], req["phone"])
- if err != nil {
- e.OutErr(c, e.ERR, err)
- return
- }
- userdata, _ := db.UserFindByPhoneOrNickname(db.DBs[c.GetString("mid")], req["phone"])
- if userdata != nil && userdata.State == 2 {
- e.OutErr(c, 400, e.NewErr(400, "账号已冻结"))
- return
- }
- types := ""
- if !isExist {
- types = "register"
- } else if isExist {
- types = "login"
- }
- smsType := svc.SysCfgGet(c, "sms_type")
- c.Set("sms_type", smsType)
- if c.GetString("sms_type") == "1" {
- count := sms2.SmsNumGetSmsNum(db.Db, "putong", c.GetString("mid"))
- if count-1 < 0 {
- e.OutErr(c, e.ERR_MOB_SMS_NO_AVA, err)
- return
- }
- } else {
- count, _ := zhimeng.SmsNum(db.Db, c.GetString("mid"), c.GetString("sms_type"), db.SysCfgGet(c, "third_zm_sms_key"), db.SysCfgGet(c, "third_zm_sms_secret"))
- if count-1 < 0 {
- e.OutErr(c, e.ERR_MOB_SMS_NO_AVA, err)
- return
- }
- }
- appName := db.SysCfgGet(c, "sms_push_sign")
- captcha := createCaptcha()
- content := fmt.Sprintf("【%s】验证码:%s", appName, captcha)
- key := fmt.Sprintf("%s_SMS_%s", db.SysCfgGet(c, "app_name"), req["phone"])
- templateCode := ""
- switch types {
- case "login":
- content = fmt.Sprintf("【%s】快捷登录验证码:%s", appName, captcha)
- key = fmt.Sprintf("%s_SMS_FastLogin_%s", db.SysCfgGet(c, "app_name"), req["phone"])
- templateCode = "login"
- case "register":
- content = fmt.Sprintf("【%s】注册验证码:%s", appName, captcha)
- key = fmt.Sprintf("%s_SMS_FastLogin_%s", db.SysCfgGet(c, "app_name"), req["phone"])
- templateCode = "register"
- }
- marshal, _ := json.Marshal(c.Request.Header)
- waykeys := "app_" + c.ClientIP() + "_" + utils.IntToStr(utils.GetApiVersion(c)) + "_" + c.Request.RequestURI + "_" + string(marshal)
- postData := map[string]interface{}{
- "content": content,
- "mobile": req["phone"],
- "templateCode": templateCode,
- "way": php2go.Base64Encode(waykeys),
- }
- requestBody := new(md.Register)
- requestBody.Mobile = req["phone"]
- requestBody.Captcha = captcha
- if requestBody.Zone == "" {
- requestBody.Zone = "86"
- }
- err = sms.GetSmsConfig(c, requestBody.Zone, postData)
- if err != nil {
- e.OutErr(c, 400, err)
- return
- }
- tmp := struct {
- Data md.Register `json:"data"`
- CacheTime int64 `json:"cache_time"`
- }{
- Data: *requestBody,
- CacheTime: time.Now().Unix(),
- }
- if _, err := cache.SetEx(key, utils.Serialize(tmp), 180); err != nil {
- e.OutErr(c, e.ERR, err)
- return
- }
- //存入一个缓存 用于邀请码注册时候判断
- keys := fmt.Sprintf("%s_SMSCHECK_%s", c.GetString("mid"), requestBody.Mobile)
- tmps := struct {
- Check int `json:"check"`
- CacheTime int64 `json:"cache_time"`
- }{
- Check: 1,
- CacheTime: time.Now().Unix(),
- }
- if _, err := cache.SetEx(keys, utils.Serialize(tmps), 3600); err != nil {
- e.OutErr(c, e.ERR, err)
- return
- }
- e.OutSuc(c, "验证码已发送,3分钟内有效", nil)
- return
- }
- func createCaptcha() string {
- return fmt.Sprintf("%05v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(1000000))
- }
|