注册
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,4 +13,5 @@
|
|||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
# Dependency directories (remove the comment below to include it)
|
||||||
# vendor/
|
# vendor/
|
||||||
*.idea
|
*.idea
|
||||||
|
*.log
|
||||||
@@ -1,7 +1,93 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import "git.rosy.net.cn/jx-print/globals"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"git.rosy.net.cn/jx-print/globals"
|
||||||
|
"git.rosy.net.cn/jx-print/model"
|
||||||
|
"github.com/dchest/captcha"
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
type CallBack struct {
|
||||||
|
Data string `json:"data"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
globals.SugarLogger.Debugf("test init ...")
|
globals.SugarLogger.Debugf("test init ...")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func callFunc(c *gin.Context, worker func() (retVal interface{}, errCode string, err error)) bool {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
callBack = &CallBack{
|
||||||
|
Code: model.ErrCodeNormal,
|
||||||
|
}
|
||||||
|
token string
|
||||||
|
cookie *http.Cookie
|
||||||
|
result interface{}
|
||||||
|
)
|
||||||
|
//验证token
|
||||||
|
//v2下的接口需要验证,v1不需要
|
||||||
|
if !strings.Contains(c.Request.URL.String(), "v1") {
|
||||||
|
if cookie, err = c.Request.Cookie("token"); err != nil {
|
||||||
|
callBack.Desc = err.Error()
|
||||||
|
c.JSON(http.StatusOK, callBack)
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
token = cookie.Value
|
||||||
|
}
|
||||||
|
if token != "token" {
|
||||||
|
err = fmt.Errorf("token 已过期,请重新登录!")
|
||||||
|
callBack.Desc = err.Error()
|
||||||
|
c.JSON(http.StatusOK, callBack)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if result, _, err = worker(); err == nil {
|
||||||
|
if result != nil {
|
||||||
|
if data, err := json.Marshal(&result); err == nil {
|
||||||
|
callBack.Code = model.ErrCodeSuccess
|
||||||
|
callBack.Data = string(data)
|
||||||
|
c.JSON(http.StatusOK, callBack)
|
||||||
|
globals.SugarLogger.Debugf("End API :%s success", c.Request.URL)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("data error!")
|
||||||
|
callBack.Desc = err.Error()
|
||||||
|
c.JSON(http.StatusOK, callBack)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callBack.Code = model.ErrCodeSuccess
|
||||||
|
c.JSON(http.StatusOK, callBack)
|
||||||
|
globals.SugarLogger.Debugf("End API :%s success", c.Request.URL)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callBack.Desc = err.Error()
|
||||||
|
c.JSON(http.StatusOK, callBack)
|
||||||
|
globals.SugarLogger.Debugf("End API :%s error:%v", c.Request.URL, err)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func captchaVerify(c *gin.Context, code string) bool {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
if captchaId := session.Get(c.ClientIP() + model.SessionKey); captchaId != nil {
|
||||||
|
session.Delete(c.ClientIP() + model.SessionKey)
|
||||||
|
_ = session.Save()
|
||||||
|
if captcha.VerifyString(captchaId.(string), code) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,120 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.rosy.net.cn/jx-print/globals"
|
||||||
|
"git.rosy.net.cn/jx-print/model"
|
||||||
|
"git.rosy.net.cn/jx-print/services"
|
||||||
"git.rosy.net.cn/jx-print/utils"
|
"git.rosy.net.cn/jx-print/utils"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RefreshCode(c *gin.Context){
|
//刷新验证码 POST
|
||||||
utils.Captcha(c,4)
|
func RefreshCode(c *gin.Context) {
|
||||||
|
utils.Captcha(c, 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetUsersParam struct {
|
||||||
|
Name string `json:"name" uri:"name"` //用户名
|
||||||
|
UserID string `json:"user_id" uri:"user_id"` //用户名
|
||||||
|
Mobile string `json:"mobile" uri:"mobile"` //用户名
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询用户 GET
|
||||||
|
func GetUsers(c *gin.Context) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
user = &GetUsersParam{}
|
||||||
|
)
|
||||||
|
globals.SugarLogger.Debugf("Begin API :%s params: %v ip: %s", c.Request.URL, c.Params, c.ClientIP())
|
||||||
|
if err = c.ShouldBindUri(&user); err != nil {
|
||||||
|
c.JSON(http.StatusOK, &CallBack{
|
||||||
|
Code: model.ErrCodeNormal,
|
||||||
|
Desc: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !callFunc(c, func() (retVal interface{}, errCode string, err error) {
|
||||||
|
retVal, err = services.GetUsers(c, user.UserID, user.Name, user.Mobile)
|
||||||
|
return retVal, "", err
|
||||||
|
}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterUserParam struct {
|
||||||
|
Name string `json:"name" form:"name" binding:"required"` //用户名
|
||||||
|
Password string `json:"password" form:"password" binding:"required"` //密码,md5后的
|
||||||
|
Code string `json:"code" form:"code" binding:"required"` //验证码
|
||||||
|
}
|
||||||
|
|
||||||
|
//注册 POST
|
||||||
|
func RegisterUser(c *gin.Context) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
user = &RegisterUserParam{}
|
||||||
|
)
|
||||||
|
globals.SugarLogger.Debugf("Begin API :%s params: %v ip: %s", c.Request.URL, c.Params, c.ClientIP())
|
||||||
|
if err = c.Bind(&user); err != nil {
|
||||||
|
c.JSON(http.StatusOK, &CallBack{
|
||||||
|
Code: model.ErrCodeNormal,
|
||||||
|
Desc: err.Error(),
|
||||||
|
})
|
||||||
|
globals.SugarLogger.Debugf("End API :%s error:%v:", c.Request.URL, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !captchaVerify(c, user.Code) {
|
||||||
|
c.JSON(http.StatusOK, &CallBack{
|
||||||
|
Code: model.ErrCodeNormal,
|
||||||
|
Desc: "验证码错误!",
|
||||||
|
})
|
||||||
|
globals.SugarLogger.Debugf("End API :%s error:%v:", c.Request.URL, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !callFunc(c, func() (retVal interface{}, errCode string, err error) {
|
||||||
|
err = services.RegisterUser(c, user.Name, user.Password)
|
||||||
|
return retVal, "", err
|
||||||
|
}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginParam struct {
|
||||||
|
Name string `json:"name" form:"name" binding:"required"` //用户名
|
||||||
|
Password string `json:"password" form:"password" binding:"required"` //密码,md5后的
|
||||||
|
Code string `json:"code" form:"code" binding:"required"` //验证码
|
||||||
|
}
|
||||||
|
|
||||||
|
//登录 POST
|
||||||
|
func Login(c *gin.Context) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
user = &LoginParam{}
|
||||||
|
)
|
||||||
|
globals.SugarLogger.Debugf("Begin API :%s params: %v ip: %s", c.Request.URL, c.Params, c.ClientIP())
|
||||||
|
if err = c.Bind(&user); err != nil {
|
||||||
|
c.JSON(http.StatusOK, &CallBack{
|
||||||
|
Code: model.ErrCodeNormal,
|
||||||
|
Desc: err.Error(),
|
||||||
|
})
|
||||||
|
globals.SugarLogger.Debugf("End API :%s error:%v:", c.Request.URL, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !captchaVerify(c, user.Code) {
|
||||||
|
c.JSON(http.StatusOK, &CallBack{
|
||||||
|
Code: model.ErrCodeNormal,
|
||||||
|
Desc: "验证码错误!",
|
||||||
|
})
|
||||||
|
globals.SugarLogger.Debugf("End API :%s error:%v:", c.Request.URL, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !callFunc(c, func() (retVal interface{}, errCode string, err error) {
|
||||||
|
retVal, err = services.Login(c, user.Name, user.Password, user.Code)
|
||||||
|
return retVal, "", err
|
||||||
|
}) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
52
dao/dao.go
Normal file
52
dao/dao.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
putils "git.rosy.net.cn/jx-print/utils"
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Insert(db *sqlx.DB, obj interface{}) (err error) {
|
||||||
|
var (
|
||||||
|
value = reflect.ValueOf(obj)
|
||||||
|
stype = reflect.TypeOf(obj)
|
||||||
|
sname = stype.Name()
|
||||||
|
sql, values = strings.Builder{}, strings.Builder{}
|
||||||
|
sqlParams = []interface{}{}
|
||||||
|
direct reflect.Value
|
||||||
|
)
|
||||||
|
if stype.Kind() != reflect.Struct {
|
||||||
|
direct = reflect.Indirect(value)
|
||||||
|
} else {
|
||||||
|
direct = value
|
||||||
|
}
|
||||||
|
sql.WriteString("INSERT INTO ")
|
||||||
|
for i := 0; i < stype.NumField()-1; i++ {
|
||||||
|
if stype.Field(i).Type.String() == "*time.Time" {
|
||||||
|
if direct.Field(i).Interface().(*time.Time) != nil {
|
||||||
|
values.WriteString(stype.Field(i).Tag.Get("json") + ",")
|
||||||
|
sqlParams = append(sqlParams, direct.Field(i).Interface())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !direct.Field(i).IsZero() {
|
||||||
|
values.WriteString(stype.Field(i).Tag.Get("json") + ",")
|
||||||
|
sqlParams = append(sqlParams, direct.Field(i).Interface())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sql.WriteString(putils.UnMarshalHr(sname) + "(")
|
||||||
|
sql.WriteString(values.String()[:len(values.String())-1])
|
||||||
|
sql.WriteString(") VALUES(")
|
||||||
|
for i := 0; i < len(strings.Split(values.String(), ","))-1; i++ {
|
||||||
|
if i != 0 {
|
||||||
|
sql.WriteString(",")
|
||||||
|
}
|
||||||
|
sql.WriteString("?")
|
||||||
|
}
|
||||||
|
sql.WriteString(")")
|
||||||
|
_, err = db.DB.Exec(sql.String(), sqlParams...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
31
dao/user_dao.go
Normal file
31
dao/user_dao.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.rosy.net.cn/jx-print/model"
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUsers(db *sqlx.DB, userID, name, mobile string) (users []*model.User, err error) {
|
||||||
|
var sqlParams []interface{}
|
||||||
|
sql := `
|
||||||
|
SELECT *
|
||||||
|
FROM user
|
||||||
|
WHERE 1 = 1
|
||||||
|
`
|
||||||
|
if name != "" {
|
||||||
|
sql += " AND name LIKE ?"
|
||||||
|
sqlParams = append(sqlParams, "%"+name+"%")
|
||||||
|
}
|
||||||
|
if userID != "" {
|
||||||
|
sql += " AND user_id = ?"
|
||||||
|
sqlParams = append(sqlParams, userID)
|
||||||
|
}
|
||||||
|
if mobile != "" {
|
||||||
|
sql += " AND mobile = ?"
|
||||||
|
sqlParams = append(sqlParams, mobile)
|
||||||
|
}
|
||||||
|
if err = db.Select(&users, sql, sqlParams...); err == nil {
|
||||||
|
return users, err
|
||||||
|
}
|
||||||
|
return users, err
|
||||||
|
}
|
||||||
@@ -1,23 +1,27 @@
|
|||||||
package globals
|
package globals
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
SugarLogger *zap.SugaredLogger
|
SugarLogger *zap.SugaredLogger
|
||||||
db *sql.DB
|
db *sqlx.DB
|
||||||
)
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
logger, _ := zap.NewDevelopment()
|
logger, _ := zap.NewDevelopment()
|
||||||
SugarLogger = logger.Sugar()
|
SugarLogger = logger.Sugar()
|
||||||
|
sqlStr :="root:WebServer@1@tcp(127.0.0.1:3306)/api?charset=utf8mb4&loc=Local&parseTime=true"
|
||||||
|
db, err = sqlx.Connect("mysql", sqlStr)
|
||||||
|
if err != nil {
|
||||||
|
SugarLogger.Debugf("加载数据库失败!err :%v",err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//parseTime:时间格式转换(查询结果为时间时,是否自动解析为时间);
|
func GetDB()*sqlx.DB{
|
||||||
|
return db
|
||||||
// loc=Local:MySQL的时区设置
|
|
||||||
|
|
||||||
sqlStr := "root:123456@tcp(127.0.0.1:3306)/testdb?charset=utf8&parseTime=true&loc=Local"
|
|
||||||
db, _ = sql.Open("mysql", sqlStr)
|
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,33 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SessionKey = "jxCode"
|
SessionKey = "jxCode"
|
||||||
|
RegisterKey = "jxRegister"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ErrCodeSuccess = "0"
|
||||||
|
ErrCodeNormal = "-1"
|
||||||
|
|
||||||
|
ErrCodeToken = "-1000"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FieldDeletedAt = "deleted_at"
|
||||||
|
FieldCreatedAt = "created_at"
|
||||||
|
FieldUpdatedAt = "updated_at"
|
||||||
|
FieldLastOperator = "last_operator"
|
||||||
|
FieldID = "id"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ModelIDCULD struct {
|
type ModelIDCULD struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id" db:"id"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt *time.Time `json:"created_at" db:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt *time.Time `json:"updated_at" db:"updated_at"`
|
||||||
LastOperator string `json:"last_operator"`
|
LastOperator string `json:"last_operator" db:"last_operator"`
|
||||||
DeletedAt time.Time `json:"deleted_at"`
|
DeletedAt *time.Time `json:"deleted_at" db:"deleted_at"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,32 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
ID int `json:"id" db:"id"`
|
||||||
|
CreatedAt *time.Time `json:"created_at" db:"created_at"`
|
||||||
|
UpdatedAt *time.Time `json:"updated_at" db:"updated_at"`
|
||||||
|
LastOperator string `json:"last_operator" db:"last_operator"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_at" db:"deleted_at"`
|
||||||
|
UserID string `json:"user_id" db:"user_id"` // 内部唯一标识
|
||||||
|
Password string `json:"password"` //密码
|
||||||
|
Name string `json:"name"` // 外部显示标识(当前可以重复)
|
||||||
|
Mobile string `json:"mobile"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Avatar string `json:"avatar"` // 头像
|
||||||
|
Status int8 `json:"status"`
|
||||||
|
Type int8 `json:"type"` // 用户类型
|
||||||
|
Company string `json:"company"` //公司名称
|
||||||
|
CityCode int `json:"city_code" db:"city_code"`
|
||||||
|
DistrictCode int `json:"district_code" db:"district_code"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
|
||||||
|
IDCardNo string `json:"id_card_no" db:"id_card_no"` // 身份证号
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
|
||||||
|
LastLoginAt *time.Time `json:"last_login_at" db:"last_login_at"`
|
||||||
|
LastLoginIP string `json:"last_login_ip" db:"last_login_ip"`
|
||||||
|
LastLoginType string `json:"last_login_type" db:"last_login_type"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,9 +5,16 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init(r *gin.Engine){
|
func Init(r *gin.Engine) {
|
||||||
v2 := r.Group("/v2")
|
v2 := r.Group("/v2")
|
||||||
//user
|
//user
|
||||||
user := v2.Group("/user")
|
user := v2.Group("/user")
|
||||||
user.POST("/refreshCode",controllers.RefreshCode)
|
user.GET("/getUsers", controllers.GetUsers)
|
||||||
}
|
|
||||||
|
//v1是不需要token的
|
||||||
|
v1 := r.Group("v1")
|
||||||
|
userw := v1.Group("/user")
|
||||||
|
user.GET("/login", controllers.Login)
|
||||||
|
userw.GET("/refreshCode", controllers.RefreshCode)
|
||||||
|
userw.GET("/register", controllers.RegisterUser)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,2 +1,43 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-print/dao"
|
||||||
|
"git.rosy.net.cn/jx-print/globals"
|
||||||
|
"git.rosy.net.cn/jx-print/model"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUsers(c *gin.Context, name, mobile, userID string) (users []*model.User, err error) {
|
||||||
|
return dao.GetUsers(globals.GetDB(), userID, name, mobile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterUser(c *gin.Context, name, password string) (err error) {
|
||||||
|
var (
|
||||||
|
db = globals.GetDB()
|
||||||
|
user = model.User{}
|
||||||
|
now = time.Now()
|
||||||
|
)
|
||||||
|
if users, _ := dao.GetUsers(db, "", name, ""); len(users) > 0 {
|
||||||
|
return fmt.Errorf("用户名重复!")
|
||||||
|
}
|
||||||
|
user.UserID = utils.GetUUID()
|
||||||
|
user.Name = name
|
||||||
|
user.Password = fmt.Sprintf("%x", md5.Sum([]byte(model.RegisterKey+password)))
|
||||||
|
user.CreatedAt = &now
|
||||||
|
user.UpdatedAt = &now
|
||||||
|
user.DeletedAt = &utils.DefaultTimeValue
|
||||||
|
err = dao.Insert(db, user)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Login(c *gin.Context, name, password, code string) (user *model.User, err error) {
|
||||||
|
//var (
|
||||||
|
// db = globals.GetDB()
|
||||||
|
//)
|
||||||
|
|
||||||
|
return user, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,9 +7,25 @@ import (
|
|||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var commonInitialisms = []string{"ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS"}
|
||||||
|
var commonInitialismsReplacer *strings.Replacer
|
||||||
|
var uncommonInitialismsReplacer *strings.Replacer
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var commonInitialismsForReplacer []string
|
||||||
|
var uncommonInitialismsForReplacer []string
|
||||||
|
for _, initialism := range commonInitialisms {
|
||||||
|
commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism)))
|
||||||
|
uncommonInitialismsForReplacer = append(uncommonInitialismsForReplacer, strings.Title(strings.ToLower(initialism)), initialism)
|
||||||
|
}
|
||||||
|
commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...)
|
||||||
|
uncommonInitialismsReplacer = strings.NewReplacer(uncommonInitialismsForReplacer...)
|
||||||
|
}
|
||||||
|
|
||||||
func Captcha(c *gin.Context, length ...int) {
|
func Captcha(c *gin.Context, length ...int) {
|
||||||
l := captcha.DefaultLen
|
l := captcha.DefaultLen
|
||||||
w, h := 107, 36
|
w, h := 107, 36
|
||||||
@@ -24,25 +40,11 @@ func Captcha(c *gin.Context, length ...int) {
|
|||||||
}
|
}
|
||||||
captchaId := captcha.NewLen(l)
|
captchaId := captcha.NewLen(l)
|
||||||
session := sessions.Default(c)
|
session := sessions.Default(c)
|
||||||
session.Set(model.SessionKey, captchaId)
|
session.Set(c.ClientIP()+model.SessionKey, captchaId)
|
||||||
_ = session.Save()
|
_ = session.Save()
|
||||||
_ = Serve(c.Writer, c.Request, captchaId, ".png", "zh", false, w, h)
|
_ = Serve(c.Writer, c.Request, captchaId, ".png", "zh", false, w, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CaptchaVerify(c *gin.Context, code string) bool {
|
|
||||||
session := sessions.Default(c)
|
|
||||||
if captchaId := session.Get(model.SessionKey); captchaId != nil {
|
|
||||||
session.Delete(model.SessionKey)
|
|
||||||
_ = session.Save()
|
|
||||||
if captcha.VerifyString(captchaId.(string), code) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func Serve(w http.ResponseWriter, r *http.Request, id, ext, lang string, download bool, width, height int) error {
|
func Serve(w http.ResponseWriter, r *http.Request, id, ext, lang string, download bool, width, height int) error {
|
||||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
w.Header().Set("Pragma", "no-cache")
|
w.Header().Set("Pragma", "no-cache")
|
||||||
@@ -65,4 +67,55 @@ func Serve(w http.ResponseWriter, r *http.Request, id, ext, lang string, downloa
|
|||||||
}
|
}
|
||||||
http.ServeContent(w, r, id+ext, time.Time{}, bytes.NewReader(content.Bytes()))
|
http.ServeContent(w, r, id+ext, time.Time{}, bytes.NewReader(content.Bytes()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//驼峰转下划线
|
||||||
|
func UnMarshalHr(name string) string {
|
||||||
|
const (
|
||||||
|
lower = false
|
||||||
|
upper = true
|
||||||
|
)
|
||||||
|
|
||||||
|
if name == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
value = commonInitialismsReplacer.Replace(name)
|
||||||
|
buf = bytes.NewBufferString("")
|
||||||
|
lastCase, currCase, nextCase, nextNumber bool
|
||||||
|
)
|
||||||
|
|
||||||
|
for i, v := range value[:len(value)-1] {
|
||||||
|
nextCase = bool(value[i+1] >= 'A' && value[i+1] <= 'Z')
|
||||||
|
nextNumber = bool(value[i+1] >= '0' && value[i+1] <= '9')
|
||||||
|
|
||||||
|
if i > 0 {
|
||||||
|
if currCase == upper {
|
||||||
|
if lastCase == upper && (nextCase == upper || nextNumber == upper) {
|
||||||
|
buf.WriteRune(v)
|
||||||
|
} else {
|
||||||
|
if value[i-1] != '_' && value[i+1] != '_' {
|
||||||
|
buf.WriteRune('_')
|
||||||
|
}
|
||||||
|
buf.WriteRune(v)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf.WriteRune(v)
|
||||||
|
if i == len(value)-2 && (nextCase == upper && nextNumber == lower) {
|
||||||
|
buf.WriteRune('_')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currCase = upper
|
||||||
|
buf.WriteRune(v)
|
||||||
|
}
|
||||||
|
lastCase = currCase
|
||||||
|
currCase = nextCase
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteByte(value[len(value)-1])
|
||||||
|
|
||||||
|
s := strings.ToLower(buf.String())
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user