User.go 11.2 KB
package Api

import (
	"github.com/aarongao/tools"
	"github.com/davecgh/go-spew/spew"
	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"
	"letu/DB"
	"letu/Lib/Auth"
	"letu/Lib/JWT"
	"regexp"
	"time"
)

var Regular = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"

// @Title 登录
// @Description 用户管理 - 用户登录&注册
// @Accept  json
// @Produce  json
// @Param   Mobile     aaron    string     true        "手机号"
// @Param   Code     1    string     true        "验证码(使用验证码的新手机号自动注册)"
// @Param   DeviceId     abc123    string     false        "手机唯一识别码,不重复(存放于http.header中)"
// @Param   Mac     abc123    string     false        "网卡Mac地址(存放于http.header中)"
// @Param   SystemType     ios    string     false        "ios,android(存放于http.header中)"
// @Param   SystemVersion     13.01    string     false        "手机版本(存放于http.header中)"
// @Param   SystemModel     iphone8    string     false        "手机型号(存放于http.header中)"
// @Param   AppVersion     1.0    string     false        "app版本号(存放于http.header中)"
// @Param   DeviceToken     abc    string     false        "推送token(存放于http.header中)"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":{"Id":"5e09c64c1c09c6f0f7ca2fa9","Token":"640bf934e425aba5d3c90998b2641f2f0ca07261d334d9615d1cd4790b5f34e7"}} 调用其它需要登陆的接口时携带token,有过期时间"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /LoginUser? [post]
func LoginUser(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
	c.Header("Access-Control-Allow-Credentials", "true")

	reg := regexp.MustCompile(Regular)
	if !reg.MatchString(c.PostForm("Mobile")) {

		c.JSON(200, tools.ResponseError{
			1,
			"手机号格式不正确",
		})
		return
	}

	if c.PostForm("Mobile") == "" || c.PostForm("Code") == "" {
		c.JSON(200, tools.ResponseError{
			1,
			"手机号和验证码不能空",
		})
		return
	}

	// 检查验证码
	cacheCode := DB.Redis.Get("code_" + c.PostForm("Mobile"))
	selected := bson.M{}
	var User *DB.SMember
	if cacheCode == c.PostForm("Code") {
		selected["Mobile"] = c.PostForm("Mobile")
		DB.CMember.FindOne(tools.GetContext(), selected).Decode(&User)

		// 验证码匹配,但手机号不存在
		if User == nil {
			var auth = []string{"用户管理", "通知管理"}
			objectID := primitive.NewObjectID()
			User = &DB.SMember{
				Id:       &objectID,
				UserType: "visitor",
				Mobile:   c.PostForm("Mobile"),
				Device: &DB.SDevice{
					c.Request.Header.Get("DeviceId"),
					c.Request.Header.Get("Mac"),
					c.Request.Header.Get("UDID"),
					c.Request.Header.Get("SystemVersion"),
					c.Request.Header.Get("SystemModel"),
					c.Request.Header.Get("AppVersion"),
					c.Request.Header.Get("AppVersion"),
					c.Request.Header.Get("DeviceToken"),
					time.Now().Unix(),
				},
				Auth:       auth,
				CreateTime: time.Now().Unix(),
			}
			_, err := DB.CMember.InsertOne(tools.GetContext(), User)
			if err != nil {

				spew.Dump(err)
				c.JSON(200, tools.ResponseError{
					1,
					"登陆失败(数据创建错误)",
				})
				return
			}
		}

	} else {
		c.JSON(200, tools.ResponseError{
			1,
			"验证码不正确",
		})
		return
	}

	// 生成token
	dd, _ := time.ParseDuration("8760h")
	User.Token, _ = JWT.CreateToken(User, time.Now().Add(dd).Unix())
	c.JSON(200, tools.ResponseSeccess{
		0,
		User,
	})

}

// @Title 注册客户端
// @Description 用户管理 - 注册客户端
// @Accept  json
// @Produce  json
// @Param   DeviceId     abc123    string     false        "手机唯一识别码,不重复(存放于http.header中)"
// @Param   Mac     abc123    string     false        "网卡Mac地址(存放于http.header中)"
// @Param   SystemType     ios    string     false        "ios,android(存放于http.header中)"
// @Param   SystemVersion     13.01    string     false        "手机版本(存放于http.header中)"
// @Param   SystemModel     iphone8    string     false        "手机型号(存放于http.header中)"
// @Param   AppVersion     1.0    string     false        "app版本号(存放于http.header中)"
// @Param   DeviceToken     abc    string     false        "推送token(存放于http.header中)"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /RegisterDevice? [post]
func RegisterDevice(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
	c.Header("Access-Control-Allow-Credentials", "true")

	if c.Request.Header.Get("DeviceId") == "" {
		c.JSON(200, tools.ResponseError{
			1,
			"DeviceId不正确",
		})
		return
	}

	upsert := true
	DB.CDevice.FindOneAndUpdate(tools.GetContext(),
		bson.M{"DeviceId": c.Request.Header.Get("DeviceId")},
		bson.M{"$set": bson.M{
			"Mac":           c.Request.Header.Get("Mac"),
			"UDID":          c.Request.Header.Get("UDID"),
			"SystemType":    c.Request.Header.Get("SystemType"),
			"SystemVersion": c.Request.Header.Get("SystemVersion"),
			"SystemModel":   c.Request.Header.Get("SystemModel"),
			"AppVersion":    c.Request.Header.Get("AppVersion"),
			"DeviceToken":   c.Request.Header.Get("DeviceToken"),
		}}, &options.FindOneAndUpdateOptions{
			Upsert: &upsert,
		},
	)

	c.JSON(200, tools.ResponseSeccess{
		0,
		"ok",
	})

}

// @Title 用户信息
// @Description 用户管理 - 获取用户信息
// @Accept  json
// @Produce  json
// @Param   id     aaron    string     true        "用户id"
// @Param   Token     wgergejfwe    string     true        "用户token"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":{"Id":"5e09c64c1c09c6f0f7ca2fa9","Token":"640bf934e425aba5d3c90998b2641f2f0ca07261d334d9615d1cd4790b5f34e7"}}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /UserInfo? [get]
func UserInfo(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
	c.Header("Access-Control-Allow-Credentials", "true")

	_user, _ := c.Get("UserInfo")
	user := _user.(*DB.SMember)

	objID, err := primitive.ObjectIDFromHex(c.Query("id"))
	if err != nil {
		c.JSON(200, tools.ResponseError{
			1,
			"用户id不正确",
		})
		return
	}

	var User DB.SMember
	DB.CMember.FindOne(tools.GetContext(), bson.M{"_id": objID}).Decode(&User)

	User.Device = &DB.SDevice{}

	if user.UserType == "visitor" {
		User.Username = ""
		User.Password = ""
		User.Auth = nil
	}

	c.JSON(200, tools.ResponseSeccess{
		0,
		User,
	})

}

// @Title 用户信息
// @Description 用户管理 - 检查Token是否过期
// @Accept  json
// @Produce  json
// @Param   Token     wgergejfwe    string     true        "用户token"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":401,"errmsg":"token过期"}"
// @Router /CheckToken? [post]
func CheckToken(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
	c.Header("Access-Control-Allow-Credentials", "true")

	if c.PostForm("Token") == "" {
		c.JSON(200, tools.ResponseError{
			1,
			"Token不正确",
		})
		return
	}

	user, err := JWT.ParseToken(c.PostForm("Token"))

	if err != nil {
		c.JSON(200, tools.ResponseError{
			401,
			err.Error(),
		})
		return
	}

	c.JSON(200, tools.ResponseSeccess{
		0,
		user,
	})

}

// @Title 修改用户信息
// @Description 用户管理 - 修改用户信息
// @Accept  json
// @Produce  json
// @Param   id     aaron    string     true        "用户id""
// @Param   Token     wgergejfwe    string     true        "用户token"
// @Param   Birthday     2010.10.10    string     true        "生日"
// @Param   FullName     aarongao    string     true        "全名"
// @Param   Code     12345678    string     true        "6位验证码"
// @Param   Mobile     18616619599    string     true        "手机,同用户名"
// @Param   Sex     男    string     true        "性别"
// @Param   Openid     12345    string     true        "微信id"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /UpdateUser? [post]
func UpdateUser(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
	c.Header("Access-Control-Allow-Credentials", "true")

	_user, _ := c.Get("UserInfo")
	user := _user.(*DB.SMember)

	err := Auth.CheckUserAuth(c.PostForm("id"), user)
	if err != nil {
		c.JSON(200, tools.ResponseError{
			401,
			"没有权限",
		})
		return
	}

	if c.PostForm("id") != user.Id.Hex() {
		c.JSON(200, tools.ResponseError{
			401,
			"没有权限",
		})
		return
	}

	reg := regexp.MustCompile(Regular)
	if !reg.MatchString(c.PostForm("Mobile")) {

		c.JSON(200, tools.ResponseError{
			1,
			"手机号格式不正确",
		})
		return
	}

	if c.PostForm("Mobile") == "" || c.PostForm("Code") == "" {
		c.JSON(200, tools.ResponseError{
			1,
			"手机号或验证码不能为空",
		})
		return
	}

	// 检查验证码
	code := DB.Redis.Get("code_" + c.PostForm("Mobile"))
	if code == "" || code != c.PostForm("Code") {
		c.JSON(200, tools.ResponseError{
			1,
			"验证码错误",
		})
		return
	}

	objID, _ := primitive.ObjectIDFromHex(c.PostForm("id"))
	_, err = DB.CMember.UpdateOne(tools.GetContext(),
		bson.M{"_id": objID},
		bson.M{"$set": bson.M{
			"Birthday": c.PostForm("Birthday"),
			"FullName": c.PostForm("FullName"),
			"Mobile":   c.PostForm("Mobile"),
			"Sex":      c.PostForm("Sex"),
		}},
	)

	if err == nil {
		var User *DB.SMember
		objID, _ := primitive.ObjectIDFromHex(c.PostForm("id"))
		DB.CMember.FindOne(tools.GetContext(), bson.M{"_id": objID}).Decode(&User)
		User.Token = ""
		c.JSON(200, tools.ResponseSeccess{
			0,
			User,
		})
	} else {
		c.JSON(200, tools.ResponseError{
			1,
			err.Error(),
		})
	}

}

// @Title 删除用户
// @Description 用户管理 - 删除用户(注销)
// @Accept  json
// @Produce  json
// @Param   id     aaron    string     true        "用户id""
// @Param   Token     wgergejfwe    string     true        "用户token"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /RemoveUser? [post]
func RemoveUser(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
	c.Header("Access-Control-Allow-Credentials", "true")

	_user, _ := c.Get("UserInfo")
	user := _user.(*DB.SMember)

	err := Auth.CheckUserAuth(c.PostForm("id"), user)
	if err != nil {
		c.JSON(200, tools.ResponseError{
			401,
			"没有权限",
		})
		return
	}

	objID, err := primitive.ObjectIDFromHex(c.PostForm("id"))
	if err != nil {
		c.JSON(200, tools.ResponseError{
			1,
			"用户id不正确",
		})
		return
	}

	_, err = DB.CMember.DeleteOne(tools.GetContext(), bson.M{"_id": objID})

	if err == nil {

		c.JSON(200, tools.ResponseSeccess{
			0,
			"ok",
		})
	} else {
		c.JSON(200, tools.ResponseError{
			1,
			err.Error(),
		})
	}

}