diff --git a/API/AccessLog.go b/API/AccessLog.go
index 3b2cccc..7b88675 100644
--- a/API/AccessLog.go
+++ b/API/AccessLog.go
@@ -33,10 +33,12 @@ func AccessLog(c *gin.Context) {
DateTime, _ := strconv.ParseInt(c.PostForm("DateTime"), 0, 64)
+ TypeNum, _ := strconv.ParseInt("TypeNum", 0, 64)
+
DB.CAccessLog.Insert(DB.SAccessLog{
c.PostForm("UserId"),
c.PostForm("UserName"),
- c.PostForm("TypeNum"),
+ TypeNum,
c.PostForm("TypeName"),
DateTime,
Location,
diff --git a/API/Sms.go b/API/Sms.go
new file mode 100644
index 0000000..1cdb005
--- /dev/null
+++ b/API/Sms.go
@@ -0,0 +1,106 @@
+package Api
+
+import (
+ "encoding/json"
+ "github.com/aarongao/tools"
+ "github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
+ "github.com/gin-gonic/gin"
+ "letu/DB"
+ "letu/Lib"
+ "time"
+)
+
+// @Title 发送短信验证码
+// @Description 发送短信验证码
+// @Accept json
+// @Produce json
+// @Param mobile 18616619599 string true "手机号"
+// @Param Location {"Latitude": 119, "Longitude": 39} string true "位置"
+// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}验证码3分钟内有效"
+// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
+// @Router /Sms/Send? [post]
+func Send(c *gin.Context) {
+ c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
+ c.Header("Access-Control-Allow-Credentials", "true")
+
+ if c.PostForm("Mobile") == "" {
+ c.JSON(200, tools.ResponseError{
+ 1,
+ "手机号不正确",
+ })
+ return
+ }
+ if c.PostForm("Location") == "" {
+ c.JSON(200, tools.ResponseError{
+ 1,
+ "缺少位置信息",
+ })
+ return
+ }
+
+ cacheCode := DB.Redis.Get(c.PostForm("Mobile"))
+ if cacheCode != nil {
+ c.JSON(200, tools.ResponseError{
+ 1,
+ "code没有过期",
+ })
+ return
+ }
+
+ code := Lib.SmsCode(6)
+
+ client, err := dysmsapi.NewClientWithAccessKey("cn-hangzhou", "LTAI4FdQeNMQXRU6u5J3EFQc", "PwvyF5rRNBWLDya41WrCpvENevYZGi")
+
+ request := dysmsapi.CreateSendSmsRequest()
+ request.Scheme = "https"
+
+ request.PhoneNumbers = c.PostForm("Mobile")
+ request.SignName = "乐游图"
+ request.TemplateCode = "SMS_182595013"
+ request.TemplateParam = "{\"code\":\"" + string(code) + "\"}"
+
+ response, err := client.SendSms(request)
+ var reserr string
+ if err != nil {
+ println(err.Error())
+ reserr = err.Error()
+ } else {
+ reserr = ""
+ DB.Redis.Set(c.PostForm("Mobile"), code, time.Second*60*3)
+ }
+
+ var Location DB.SLocation
+ json.Unmarshal([]byte(c.PostForm("Location")), &Location)
+
+ //go func(res *dysmsapi.SendSmsResponse) {
+ DB.CActionLog.Insert(DB.SActionLog{
+ "",
+ "",
+ c.PostForm("Mobile"),
+ 1,
+ "注册验证码",
+ time.Now().Unix(),
+ Location,
+ string(code),
+ reserr,
+ })
+ //}(response)
+
+ if response.Code == "OK" {
+
+ c.JSON(200, tools.ResponseSeccess{
+ 0,
+ "ok",
+ })
+ } else {
+
+ c.JSON(200, tools.ResponseSeccess{
+ 1,
+ "验证码发送失败",
+ })
+ }
+}
+
+func CreateAccessLog() {
+
+}
diff --git a/API/User.go b/API/User.go
index 75600f8..427133e 100644
--- a/API/User.go
+++ b/API/User.go
@@ -19,6 +19,7 @@ import (
// @Param confirmpassword 1 string true "确认密码"
// @Param birthday 2010.10.10 string true "生日"
// @Param fullname aarongao string true "全名"
+// @Param code 12345678 string true "6位验证码"
// @Param mobile 18616619599 string true "手机,同用户名"
// @Param openid 12345 string true "微信id"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
@@ -28,7 +29,14 @@ func CreateUser(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
- if c.PostForm("mobile") == "" || c.PostForm("password") != c.PostForm("confirmpassword") {
+ if c.PostForm("mobile") == "" {
+ c.JSON(200, tools.ResponseError{
+ 1,
+ "必须有手机号",
+ })
+ return
+ }
+ if c.PostForm("password") != c.PostForm("confirmpassword") {
c.JSON(200, tools.ResponseError{
1,
"密码错误",
@@ -36,8 +44,18 @@ func CreateUser(c *gin.Context) {
return
}
+ // 检查验证码
+ code := DB.Redis.Get(c.PostForm("mobile"))
+ if code == "" || code != c.PostForm("code") {
+ c.JSON(200, tools.ResponseError{
+ 1,
+ "验证码错误",
+ })
+ return
+ }
+
objectID := bson.NewObjectId()
- DB.CMember.Insert(DB.SMember{
+ err := DB.CMember.Insert(DB.SMember{
&objectID,
c.PostForm("password"),
c.PostForm("birthday"),
@@ -46,11 +64,18 @@ func CreateUser(c *gin.Context) {
c.PostForm("openid"),
"",
})
+ if err == nil{
+ c.JSON(200, tools.ResponseSeccess{
+ 0,
+ "ok",
+ })
+ }else{
+ c.JSON(200, tools.ResponseError{
+ 0,
+ "此手机号已经注册",
+ })
+ }
- c.JSON(200, tools.ResponseSeccess{
- 0,
- "ok",
- })
}
@@ -104,8 +129,6 @@ func LoginUser(c *gin.Context) {
}
-
-
// @Title 用户信息
// @Description 获取用户信息
// @Accept json
@@ -118,7 +141,7 @@ func UserInfo(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
- if c.Query("id") == ""{
+ if c.Query("id") == "" {
c.JSON(200, tools.ResponseError{
1,
"空",
@@ -137,7 +160,6 @@ func UserInfo(c *gin.Context) {
})
} else {
-
c.JSON(200, tools.ResponseSeccess{
0,
User,
diff --git a/Config/config.go b/Config/config.go
index 3eda95e..ff60bfa 100644
--- a/Config/config.go
+++ b/Config/config.go
@@ -1,7 +1,7 @@
package Config
type Config struct {
- TagType []string
- DbPath string
+ TagType []string
+ DbPath string
+ RedisPath string
}
-
diff --git a/Config/config.json b/Config/config.json
index 60303a8..47c9d38 100644
--- a/Config/config.json
+++ b/Config/config.json
@@ -1,4 +1,5 @@
{
"tagType": ["menu","normal"],
- "dbPath": "127.0.0.1:27017"
+ "dbPath": "127.0.0.1:27017",
+ "redisPath": "127.0.0.1:6379"
}
diff --git a/DB/db.go b/DB/db.go
index 4e7b6bf..565a8a9 100644
--- a/DB/db.go
+++ b/DB/db.go
@@ -3,8 +3,11 @@ package DB
import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
+ "letu/Lib/Cache"
)
+var Redis *Cache.Redis
+
var DBSession *mgo.Session
var CItem *mgo.Collection //所有游玩项目内容
var CComplaint *mgo.Collection //投诉
@@ -15,6 +18,7 @@ var CTags *mgo.Collection //标签
var CScenic *mgo.Collection //景区
var CLine *mgo.Collection //推荐线路
var CAccessLog *mgo.Collection //访问记录
+var CActionLog *mgo.Collection //行为记录
var DB *mgo.Database
type SItem struct {
@@ -41,12 +45,23 @@ type SLocation struct {
type SAccessLog struct {
UserId string `bson:"UserId" json:"UserId"` // 用户ID
UserName string `bson:"UserName" json:"UserName"` //用户名称
- TypeNum string `bson:"TypeNum" json:"TypeNum"` //类型编号
+ TypeNum int64 `bson:"TypeNum" json:"TypeNum"` //类型编号
TypeName string `bson:"TypeName" json:"TypeName"` //类型名称
DateTime int64 `bson:"DateTime" json:"DateTime"` //时间戳
Location SLocation `bson:"Location" json:"Location"` //位置
Remarks string `bson:"Remarks" json:"Remarks"` //备注
}
+type SActionLog struct {
+ UserId string `bson:"UserId" json:"UserId"` // 用户ID
+ UserName string `bson:"UserName" json:"UserName"` //用户名称
+ Mobile string `bson:"Mobile" json:"Mobile"` //手机号
+ TypeNum int64 `bson:"TypeNum" json:"TypeNum"` //类型编号
+ TypeName string `bson:"TypeName" json:"TypeName"` //类型名称
+ DateTime int64 `bson:"DateTime" json:"DateTime"` //时间戳
+ Location SLocation `bson:"Location" json:"Location"` //位置
+ Content string `bson:"Content" json:"Content"` //内容
+ Error interface{} `bson:"Error" json:"Error"` //错误信息
+}
type SCommodity struct {
Id *bson.ObjectId `bson:"_id" json:"Id" valid:"required"`
Name string `bson:"Name" json:"Name"`
diff --git a/Lib/Cache/redis.go b/Lib/Cache/redis.go
new file mode 100644
index 0000000..1f93806
--- /dev/null
+++ b/Lib/Cache/redis.go
@@ -0,0 +1,103 @@
+package Cache
+
+import (
+ "encoding/json"
+ "github.com/garyburd/redigo/redis"
+ "time"
+)
+
+//Redis redis cache
+type Redis struct {
+ conn *redis.Pool
+}
+
+//RedisOpts redis 连接属性
+type RedisOpts struct {
+ Host string `yml:"host" json:"host"`
+ Password string `yml:"password" json:"password"`
+ Database int `yml:"database" json:"database"`
+ MaxIdle int `yml:"max_idle" json:"max_idle"`
+ MaxActive int `yml:"max_active" json:"max_active"`
+ IdleTimeout int32 `yml:"idle_timeout" json:"idle_timeout"` //second
+}
+
+//NewRedis 实例化
+func NewRedis(opts *RedisOpts) *Redis {
+ pool := &redis.Pool{
+ MaxActive: opts.MaxActive,
+ MaxIdle: opts.MaxIdle,
+ IdleTimeout: time.Second * time.Duration(opts.IdleTimeout),
+ Dial: func() (redis.Conn, error) {
+ return redis.Dial("tcp", opts.Host,
+ redis.DialDatabase(opts.Database),
+ redis.DialPassword(opts.Password),
+ )
+ },
+ TestOnBorrow: func(conn redis.Conn, t time.Time) error {
+ if time.Since(t) < time.Minute {
+ return nil
+ }
+ _, err := conn.Do("PING")
+ return err
+ },
+ }
+ return &Redis{pool}
+}
+
+//Get 获取一个值
+func (r *Redis) Get(key string) interface{} {
+ conn := r.conn.Get()
+ defer conn.Close()
+
+ var data []byte
+ var err error
+ if data, err = redis.Bytes(conn.Do("GET", key)); err != nil {
+ return nil
+ }
+ var reply interface{}
+ if err = json.Unmarshal(data, &reply); err != nil {
+ return nil
+ }
+
+ return reply
+}
+
+//Set 设置一个值
+func (r *Redis) Set(key string, val interface{}, timeout time.Duration) (err error) {
+ conn := r.conn.Get()
+ defer conn.Close()
+
+ var data []byte
+ if data, err = json.Marshal(val); err != nil {
+ return
+ }
+
+ _, err = conn.Do("SETEX", key, int64(timeout/time.Second), data)
+
+ return
+}
+
+//IsExist 判断key是否存在
+func (r *Redis) IsExist(key string) bool {
+ conn := r.conn.Get()
+ defer conn.Close()
+
+ a, _ := conn.Do("EXISTS", key)
+ i := a.(int64)
+ if i > 0 {
+ return true
+ }
+ return false
+}
+
+//Delete 删除
+func (r *Redis) Delete(key string) error {
+ conn := r.conn.Get()
+ defer conn.Close()
+
+ if _, err := conn.Do("DEL", key); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/Lib/Code.go b/Lib/Code.go
new file mode 100644
index 0000000..3fd231f
--- /dev/null
+++ b/Lib/Code.go
@@ -0,0 +1,21 @@
+package Lib
+
+import (
+ "fmt"
+ "math/rand"
+ "strings"
+ "time"
+)
+
+
+func SmsCode(width int) string {
+ numeric := [10]byte{0,1,2,3,4,5,6,7,8,9}
+ r := len(numeric)
+ rand.Seed(time.Now().UnixNano())
+
+ var sb strings.Builder
+ for i := 0; i < width; i++ {
+ fmt.Fprintf(&sb, "%d", numeric[ rand.Intn(r) ])
+ }
+ return sb.String()
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 85eca55..f9bea89 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@
1. [查询线路信息](#lineinfo-get)
1. [用户登录](#loginuser-post)
1. [返回景区基础信息](#scenicinfo-get)
+1. [发送短信验证码](#sms/send-post)
1. [标签列表](#tags-get)
1. [更新商品](#updatecommodity-post)
1. [更新设施](#updateitem-post)
@@ -166,6 +167,7 @@
| confirmpassword | 1 | string | 确认密码 | Yes |
| birthday | 2010.10.10 | string | 生日 | Yes |
| fullname | aarongao | string | 全名 | Yes |
+| code | 12345678 | string | 6位验证码 | Yes |
| mobile | 18616619599 | string | 手机,同用户名 | Yes |
| openid | 12345 | string | 微信id | Yes |
@@ -254,6 +256,26 @@
+
+
+#### /Sms/Send (POST)
+
+
+发送短信验证码
+
+| Param Name | Example | Data Type | Description | Required? |
+|-----|-----|-----|-----|-----|
+| mobile | 18616619599 | string | 手机号 | Yes |
+| Location | {"Latitude": 119, "Longitude": 39} | string | 位置 | Yes |
+
+
+| Code | Type | Model | Message |
+|-----|-----|-----|-----|
+| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":"ok"}验证码3分钟内有效 |
+| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
+
+
+
#### /Tags (GET)
diff --git a/main.go b/main.go
index 301f28d..7548292 100644
--- a/main.go
+++ b/main.go
@@ -8,6 +8,7 @@ import (
"letu/Api"
"letu/Config"
"letu/DB"
+ "letu/Lib/Cache"
"letu/Lib/Ws"
"os"
)
@@ -30,6 +31,18 @@ func main() {
// 连接数据库
DB.DBSession, err = mgo.Dial(conf.DbPath)
defer DB.DBSession.Close()
+
+ // 连接redis
+ DB.Redis = Cache.NewRedis(&Cache.RedisOpts{
+ conf.RedisPath,
+ "",
+ 0,
+ 20,
+ 20,
+ 0,
+ })
+
+
//设置模式
DB.DBSession.SetMode(mgo.Monotonic, true)
//获取文档集
@@ -43,6 +56,7 @@ func main() {
DB.CScenic = DB.DB.C("Scenic")
DB.CLine = DB.DB.C("Line")
DB.CAccessLog = DB.DB.C("AccessLog")
+ DB.CActionLog = DB.DB.C("ActionLog")
r := gin.Default()
//r.Static("/.well-known", "./.well-known/")
@@ -69,6 +83,7 @@ func main() {
r.GET("/AllScenic", Api.AllScenic)
r.POST("/AccessLog", Api.AccessLog)
r.GET("/AccessLog", Api.AccessLog)
+ r.POST("/Sms/Send", Api.Send)
//r.GET("/ws", Api.WsPage)
r.Static("/Upload", "./Upload")
--
libgit2 0.21.0