blog_backend_api/controller/user.go

538 lines
12 KiB
Go

package controller
import (
"background/config"
"background/db"
"background/logs"
"background/model"
"background/redis"
"background/utils"
"bytes"
"crypto/md5"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"math/rand"
"net/http"
"net/smtp"
"regexp"
"strconv"
"strings"
"time"
"github.com/fatih/structs"
"github.com/gin-gonic/gin"
_ "github.com/go-sql-driver/mysql"
sessions "github.com/tommy351/gin-sessions"
)
type UserController struct {
}
type ReqSendEmailCode struct {
EmailAdress string `json:"email_address"`
}
type SetUserGroupReq struct {
Id int64 `json:"id,omitempty"`
Description string `json:"description"`
GroupName string `json:"group_name"`
UserIds []int `json:"user_ids"`
}
func (this *UserController) Auth(c *gin.Context) {
var resp RespBase
var statuscode int
statuscode = 200
var userinfo map[string]interface{}
//var userSockToken map[string] interface{}
defer func() {
c.JSON(statuscode, resp)
}()
socketToken := c.Query("socketToken")
struserinfo, e := redis.Get(socketToken)
if e != nil {
logs.Error(e.Error())
return
}
e = json.Unmarshal([]byte(struserinfo), userinfo)
if nil != e {
logs.Error(e.Error())
return
}
}
func (this *UserController) SetUser(c *gin.Context) {
}
func (this *UserController) ModifyPasswd(c *gin.Context) {
type ReqModifyPasswd struct {
id int `json:"id"`
UserName string `json:"user_name"`
Password string `json:"password"`
}
var req ReqModifyPasswd
var resp RespBase
resp.Status = -1
resp.Msg = "err"
defer func() {
c.JSON(200, resp)
}()
e := c.BindJSON(&req)
if nil != e {
logs.Error(e.Error())
return
}
e = model.ModyfyPassword(req.UserName, req.Password)
if nil != e {
logs.Error(e.Error())
return
}
resp.Msg = "OK"
resp.Status = 0
}
func (this *UserController) DelUser(c *gin.Context) {
}
func (this *UserController) GetUser(c *gin.Context) {
var resp RespBase
resp.Msg = "操作失败"
resp.Status = 20
defer func() {
c.JSON(200, resp)
}()
session := sessions.Get(c)
userinfo := session.Get("")
if userinfo == nil {
logs.Error("error could not find key")
return
}
var users map[string]interface{}
e := json.Unmarshal([]byte(userinfo.(string)), &users)
if nil != e {
logs.Error(e.Error())
}
delete(users, "socketToken")
resp.Status = 0
resp.Msg = "操作成功"
resp.Data = users
}
func (this *UserController) Users(c *gin.Context) {
var statuscode int
var resp RespBase
resp.Msg = "获取失败"
resp.Status = 0
statuscode = 200
defer func() {
c.JSON(statuscode, resp)
}()
offset := c.Query("offset")
limit := c.Query("limit")
ioffset, e := strconv.Atoi(offset)
if nil != e {
logs.Error(e.Error())
return
}
ilimit, er := strconv.Atoi(limit)
if nil != er {
logs.Error(e.Error())
return
}
dat := map[string]interface{}{}
users, all := model.GetUsers(int32(ilimit), int32(ioffset), "")
dat["users"] = users
dat["all"] = all
resp.Msg = "OK"
resp.Data = dat
}
func (this *UserController) SerarchUsers(c *gin.Context) {
var statuscode int
var resp RespBase
resp.Msg = "获取失败"
resp.Status = 0
statuscode = 200
defer func() {
c.JSON(statuscode, resp)
}()
offset := c.Query("offset")
limit := c.Query("limit")
username := c.PostForm("username")
ioffset, e := strconv.Atoi(offset)
if nil != e {
logs.Error(e.Error())
return
}
ilimit, er := strconv.Atoi(limit)
if nil != er {
logs.Error(e.Error())
return
}
dat := map[string]interface{}{}
users, all := model.GetUsers(int32(ilimit), int32(ioffset), username)
dat["users"] = users
dat["all"] = all
resp.Msg = "OK"
resp.Data = dat
}
func CreateVerify(length int32) string {
strAry := []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
result := string("")
for i := int32(0); i < length; i++ {
x := rand.Intn(len(strAry))
result += string(strAry[x])
}
return result
}
/**
* 取随机Token
* @param {Number} length 取Token的长度
* @return {string} 获取的Token
*/
func createToken(length int32) string {
strAry := []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_'}
result := string("")
for i := int32(0); i < length; i++ {
x := rand.Intn(len(strAry))
result += string(strAry[x])
}
return result
}
func DefaultOption(c *gin.Context) {
var resp RespBase
defer func() {
c.JSON(204, resp)
}()
}
func (this *UserController) Login(c *gin.Context) {
// defer func() {
// if err := recover();err != nil{
// log.Printf("panic: v%",err)
// }
// }()
type LoginReq struct {
RememberMe int32 `json:"remember_me"`
UserName string `json:"user_name"`
UserPwd string `json:"user_pwd"`
}
var req LoginReq
statusCode := 200
var resp RespBase
defer func() {
c.JSON(statusCode, resp)
}()
e := c.Bind(&req)
if e != nil {
log.Println(e.Error())
return
}
h := md5.New()
h.Write([]byte(req.UserPwd)) // 需要加密的字符串为 123456
passmd5 := h.Sum(nil)
var result []model.Users
query := fmt.Sprintf("select * from users where user_name = '%s'", req.UserName)
er := db.GetMysqlClient().Query2(query,
&result)
logs.Debug("sql query:" + query)
if nil != er {
log.Println(er.Error())
}
strpassmd5 := utils.ByteSliceToString(passmd5)
if len(result) == 1 {
if result[0].UserPwd == strpassmd5 {
socketToken := md5.New()
socketToken.Write([]byte(createToken(6))) // 需要加密的字符串为 123456
socketTokenMd5 := socketToken.Sum(nil)
m := structs.Map(result[0])
m["SocketToken"] = utils.ByteSliceToString(socketTokenMd5)
sessionInfo, err := json.Marshal(m)
if err != nil {
log.Println(err.Error())
}
if req.RememberMe == 1 {
config.RedisOne().Set(utils.ByteSliceToString(socketTokenMd5), string(sessionInfo), time.Second*24*3600)
} else {
log.Print(utils.ByteSliceToString(socketTokenMd5), string(sessionInfo), time.Second*8*3600)
cli := config.RedisOne()
if nil != cli{
status := cli.Set(utils.ByteSliceToString(socketTokenMd5), string(sessionInfo), time.Second*8*3600)
if status.Err() != nil{
log.Println(status)
}
}
}
//存储session
session := sessions.Get(c)
log.Println("set session", string(sessionInfo))
session.Set("", string(sessionInfo))
session.Clear()
//session.
var Options *sessions.Options
if req.RememberMe == 1 {
Options = &sessions.Options{
MaxAge: 2 * 24 * 3600 * 1000,
}
} else {
Options = &sessions.Options{
MaxAge: 8 * 3600 * 1000,
}
}
session.Options(*Options)
session.Save()
resp.Msg = "登录成功"
resp.Status = 0
resp.Data = string(sessionInfo)
} else {
resp.Status = 422
resp.Msg = "用户密码不正确"
}
} else {
resp.Status = 422
resp.Msg = "登录账号不存在,请重新输入"
}
}
func (this *UserController) Register(c *gin.Context) {
type RegisterReq struct {
DisplayName string `json:"display_name"`
EmailAdress string `json:"email_address"`
EmailCode string `json:"email_code"`
UserName string `json:"user_name"`
UserPwd string `json:"user_pwd"`
}
var req RegisterReq
statusCode := 200
var resp RespBase
var user model.Users
resp.Msg = "失败"
resp.Status = 1
defer func() {
c.JSON(statusCode, resp)
}()
e := c.Bind(&req)
if e != nil {
log.Println(e.Error())
return
}
userKey := fmt.Sprintf("user_%s_verify", req.EmailAdress)
verify := config.RedisOne().Get(userKey).Val()
if verify != req.EmailCode {
resp.Msg = "验证码错误"
resp.Status = 20
return
}
user.UserName = req.UserName
user.EmailAddress = req.EmailAdress
user.DisplayName = req.DisplayName
h := md5.New()
h.Write([]byte(req.UserPwd))
passwdmd5 := h.Sum(nil)
strpassmd5 := utils.ByteSliceToString(passwdmd5)
user.UserPwd = strpassmd5
user.UpdatedDate = time.Now().Format("2006-01-02 15:04:05")
user.CreatedDate = time.Now().Format("2006-01-02 15:04:05")
var result []model.Users
er := db.GetMysqlClient().Query2("select * from users where user_name = ?",
&result, req.UserName)
if nil != er {
log.Println(er.Error())
return
}
if len(result) > 0 {
resp.Msg = "失败,账号已经存在"
resp.Status = 20
return
}
query := fmt.Sprintf("insert into users(user_name,user_pwd,created_date,"+
"updated_date,display_name,email_address) values ('%s','%s','%s','%s','%s','%s')", user.UserName, user.UserPwd, user.CreatedDate, user.UpdatedDate,
user.DisplayName, user.EmailAddress)
n, er := db.GetMysqlClient().Insert(query)
if n == 0 || n < 0 {
statusCode = 422
logs.Error(er.Error())
resp.Msg = "失败,账号已经存在"
resp.Status = 20
return
}
if nil != er {
statusCode = 422
logs.Error(er.Error())
resp.Msg = "失败"
resp.Status = 20
return
}
resp.Msg = "成功"
resp.Status = 0
}
func (this *UserController) Logout(c *gin.Context) {
token := c.Param("token")
log.Print("logout token is ", token)
var resp RespBase
config.RedisOne().Del(token)
resp.Msg = "退出成功"
resp.Status = 0
defer func() {
c.JSON(200, resp)
}()
session := sessions.Get(c)
session.Delete("")
session.Save()
}
func Reader2Json(r io.ReadCloser) string {
var ret string
for i := 0; ; i++ {
s := make([]byte, 10)
_, e := r.Read(s)
ret += string(s)
if e != nil {
break
}
}
return ret
}
func SendExternalEmail(msg interface{}) error {
req := make(map[string]interface{}, 1)
req["type"] = "text"
req["action"] = "smtp-sys"
req["apiType"] = "send"
content, err := json.Marshal(msg)
if err != nil {
log.Println(err.Error())
return errors.New("Json marshal error")
}
req["content"] = string(content)
var buffer bytes.Buffer
b, e := json.Marshal(req)
if e != nil {
log.Println(e.Error())
}
buffer.Write(b)
resp, err := http.Post("http://47.93.230.163:8091/msg/v1/send", "application/json", &buffer)
if resp.StatusCode != 200 {
return errors.New("error send emain")
}
if err != nil {
logs.Error("error send email")
return err
}
return nil
}
func SendToMail(title, user string, password string, host string, to string, content string,
ifgenerate bool) error {
var content_type string
hp := strings.Split(host, ":")
auth := smtp.PlainAuth("", user, password, hp[0])
content_type = "Content-Type: text/plain" + "; charset=UTF-8"
msg := []byte("To: " + to + "\r\nFrom: " + user + "\r\nSubject: " + title + "\r\n" +
content_type + "\r\n\r\n" + content + "\r\n")
send_to := strings.Split(to, ";")
//检测是否是邮件地址
for k, _ := range send_to {
match, _ := regexp.MatchString("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?", send_to[k])
if !match {
return errors.New("Format Error")
}
}
err := smtp.SendMail(host, auth, user, send_to, msg)
if err != nil {
return err
}
return err
}
func (this *UserController) SendEmailCode(c *gin.Context) {
var req ReqSendEmailCode
var resp RespBase = RespBase{Msg: "邮件已经存在", Status: 0}
statusCode := 200
defer func() {
c.JSON(statusCode, resp)
}()
e := c.Bind(&req)
if nil != e {
log.Println(e.Error())
resp.Msg = "请求参数错误"
return
}
//判断邮箱是否存在
var users []model.Users
e = db.GetMysqlClient().Query2("select * from users where email_adress = ?", &users, req.EmailAdress)
if nil != e {
log.Print(e.Error())
resp.Msg = "email address error"
return
}
if len(users) != 0 {
statusCode = 422
return
}
//产生验证码
verify := CreateVerify(6)
session := sessions.Get(c)
session.Set(req.EmailAdress, verify)
session.Save()
sendcontent := make(map[string]interface{}, 1)
sendcontent["subject"] = "邮箱验证码,请注意查收"
sendcontent["receivers"] = req.EmailAdress
sendcontent["content"] = string("您本次注册的验证码为:") + verify + string(",工作人员不会向您索取,请勿泄露。请尽快完成操作。")
e = SendExternalEmail(sendcontent)
if e != nil {
log.Println(e.Error())
return
}
//成功
resp.Msg = "发送成功"
}