Commit 128c8d273830ab5e05fdf28372e724f336bb8c40

Authored by aarongao
1 parent af56ff1d
Exists in v1.2 and in 2 other branches master, v1.1

upload

API/AccessLog.go
@@ -33,10 +33,12 @@ func AccessLog(c *gin.Context) { @@ -33,10 +33,12 @@ func AccessLog(c *gin.Context) {
33 33
34 DateTime, _ := strconv.ParseInt(c.PostForm("DateTime"), 0, 64) 34 DateTime, _ := strconv.ParseInt(c.PostForm("DateTime"), 0, 64)
35 35
  36 + TypeNum, _ := strconv.ParseInt("TypeNum", 0, 64)
  37 +
36 DB.CAccessLog.Insert(DB.SAccessLog{ 38 DB.CAccessLog.Insert(DB.SAccessLog{
37 c.PostForm("UserId"), 39 c.PostForm("UserId"),
38 c.PostForm("UserName"), 40 c.PostForm("UserName"),
39 - c.PostForm("TypeNum"), 41 + TypeNum,
40 c.PostForm("TypeName"), 42 c.PostForm("TypeName"),
41 DateTime, 43 DateTime,
42 Location, 44 Location,
API/Sms.go 0 → 100644
@@ -0,0 +1,106 @@ @@ -0,0 +1,106 @@
  1 +package Api
  2 +
  3 +import (
  4 + "encoding/json"
  5 + "github.com/aarongao/tools"
  6 + "github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
  7 + "github.com/gin-gonic/gin"
  8 + "letu/DB"
  9 + "letu/Lib"
  10 + "time"
  11 +)
  12 +
  13 +// @Title 发送短信验证码
  14 +// @Description 发送短信验证码
  15 +// @Accept json
  16 +// @Produce json
  17 +// @Param mobile 18616619599 string true "手机号"
  18 +// @Param Location {"Latitude": 119, "Longitude": 39} string true "位置"
  19 +// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}验证码3分钟内有效"
  20 +// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
  21 +// @Router /Sms/Send? [post]
  22 +func Send(c *gin.Context) {
  23 + c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
  24 + c.Header("Access-Control-Allow-Credentials", "true")
  25 +
  26 + if c.PostForm("Mobile") == "" {
  27 + c.JSON(200, tools.ResponseError{
  28 + 1,
  29 + "手机号不正确",
  30 + })
  31 + return
  32 + }
  33 + if c.PostForm("Location") == "" {
  34 + c.JSON(200, tools.ResponseError{
  35 + 1,
  36 + "缺少位置信息",
  37 + })
  38 + return
  39 + }
  40 +
  41 + cacheCode := DB.Redis.Get(c.PostForm("Mobile"))
  42 + if cacheCode != nil {
  43 + c.JSON(200, tools.ResponseError{
  44 + 1,
  45 + "code没有过期",
  46 + })
  47 + return
  48 + }
  49 +
  50 + code := Lib.SmsCode(6)
  51 +
  52 + client, err := dysmsapi.NewClientWithAccessKey("cn-hangzhou", "LTAI4FdQeNMQXRU6u5J3EFQc", "PwvyF5rRNBWLDya41WrCpvENevYZGi")
  53 +
  54 + request := dysmsapi.CreateSendSmsRequest()
  55 + request.Scheme = "https"
  56 +
  57 + request.PhoneNumbers = c.PostForm("Mobile")
  58 + request.SignName = "乐游图"
  59 + request.TemplateCode = "SMS_182595013"
  60 + request.TemplateParam = "{\"code\":\"" + string(code) + "\"}"
  61 +
  62 + response, err := client.SendSms(request)
  63 + var reserr string
  64 + if err != nil {
  65 + println(err.Error())
  66 + reserr = err.Error()
  67 + } else {
  68 + reserr = ""
  69 + DB.Redis.Set(c.PostForm("Mobile"), code, time.Second*60*3)
  70 + }
  71 +
  72 + var Location DB.SLocation
  73 + json.Unmarshal([]byte(c.PostForm("Location")), &Location)
  74 +
  75 + //go func(res *dysmsapi.SendSmsResponse) {
  76 + DB.CActionLog.Insert(DB.SActionLog{
  77 + "",
  78 + "",
  79 + c.PostForm("Mobile"),
  80 + 1,
  81 + "注册验证码",
  82 + time.Now().Unix(),
  83 + Location,
  84 + string(code),
  85 + reserr,
  86 + })
  87 + //}(response)
  88 +
  89 + if response.Code == "OK" {
  90 +
  91 + c.JSON(200, tools.ResponseSeccess{
  92 + 0,
  93 + "ok",
  94 + })
  95 + } else {
  96 +
  97 + c.JSON(200, tools.ResponseSeccess{
  98 + 1,
  99 + "验证码发送失败",
  100 + })
  101 + }
  102 +}
  103 +
  104 +func CreateAccessLog() {
  105 +
  106 +}
@@ -19,6 +19,7 @@ import ( @@ -19,6 +19,7 @@ import (
19 // @Param confirmpassword 1 string true "确认密码" 19 // @Param confirmpassword 1 string true "确认密码"
20 // @Param birthday 2010.10.10 string true "生日" 20 // @Param birthday 2010.10.10 string true "生日"
21 // @Param fullname aarongao string true "全名" 21 // @Param fullname aarongao string true "全名"
  22 +// @Param code 12345678 string true "6位验证码"
22 // @Param mobile 18616619599 string true "手机,同用户名" 23 // @Param mobile 18616619599 string true "手机,同用户名"
23 // @Param openid 12345 string true "微信id" 24 // @Param openid 12345 string true "微信id"
24 // @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}" 25 // @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
@@ -28,7 +29,14 @@ func CreateUser(c *gin.Context) { @@ -28,7 +29,14 @@ func CreateUser(c *gin.Context) {
28 c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin")) 29 c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
29 c.Header("Access-Control-Allow-Credentials", "true") 30 c.Header("Access-Control-Allow-Credentials", "true")
30 31
31 - if c.PostForm("mobile") == "" || c.PostForm("password") != c.PostForm("confirmpassword") { 32 + if c.PostForm("mobile") == "" {
  33 + c.JSON(200, tools.ResponseError{
  34 + 1,
  35 + "必须有手机号",
  36 + })
  37 + return
  38 + }
  39 + if c.PostForm("password") != c.PostForm("confirmpassword") {
32 c.JSON(200, tools.ResponseError{ 40 c.JSON(200, tools.ResponseError{
33 1, 41 1,
34 "密码错误", 42 "密码错误",
@@ -36,8 +44,18 @@ func CreateUser(c *gin.Context) { @@ -36,8 +44,18 @@ func CreateUser(c *gin.Context) {
36 return 44 return
37 } 45 }
38 46
  47 + // 检查验证码
  48 + code := DB.Redis.Get(c.PostForm("mobile"))
  49 + if code == "" || code != c.PostForm("code") {
  50 + c.JSON(200, tools.ResponseError{
  51 + 1,
  52 + "验证码错误",
  53 + })
  54 + return
  55 + }
  56 +
39 objectID := bson.NewObjectId() 57 objectID := bson.NewObjectId()
40 - DB.CMember.Insert(DB.SMember{ 58 + err := DB.CMember.Insert(DB.SMember{
41 &objectID, 59 &objectID,
42 c.PostForm("password"), 60 c.PostForm("password"),
43 c.PostForm("birthday"), 61 c.PostForm("birthday"),
@@ -46,11 +64,18 @@ func CreateUser(c *gin.Context) { @@ -46,11 +64,18 @@ func CreateUser(c *gin.Context) {
46 c.PostForm("openid"), 64 c.PostForm("openid"),
47 "", 65 "",
48 }) 66 })
  67 + if err == nil{
  68 + c.JSON(200, tools.ResponseSeccess{
  69 + 0,
  70 + "ok",
  71 + })
  72 + }else{
  73 + c.JSON(200, tools.ResponseError{
  74 + 0,
  75 + "此手机号已经注册",
  76 + })
  77 + }
49 78
50 - c.JSON(200, tools.ResponseSeccess{  
51 - 0,  
52 - "ok",  
53 - })  
54 79
55 } 80 }
56 81
@@ -104,8 +129,6 @@ func LoginUser(c *gin.Context) { @@ -104,8 +129,6 @@ func LoginUser(c *gin.Context) {
104 129
105 } 130 }
106 131
107 -  
108 -  
109 // @Title 用户信息 132 // @Title 用户信息
110 // @Description 获取用户信息 133 // @Description 获取用户信息
111 // @Accept json 134 // @Accept json
@@ -118,7 +141,7 @@ func UserInfo(c *gin.Context) { @@ -118,7 +141,7 @@ func UserInfo(c *gin.Context) {
118 c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin")) 141 c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
119 c.Header("Access-Control-Allow-Credentials", "true") 142 c.Header("Access-Control-Allow-Credentials", "true")
120 143
121 - if c.Query("id") == ""{ 144 + if c.Query("id") == "" {
122 c.JSON(200, tools.ResponseError{ 145 c.JSON(200, tools.ResponseError{
123 1, 146 1,
124 "空", 147 "空",
@@ -137,7 +160,6 @@ func UserInfo(c *gin.Context) { @@ -137,7 +160,6 @@ func UserInfo(c *gin.Context) {
137 }) 160 })
138 } else { 161 } else {
139 162
140 -  
141 c.JSON(200, tools.ResponseSeccess{ 163 c.JSON(200, tools.ResponseSeccess{
142 0, 164 0,
143 User, 165 User,
Config/config.go
1 package Config 1 package Config
2 2
3 type Config struct { 3 type Config struct {
4 - TagType []string  
5 - DbPath string 4 + TagType []string
  5 + DbPath string
  6 + RedisPath string
6 } 7 }
7 -  
Config/config.json
1 { 1 {
2 "tagType": ["menu","normal"], 2 "tagType": ["menu","normal"],
3 - "dbPath": "127.0.0.1:27017" 3 + "dbPath": "127.0.0.1:27017",
  4 + "redisPath": "127.0.0.1:6379"
4 } 5 }
@@ -3,8 +3,11 @@ package DB @@ -3,8 +3,11 @@ package DB
3 import ( 3 import (
4 "gopkg.in/mgo.v2" 4 "gopkg.in/mgo.v2"
5 "gopkg.in/mgo.v2/bson" 5 "gopkg.in/mgo.v2/bson"
  6 + "letu/Lib/Cache"
6 ) 7 )
7 8
  9 +var Redis *Cache.Redis
  10 +
8 var DBSession *mgo.Session 11 var DBSession *mgo.Session
9 var CItem *mgo.Collection //所有游玩项目内容 12 var CItem *mgo.Collection //所有游玩项目内容
10 var CComplaint *mgo.Collection //投诉 13 var CComplaint *mgo.Collection //投诉
@@ -15,6 +18,7 @@ var CTags *mgo.Collection //标签 @@ -15,6 +18,7 @@ var CTags *mgo.Collection //标签
15 var CScenic *mgo.Collection //景区 18 var CScenic *mgo.Collection //景区
16 var CLine *mgo.Collection //推荐线路 19 var CLine *mgo.Collection //推荐线路
17 var CAccessLog *mgo.Collection //访问记录 20 var CAccessLog *mgo.Collection //访问记录
  21 +var CActionLog *mgo.Collection //行为记录
18 var DB *mgo.Database 22 var DB *mgo.Database
19 23
20 type SItem struct { 24 type SItem struct {
@@ -41,12 +45,23 @@ type SLocation struct { @@ -41,12 +45,23 @@ type SLocation struct {
41 type SAccessLog struct { 45 type SAccessLog struct {
42 UserId string `bson:"UserId" json:"UserId"` // 用户ID 46 UserId string `bson:"UserId" json:"UserId"` // 用户ID
43 UserName string `bson:"UserName" json:"UserName"` //用户名称 47 UserName string `bson:"UserName" json:"UserName"` //用户名称
44 - TypeNum string `bson:"TypeNum" json:"TypeNum"` //类型编号 48 + TypeNum int64 `bson:"TypeNum" json:"TypeNum"` //类型编号
45 TypeName string `bson:"TypeName" json:"TypeName"` //类型名称 49 TypeName string `bson:"TypeName" json:"TypeName"` //类型名称
46 DateTime int64 `bson:"DateTime" json:"DateTime"` //时间戳 50 DateTime int64 `bson:"DateTime" json:"DateTime"` //时间戳
47 Location SLocation `bson:"Location" json:"Location"` //位置 51 Location SLocation `bson:"Location" json:"Location"` //位置
48 Remarks string `bson:"Remarks" json:"Remarks"` //备注 52 Remarks string `bson:"Remarks" json:"Remarks"` //备注
49 } 53 }
  54 +type SActionLog struct {
  55 + UserId string `bson:"UserId" json:"UserId"` // 用户ID
  56 + UserName string `bson:"UserName" json:"UserName"` //用户名称
  57 + Mobile string `bson:"Mobile" json:"Mobile"` //手机号
  58 + TypeNum int64 `bson:"TypeNum" json:"TypeNum"` //类型编号
  59 + TypeName string `bson:"TypeName" json:"TypeName"` //类型名称
  60 + DateTime int64 `bson:"DateTime" json:"DateTime"` //时间戳
  61 + Location SLocation `bson:"Location" json:"Location"` //位置
  62 + Content string `bson:"Content" json:"Content"` //内容
  63 + Error interface{} `bson:"Error" json:"Error"` //错误信息
  64 +}
50 type SCommodity struct { 65 type SCommodity struct {
51 Id *bson.ObjectId `bson:"_id" json:"Id" valid:"required"` 66 Id *bson.ObjectId `bson:"_id" json:"Id" valid:"required"`
52 Name string `bson:"Name" json:"Name"` 67 Name string `bson:"Name" json:"Name"`
Lib/Cache/redis.go 0 → 100644
@@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
  1 +package Cache
  2 +
  3 +import (
  4 + "encoding/json"
  5 + "github.com/garyburd/redigo/redis"
  6 + "time"
  7 +)
  8 +
  9 +//Redis redis cache
  10 +type Redis struct {
  11 + conn *redis.Pool
  12 +}
  13 +
  14 +//RedisOpts redis 连接属性
  15 +type RedisOpts struct {
  16 + Host string `yml:"host" json:"host"`
  17 + Password string `yml:"password" json:"password"`
  18 + Database int `yml:"database" json:"database"`
  19 + MaxIdle int `yml:"max_idle" json:"max_idle"`
  20 + MaxActive int `yml:"max_active" json:"max_active"`
  21 + IdleTimeout int32 `yml:"idle_timeout" json:"idle_timeout"` //second
  22 +}
  23 +
  24 +//NewRedis 实例化
  25 +func NewRedis(opts *RedisOpts) *Redis {
  26 + pool := &redis.Pool{
  27 + MaxActive: opts.MaxActive,
  28 + MaxIdle: opts.MaxIdle,
  29 + IdleTimeout: time.Second * time.Duration(opts.IdleTimeout),
  30 + Dial: func() (redis.Conn, error) {
  31 + return redis.Dial("tcp", opts.Host,
  32 + redis.DialDatabase(opts.Database),
  33 + redis.DialPassword(opts.Password),
  34 + )
  35 + },
  36 + TestOnBorrow: func(conn redis.Conn, t time.Time) error {
  37 + if time.Since(t) < time.Minute {
  38 + return nil
  39 + }
  40 + _, err := conn.Do("PING")
  41 + return err
  42 + },
  43 + }
  44 + return &Redis{pool}
  45 +}
  46 +
  47 +//Get 获取一个值
  48 +func (r *Redis) Get(key string) interface{} {
  49 + conn := r.conn.Get()
  50 + defer conn.Close()
  51 +
  52 + var data []byte
  53 + var err error
  54 + if data, err = redis.Bytes(conn.Do("GET", key)); err != nil {
  55 + return nil
  56 + }
  57 + var reply interface{}
  58 + if err = json.Unmarshal(data, &reply); err != nil {
  59 + return nil
  60 + }
  61 +
  62 + return reply
  63 +}
  64 +
  65 +//Set 设置一个值
  66 +func (r *Redis) Set(key string, val interface{}, timeout time.Duration) (err error) {
  67 + conn := r.conn.Get()
  68 + defer conn.Close()
  69 +
  70 + var data []byte
  71 + if data, err = json.Marshal(val); err != nil {
  72 + return
  73 + }
  74 +
  75 + _, err = conn.Do("SETEX", key, int64(timeout/time.Second), data)
  76 +
  77 + return
  78 +}
  79 +
  80 +//IsExist 判断key是否存在
  81 +func (r *Redis) IsExist(key string) bool {
  82 + conn := r.conn.Get()
  83 + defer conn.Close()
  84 +
  85 + a, _ := conn.Do("EXISTS", key)
  86 + i := a.(int64)
  87 + if i > 0 {
  88 + return true
  89 + }
  90 + return false
  91 +}
  92 +
  93 +//Delete 删除
  94 +func (r *Redis) Delete(key string) error {
  95 + conn := r.conn.Get()
  96 + defer conn.Close()
  97 +
  98 + if _, err := conn.Do("DEL", key); err != nil {
  99 + return err
  100 + }
  101 +
  102 + return nil
  103 +}
Lib/Code.go 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +package Lib
  2 +
  3 +import (
  4 + "fmt"
  5 + "math/rand"
  6 + "strings"
  7 + "time"
  8 +)
  9 +
  10 +
  11 +func SmsCode(width int) string {
  12 + numeric := [10]byte{0,1,2,3,4,5,6,7,8,9}
  13 + r := len(numeric)
  14 + rand.Seed(time.Now().UnixNano())
  15 +
  16 + var sb strings.Builder
  17 + for i := 0; i < width; i++ {
  18 + fmt.Fprintf(&sb, "%d", numeric[ rand.Intn(r) ])
  19 + }
  20 + return sb.String()
  21 +}
0 \ No newline at end of file 22 \ No newline at end of file
@@ -20,6 +20,7 @@ @@ -20,6 +20,7 @@
20 1. [查询线路信息](#lineinfo-get) 20 1. [查询线路信息](#lineinfo-get)
21 1. [用户登录](#loginuser-post) 21 1. [用户登录](#loginuser-post)
22 1. [返回景区基础信息](#scenicinfo-get) 22 1. [返回景区基础信息](#scenicinfo-get)
  23 +1. [发送短信验证码](#sms/send-post)
23 1. [标签列表](#tags-get) 24 1. [标签列表](#tags-get)
24 1. [更新商品](#updatecommodity-post) 25 1. [更新商品](#updatecommodity-post)
25 1. [更新设施](#updateitem-post) 26 1. [更新设施](#updateitem-post)
@@ -166,6 +167,7 @@ @@ -166,6 +167,7 @@
166 | confirmpassword | 1 | string | 确认密码 | Yes | 167 | confirmpassword | 1 | string | 确认密码 | Yes |
167 | birthday | 2010.10.10 | string | 生日 | Yes | 168 | birthday | 2010.10.10 | string | 生日 | Yes |
168 | fullname | aarongao | string | 全名 | Yes | 169 | fullname | aarongao | string | 全名 | Yes |
  170 +| code | 12345678 | string | 6位验证码 | Yes |
169 | mobile | 18616619599 | string | 手机,同用户名 | Yes | 171 | mobile | 18616619599 | string | 手机,同用户名 | Yes |
170 | openid | 12345 | string | 微信id | Yes | 172 | openid | 12345 | string | 微信id | Yes |
171 173
@@ -254,6 +256,26 @@ @@ -254,6 +256,26 @@
254 256
255 257
256 258
  259 +<a name="sms/send-post"></a>
  260 +
  261 +#### /Sms/Send (POST)
  262 +
  263 +
  264 +发送短信验证码
  265 +
  266 +| Param Name | Example | Data Type | Description | Required? |
  267 +|-----|-----|-----|-----|-----|
  268 +| mobile | 18616619599 | string | 手机号 | Yes |
  269 +| Location | {"Latitude": 119, "Longitude": 39} | string | 位置 | Yes |
  270 +
  271 +
  272 +| Code | Type | Model | Message |
  273 +|-----|-----|-----|-----|
  274 +| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":"ok"}验证码3分钟内有效 |
  275 +| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
  276 +
  277 +
  278 +
257 <a name="tags-get"></a> 279 <a name="tags-get"></a>
258 280
259 #### /Tags (GET) 281 #### /Tags (GET)
@@ -8,6 +8,7 @@ import ( @@ -8,6 +8,7 @@ import (
8 "letu/Api" 8 "letu/Api"
9 "letu/Config" 9 "letu/Config"
10 "letu/DB" 10 "letu/DB"
  11 + "letu/Lib/Cache"
11 "letu/Lib/Ws" 12 "letu/Lib/Ws"
12 "os" 13 "os"
13 ) 14 )
@@ -30,6 +31,18 @@ func main() { @@ -30,6 +31,18 @@ func main() {
30 // 连接数据库 31 // 连接数据库
31 DB.DBSession, err = mgo.Dial(conf.DbPath) 32 DB.DBSession, err = mgo.Dial(conf.DbPath)
32 defer DB.DBSession.Close() 33 defer DB.DBSession.Close()
  34 +
  35 + // 连接redis
  36 + DB.Redis = Cache.NewRedis(&Cache.RedisOpts{
  37 + conf.RedisPath,
  38 + "",
  39 + 0,
  40 + 20,
  41 + 20,
  42 + 0,
  43 + })
  44 +
  45 +
33 //设置模式 46 //设置模式
34 DB.DBSession.SetMode(mgo.Monotonic, true) 47 DB.DBSession.SetMode(mgo.Monotonic, true)
35 //获取文档集 48 //获取文档集
@@ -43,6 +56,7 @@ func main() { @@ -43,6 +56,7 @@ func main() {
43 DB.CScenic = DB.DB.C("Scenic") 56 DB.CScenic = DB.DB.C("Scenic")
44 DB.CLine = DB.DB.C("Line") 57 DB.CLine = DB.DB.C("Line")
45 DB.CAccessLog = DB.DB.C("AccessLog") 58 DB.CAccessLog = DB.DB.C("AccessLog")
  59 + DB.CActionLog = DB.DB.C("ActionLog")
46 60
47 r := gin.Default() 61 r := gin.Default()
48 //r.Static("/.well-known", "./.well-known/") 62 //r.Static("/.well-known", "./.well-known/")
@@ -69,6 +83,7 @@ func main() { @@ -69,6 +83,7 @@ func main() {
69 r.GET("/AllScenic", Api.AllScenic) 83 r.GET("/AllScenic", Api.AllScenic)
70 r.POST("/AccessLog", Api.AccessLog) 84 r.POST("/AccessLog", Api.AccessLog)
71 r.GET("/AccessLog", Api.AccessLog) 85 r.GET("/AccessLog", Api.AccessLog)
  86 + r.POST("/Sms/Send", Api.Send)
72 //r.GET("/ws", Api.WsPage) 87 //r.GET("/ws", Api.WsPage)
73 88
74 r.Static("/Upload", "./Upload") 89 r.Static("/Upload", "./Upload")