ziwen 1 سال پیش
والد
کامیت
ea1ce0eab4

+ 146 - 2
controller/auth.go

@@ -1,13 +1,157 @@
 package controller
 
 import (
+	"fmt"
 	"github.com/gin-gonic/gin"
+	"github.com/go-playground/validator/v10"
+	"hongze/hongze_yb_en_api/controller/resp"
+	"hongze/hongze_yb_en_api/global"
+	"hongze/hongze_yb_en_api/models"
+	"hongze/hongze_yb_en_api/models/english_report_email"
+	"hongze/hongze_yb_en_api/services"
+	"hongze/hongze_yb_en_api/utils"
+	"time"
 )
 
 type AuthController struct {
+}
+
+func (a *AuthController) Login(c *gin.Context) {
+	req := new(models.LoginReq)
+	err := c.BindQuery(&req)
+	if err != nil {
+		errs, ok := err.(validator.ValidationErrors)
+		if !ok {
+			resp.FailData("参数解析失败", "Err:"+err.Error(), c)
+			return
+		}
+		resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
+		return
+	}
+	sysUser, err := english_report_email.CheckUser(req.Type, req.Account, req.Password)
+	if err != nil {
+		resp.FailData("登录失败,账号或密码错误", "Err:"+err.Error(), c)
+		return
+	}
+	if sysUser == nil {
+		resp.FailData("登录失败,账号或密码错误", "Err:"+err.Error(), c)
+		return
+	}
+	if sysUser.Enable == 0 {
+		resp.FailData("您的账号已被禁用,如需登录,请联系管理员", "Err:"+err.Error(), c)
+		return
+	}
+	account := utils.MD5(req.Account)
+	token, err := utils.GenToken(account)
+	sysSession := new(models.EnglishYbSession)
+	sysSession.UserId = int(sysUser.AdminId)
+	//现在要求永不过期
+	sysSession.ExpiredTime = time.Now().AddDate(99, 0, 0)
+	sysSession.CreatedTime = time.Now()
+	sysSession.LastUpdatedTime = time.Now()
+	sysSession.AccessToken = token
+	err = sysSession.AddSession()
+	fmt.Println("id:", sysSession.SessionId)
+	if err != nil {
+		resp.FailData("新增session信息失败", "Err:"+err.Error(), c)
+		return
+	}
+
+}
+
+func (a *AuthController) Register(c *gin.Context) {
+	req := new(models.LoginReq)
+	err := c.BindQuery(&req)
+	if err != nil {
+		errs, ok := err.(validator.ValidationErrors)
+		if !ok {
+			resp.FailData("参数解析失败", "Err:"+err.Error(), c)
+			return
+		}
+		resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
+		return
+	}
+}
 
+// @Title 修改密码
+// @Description 修改密码
+// @Param	request	body models.ModifyPwdReq true "type json string"
+// @Success 200 {object} models.LoginResp
+// @router /modifyPwd [post]
+func (a *AuthController) ModifyPwd(c *gin.Context) {
+	req := new(models.ModifyPwdReq)
+	err := c.BindQuery(&req)
+	if err != nil {
+		errs, ok := err.(validator.ValidationErrors)
+		if !ok {
+			resp.FailData("参数解析失败", "Err:"+err.Error(), c)
+			return
+		}
+		resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
+		return
+	}
+
+}
+
+// GetSmsCode 获取短信验证码接口
+// @Tags 用户模块
+// @Summary  获取短信验证码
+// @Description 获取短信验证码接口
+// @Security ApiKeyAuth
+// @securityDefinitions.basic BasicAuth
+// @Param mobile	query string true "手机号"
+// @Param area_num	query string true "手机国际区号(中国大陆:86)"
+// @Accept  json
+// @Product json
+// @Success 200 {string} string 获取验证码成功
+// @Failure 400 {string} string 手机号不能为空,请输入手机号
+// @Router /get_sms_code [get]
+func (a *AuthController) GetSmsCode(c *gin.Context) {
+	mobile := c.DefaultQuery("mobile", "")
+	areaNum := c.DefaultQuery("area_num", "")
+	err, errMsg := services.SendSmsCode(mobile, areaNum)
+	if err != nil {
+		if errMsg != "" {
+			errMsg = "获取验证码失败"
+		}
+		resp.Fail(errMsg, c)
+		return
+	}
+
+	resp.Ok("获取验证码成功", c)
 }
 
-func (a *AuthController) Login(c *gin.Context)  {
-	return
+// GetEmailCode 获取邮箱验证码接口
+// @Tags 用户模块
+// @Summary  获取邮箱验证码
+// @Description 获取邮箱验证码
+// @Security ApiKeyAuth
+// @securityDefinitions.basic BasicAuth
+// @Param email	query string true "电子邮箱账号"
+// @Accept  json
+// @Product json
+// @Success 200 {string} string 获取验证码成功
+// @Failure 400 {string} string 请输入邮箱地址
+// @Router /get_email_code [get]
+func (a *AuthController) GetEmailCode(c *gin.Context) {
+	email := c.DefaultQuery("email", "")
+	if email == "" {
+		resp.Fail("请输入邮箱地址", c)
+		return
+	}
+	if !utils.ValidateEmailFormatat(email) {
+		resp.Fail("邮箱格式错误,请重新输入", c)
+		return
+	}
+
+	err, errMsg := services.SendEmailCode(email)
+	if err != nil {
+		if errMsg != "" {
+			errMsg = "获取验证码失败"
+		}
+		resp.Fail(errMsg, c)
+		return
+	}
+
+	resp.Ok("获取验证码成功", c)
 }

+ 1 - 1
go.mod

@@ -17,9 +17,9 @@ require (
 	github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
 	github.com/rdlucklib/rdluck_tools v1.0.3
 	github.com/spf13/viper v1.14.0
-	github.com/swaggo/gin-swagger v1.5.3
 	github.com/swaggo/swag v1.8.8
 	golang.org/x/image v0.2.0
+	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
 	gorm.io/driver/mysql v1.4.4
 	gorm.io/gorm v1.24.2
 )

BIN
hongze_yb_en_api


+ 12 - 0
models/english_report_email/email.go

@@ -17,6 +17,7 @@ type Email struct {
 	IsDeleted    uint8     `gorm:"column:is_deleted" json:"is_deleted"`         //删除状态:0-正常;1-已删除
 	AdminId      uint      `gorm:"column:admin_id" json:"admin_id"`             //创建人ID
 	AdminName    string    `gorm:"column:admin_name" json:"admin_name"`         //创建人名称
+	Enable       int       `gorm:"column:enable" json:"enable"`
 	base.TimeBase
 }
 
@@ -47,3 +48,14 @@ func (e *Email) UpdateViewTotalById(Id uint) (err error) {
 	err = global.DEFAULT_MYSQL.Exec(sql, Id).Error
 	return
 }
+
+func CheckUser(loginType int, account, password string) (item *Email, err error) {
+	sql := ``
+	if loginType == 1 {
+		sql = `SELECT * FROM english_report_email WHERE email=? AND password=?  `
+	} else {
+		sql = `SELECT * FROM english_report_email WHERE mobile=? AND password=?  `
+	}
+	err = global.DEFAULT_MYSQL.Exec(sql, account, password).Error
+	return
+}

+ 39 - 0
models/english_yb_session.go

@@ -0,0 +1,39 @@
+package models
+
+import (
+	"hongze/hongze_yb_en_api/global"
+	"time"
+)
+
+type EnglishYbSession struct {
+	SessionId       int    `gorm:"primaryKey;column:session_id" json:"session_id"`
+	UserId          int    `gorm:"column:user_id" json:"user_id"`
+	AccessToken     string `gorm:"column:access_token" json:"access_token"`
+	ExpiredTime     time.Time
+	CreatedTime     time.Time
+	LastUpdatedTime time.Time
+}
+
+// TableName get sql table name.获取数据库表名
+func (e *EnglishYbSession) TableName() string {
+	return "english_yb_session"
+}
+
+// 新增用户登录session信息
+func (e *EnglishYbSession) AddSession() (err error) {
+	err = global.DEFAULT_MYSQL.Create(e).Error
+	return
+}
+
+func GetSessionByUserId(userId int) (item *EnglishYbSession, err error) {
+	sql := `SELECT * FROM english_yb_session WHERE user_id=? AND expired_time> NOW() ORDER BY expired_time DESC LIMIT 1 `
+	err = global.DEFAULT_MYSQL.Exec(sql, userId).Error
+	return
+}
+
+func GetSessionByToken(token string) (item *EnglishYbSession, err error) {
+	sql := `SELECT * FROM english_yb_session WHERE access_token=? AND expired_time> NOW() ORDER BY expired_time DESC LIMIT 1 `
+	err = global.DEFAULT_MYSQL.Exec(sql, token).Error
+	return
+}
+

+ 11 - 0
models/msg_code/create.go

@@ -0,0 +1,11 @@
+package msg_code
+
+import (
+	"hongze/hongze_yb_en_api/global"
+)
+
+//  Create 新增记录
+func (msgCode *MsgCode) Create() (err error) {
+	err = global.MYSQL["rddp"].Create(msgCode).Error
+	return
+}

+ 41 - 0
models/msg_code/msg_code.go

@@ -0,0 +1,41 @@
+package msg_code
+
+import "time"
+
+// MsgCode 验证码列表
+type MsgCode struct {
+	MsgCodeID       int64     `gorm:"primaryKey;column:msg_code_id;type:bigint(20);not null" json:"-"`                // 短信验证码id
+	OpenID          string    `gorm:"index:open_id;column:open_id;type:varchar(32);not null" json:"openId"`           // 用户id
+	Mobile          string    `gorm:"index:mobile;column:mobile;type:varchar(50);not null" json:"mobile"`             // 手机号/邮箱
+	Code            string    `gorm:"column:code;type:varchar(20);not null" json:"code"`                              // 验证码
+	ExpiredIn       int64     `gorm:"column:expired_in;type:bigint(20);not null" json:"expiredIn"`                    // 过期时间
+	Enabled         int8      `gorm:"column:enabled;type:tinyint(1)" json:"enabled"`                                  // 状态
+	CreatedTime     time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP" json:"createdTime"` // 创建时间
+	LastUpdatedTime time.Time `gorm:"column:last_updated_time;type:timestamp;not null;default:CURRENT_TIMESTAMP" json:"lastUpdatedTime"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *MsgCode) TableName() string {
+	return "msg_code"
+}
+
+// MsgCodeColumns get sql column name.获取数据库列名
+var MsgCodeColumns = struct {
+	MsgCodeID       string
+	OpenID          string
+	Mobile          string
+	Code            string
+	ExpiredIn       string
+	Enabled         string
+	CreatedTime     string
+	LastUpdatedTime string
+}{
+	MsgCodeID:       "msg_code_id",
+	OpenID:          "open_id",
+	Mobile:          "mobile",
+	Code:            "code",
+	ExpiredIn:       "expired_in",
+	Enabled:         "enabled",
+	CreatedTime:     "created_time",
+	LastUpdatedTime: "last_updated_time",
+}

+ 11 - 0
models/msg_code/query.go

@@ -0,0 +1,11 @@
+package msg_code
+
+import (
+	"hongze/hongze_yb_en_api/global"
+)
+
+// GetMsgCode 根据token获取信息
+func GetMsgCode(mobile, code string) (item *MsgCode, err error) {
+	err = global.MYSQL["rddp"].Where("mobile = ? and code = ? and FROM_UNIXTIME(expired_in)>=NOW() ", mobile, code).First(&item).Error
+	return
+}

+ 39 - 0
models/user.go

@@ -0,0 +1,39 @@
+package models
+
+import (
+	"hongze/hongze_yb_en_api/models/base"
+)
+
+type LoginReq struct {
+	Account    string `description:"账号"`
+	Type       int    `description:"类型 1:邮箱 2:手机"`
+	Password   string `description:"密码"`
+	IsRemember bool   `description:"是否属于受信设备"`
+}
+
+type LoginResp struct {
+	Authorization   string
+	AdminName       string `description:"系统用户名称"`
+	RealName        string `description:"系统用户姓名"`
+	RoleName        string `description:"角色名称"`
+	RoleTypeCode    string `description:"角色类型编码"`
+	SysRoleTypeCode string `description:"角色类型编码"`
+	AdminId         int    `description:"系统用户id"`
+	ProductName     string `description:"产品名称:admin,ficc,权益"`
+	Authority       int    `description:"管理权限,0:无,1:部门负责人,2:小组负责人,或者ficc销售主管,4:ficc销售组长"`
+}
+
+type RegisterReq struct {
+	Company     string
+	Mobile      string
+	Password    string
+	CountryCode string
+	Name        string `json:"name"`   //客户名称
+	Email       string `json:"email"` //邮箱地址
+	base.TimeBase
+}
+
+type ModifyPwdReq struct {
+	OldPwd string `description:"旧密码"`
+	NewPwd string `description:"新密码"`
+}

+ 4 - 0
routers/auth.go

@@ -10,4 +10,8 @@ func InitAuth(baseGroup *gin.RouterGroup) {
 	authController := new(controller.AuthController)
 	authGroup := baseGroup.Group("auth/")
 	authGroup.POST("login", authController.Login)
+	authGroup.POST("register", authController.Register)
+	authGroup.POST("modifyPwd", authController.Login)
+	authGroup.POST("smsCode", authController.GetSmsCode)
+	authGroup.POST("emailCode", authController.GetEmailCode)
 }

+ 70 - 0
services/email.go

@@ -0,0 +1,70 @@
+package services
+
+import (
+	"errors"
+	"gopkg.in/gomail.v2"
+	"hongze/hongze_yb_en_api/models/msg_code"
+	"hongze/hongze_yb_en_api/utils"
+	"strings"
+	"time"
+)
+
+
+// SendEmailCode 发送邮件
+func SendEmailCode(email string) (err error, errMsg string) {
+	if email == "" {
+		err = errors.New("请输入邮箱地址")
+		return
+	}
+	if !utils.ValidateEmailFormatat(email) {
+		err = errors.New("邮箱格式错误,请重新输入")
+		return
+	}
+	msgCode := utils.GetRandDigit(4)
+	content := "尊敬的用户:</br>您好,感谢您使用弘则研究,您正在进行邮箱验证,本次请求的验证码为:" + msgCode + "(为了保障您账号的安全性,请在15分钟内完成验证。)</br>弘则研究团队 </br>" + time.Now().Format(utils.FormatDateCN)
+	title := "弘则研究登陆验证"
+	//发送邮件
+	result, err := SendEmailByHz(title, content, email)
+
+	if result {
+		item := &msg_code.MsgCode{
+			Mobile:          email,
+			Code:            msgCode,
+			ExpiredIn:       time.Now().Add(15 * time.Minute).Unix(),
+			Enabled:         1,
+			CreatedTime:     time.Time{},
+			LastUpdatedTime: time.Time{},
+		}
+		err = item.Create()
+	} else {
+		err = errors.New("发送失败")
+	}
+
+	return
+}
+
+//发送邮件
+func SendEmailByHz(title, content string, touser string) (result bool, err error) {
+	var arr []string
+	sub := strings.Index(touser, ";")
+	if sub >= 0 {
+		spArr := strings.Split(touser, ";")
+		for _, v := range spArr {
+			arr = append(arr, v)
+		}
+	} else {
+		arr = append(arr, touser)
+	}
+	m := gomail.NewMessage()
+	m.SetHeader("From", "public@hzinsights.com")
+	m.SetHeader("To", arr...)
+	m.SetHeader("Subject", title)
+	m.SetBody("text/html", content)
+	d := gomail.NewDialer("smtp.mxhichina.com", 465, "public@hzinsights.com", "Hzinsights2018")
+	if err := d.DialAndSend(m); err != nil {
+		result = false
+		return result, err
+	}
+	result = true
+	return
+}

+ 163 - 0
services/sms.go

@@ -0,0 +1,163 @@
+package services
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"hongze/hongze_yb_en_api/models/msg_code"
+	"hongze/hongze_yb_en_api/services/alarm_msg"
+	"hongze/hongze_yb_en_api/utils"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"time"
+)
+
+// SendSmsCode 发送手机短信
+func SendSmsCode(mobile, areaNum string) (err error, errMsg string) {
+	if mobile == "" {
+		err = errors.New("请输入手机号")
+		return
+	}
+	msgCode := utils.GetRandDigit(4)
+	var result bool
+	if areaNum == "86" || areaNum == "" || areaNum == "0" {
+		//国内的短信
+		result = SendSmsCodeGn(mobile, msgCode)
+	} else {
+		//国际短信
+		result = SendSmsCodeGj(mobile, msgCode, areaNum)
+	}
+	//发送成功
+	if result {
+		item := &msg_code.MsgCode{
+			Mobile:          mobile,
+			Code:            msgCode,
+			ExpiredIn:       time.Now().Add(15 * time.Minute).Unix(),
+			Enabled:         1,
+			CreatedTime:     time.Time{},
+			LastUpdatedTime: time.Time{},
+		}
+		err = item.Create()
+	} else {
+		err = errors.New("短信发送失败")
+	}
+	return
+}
+
+
+// SendSmsCode 发送国内短信
+func SendSmsCodeGn(mobile, vCode string) bool {
+	flag := false
+	tplId := "65692"
+	result, err := sendSms(mobile, tplId, vCode)
+	if err != nil {
+		fmt.Println("发送短信失败")
+		return false
+	}
+	fmt.Println("result", string(result))
+	var netReturn map[string]interface{}
+	err = json.Unmarshal(result, &netReturn)
+	if err != nil {
+		//go SendEmail("短信验证码发送失败", "err:"+err.Error()+" result"+string(result), utils.EmailSendToUsers)
+		go alarm_msg.SendAlarmMsg("短信验证码发送失败, Err:"+err.Error()+";Result:"+string(result), 2)
+		flag = false
+	}
+	if netReturn["error_code"].(float64) == 0 {
+		fmt.Printf("接口返回result字段是:\r\n%v", netReturn["result"])
+		flag = true
+	} else {
+		// 忽略错误的手机号码这种错误
+		if netReturn["error_code"].(float64) != 205401 {
+			go alarm_msg.SendAlarmMsg("短信验证码发送失败, Result:"+string(result), 2)
+		}
+		flag = false
+	}
+	return flag
+}
+
+// sendSms 发送国内短信
+func sendSms(mobile, tplId, code string) (rs []byte, err error) {
+	var Url *url.URL
+	apiURL := "http://v.juhe.cn/sms/send"
+	//初始化参数
+	param := url.Values{}
+	//配置请求参数,方法内部已处理urlencode问题,中文参数可以直接传参
+	param.Set("mobile", mobile)            //接受短信的用户手机号码
+	param.Set("tpl_id", tplId)             //您申请的短信模板ID,根据实际情况修改
+	param.Set("tpl_value", "#code#="+code) //您设置的模板变量,根据实际情况
+	param.Set("key", utils.JhGnAppKey)     //应用APPKEY(应用详细页查询)
+
+	Url, err = url.Parse(apiURL)
+	if err != nil {
+		fmt.Printf("解析url错误:\r\n%v", err)
+		return nil, err
+	}
+	//如果参数中有中文参数,这个方法会进行URLEncode
+	Url.RawQuery = param.Encode()
+	resp, err := http.Get(Url.String())
+	if err != nil {
+		fmt.Println("err:", err)
+		return nil, err
+	}
+	defer resp.Body.Close()
+	return ioutil.ReadAll(resp.Body)
+}
+
+// SendSmsCodeGj 发送国际短信
+func SendSmsCodeGj(mobile, vCode, areaNum string) bool {
+	flag := false
+	result, err := sendSmsGj(mobile, vCode, areaNum)
+	if err != nil {
+		fmt.Println("发送短信失败")
+		return false
+	}
+	fmt.Println("result", string(result))
+	var netReturn map[string]interface{}
+	err = json.Unmarshal(result, &netReturn)
+	if err != nil {
+		//go SendEmail("短信验证码发送失败", "err:"+err.Error()+" result"+string(result), utils.EmailSendToUsers)
+		go alarm_msg.SendAlarmMsg("短信验证码发送失败, Err:"+err.Error()+";Result:"+string(result), 2)
+		flag = false
+	}
+	if netReturn["error_code"].(float64) == 0 {
+		fmt.Printf("接口返回result字段是:\r\n%v", netReturn["result"])
+		flag = true
+	} else {
+		// 忽略错误的手机号码这种错误
+		if netReturn["error_code"].(float64) != 205401 {
+			go alarm_msg.SendAlarmMsg("短信验证码发送失败, Result:"+string(result), 2)
+		}
+		flag = false
+	}
+	return flag
+}
+
+// sendSmsGj 发送国际短信
+func sendSmsGj(mobile, code, areaNum string) (rs []byte, err error) {
+	var Url *url.URL
+	apiURL := "http://v.juhe.cn/smsInternational/send.php"
+	//初始化参数
+	param := url.Values{}
+	//配置请求参数,方法内部已处理urlencode问题,中文参数可以直接传参
+	param.Set("mobile", mobile)           //接受短信的用户手机号码
+	param.Set("tplId", "10054")           //您申请的短信模板ID,根据实际情况修改
+	param.Set("tplValue", "#code#="+code) //您设置的模板变量,根据实际情况
+	param.Set("key", utils.JhGjAppKey)    //应用APPKEY(应用详细页查询)
+	param.Set("areaNum", areaNum)         //应用APPKEY(应用详细页查询)
+
+	Url, err = url.Parse(apiURL)
+	if err != nil {
+		fmt.Printf("解析url错误:\r\n%v", err)
+		return nil, err
+	}
+	//如果参数中有中文参数,这个方法会进行URLEncode
+	Url.RawQuery = param.Encode()
+	resp, err := http.Get(Url.String())
+	if err != nil {
+		fmt.Println("err:", err)
+		return nil, err
+	}
+	defer resp.Body.Close()
+	return ioutil.ReadAll(resp.Body)
+}

+ 9 - 0
utils/constants.go

@@ -44,3 +44,12 @@ const (
 	HRSYSTEM_LOGIN_TOKEN_NO_TRUST = "hrSystem:login:no_trust:"        //管理后台登录(不可信登录态)
 	HRSYSTEM_LOGIN_ADMINID_IP = "hrSystem:login:admin_id:"
 )
+
+// 聚合短信
+var (
+	JhGnTplId = "65692" //聚合国内模板编码
+	JhGjTplId = "10054" //聚合国内模板编码
+
+	JhGnAppKey = "4c8504c49dd335e99cfd7b6a3a9e2415" //聚合国内AppKey
+	JhGjAppKey = "3326ad2c1047a4cd92ace153e6044ca3"
+)