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 33  
34 34 DateTime, _ := strconv.ParseInt(c.PostForm("DateTime"), 0, 64)
35 35  
  36 + TypeNum, _ := strconv.ParseInt("TypeNum", 0, 64)
  37 +
36 38 DB.CAccessLog.Insert(DB.SAccessLog{
37 39 c.PostForm("UserId"),
38 40 c.PostForm("UserName"),
39   - c.PostForm("TypeNum"),
  41 + TypeNum,
40 42 c.PostForm("TypeName"),
41 43 DateTime,
42 44 Location,
... ...
API/Sms.go 0 → 100644
... ... @@ -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 +}
... ...
API/User.go
... ... @@ -19,6 +19,7 @@ import (
19 19 // @Param confirmpassword 1 string true "确认密码"
20 20 // @Param birthday 2010.10.10 string true "生日"
21 21 // @Param fullname aarongao string true "全名"
  22 +// @Param code 12345678 string true "6位验证码"
22 23 // @Param mobile 18616619599 string true "手机,同用户名"
23 24 // @Param openid 12345 string true "微信id"
24 25 // @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
... ... @@ -28,7 +29,14 @@ func CreateUser(c *gin.Context) {
28 29 c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
29 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 40 c.JSON(200, tools.ResponseError{
33 41 1,
34 42 "密码错误",
... ... @@ -36,8 +44,18 @@ func CreateUser(c *gin.Context) {
36 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 57 objectID := bson.NewObjectId()
40   - DB.CMember.Insert(DB.SMember{
  58 + err := DB.CMember.Insert(DB.SMember{
41 59 &objectID,
42 60 c.PostForm("password"),
43 61 c.PostForm("birthday"),
... ... @@ -46,11 +64,18 @@ func CreateUser(c *gin.Context) {
46 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 129  
105 130 }
106 131  
107   -
108   -
109 132 // @Title 用户信息
110 133 // @Description 获取用户信息
111 134 // @Accept json
... ... @@ -118,7 +141,7 @@ func UserInfo(c *gin.Context) {
118 141 c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
119 142 c.Header("Access-Control-Allow-Credentials", "true")
120 143  
121   - if c.Query("id") == ""{
  144 + if c.Query("id") == "" {
122 145 c.JSON(200, tools.ResponseError{
123 146 1,
124 147 "空",
... ... @@ -137,7 +160,6 @@ func UserInfo(c *gin.Context) {
137 160 })
138 161 } else {
139 162  
140   -
141 163 c.JSON(200, tools.ResponseSeccess{
142 164 0,
143 165 User,
... ...
Config/config.go
1 1 package Config
2 2  
3 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 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 }
... ...
DB/db.go
... ... @@ -3,8 +3,11 @@ package DB
3 3 import (
4 4 "gopkg.in/mgo.v2"
5 5 "gopkg.in/mgo.v2/bson"
  6 + "letu/Lib/Cache"
6 7 )
7 8  
  9 +var Redis *Cache.Redis
  10 +
8 11 var DBSession *mgo.Session
9 12 var CItem *mgo.Collection //所有游玩项目内容
10 13 var CComplaint *mgo.Collection //投诉
... ... @@ -15,6 +18,7 @@ var CTags *mgo.Collection //标签
15 18 var CScenic *mgo.Collection //景区
16 19 var CLine *mgo.Collection //推荐线路
17 20 var CAccessLog *mgo.Collection //访问记录
  21 +var CActionLog *mgo.Collection //行为记录
18 22 var DB *mgo.Database
19 23  
20 24 type SItem struct {
... ... @@ -41,12 +45,23 @@ type SLocation struct {
41 45 type SAccessLog struct {
42 46 UserId string `bson:"UserId" json:"UserId"` // 用户ID
43 47 UserName string `bson:"UserName" json:"UserName"` //用户名称
44   - TypeNum string `bson:"TypeNum" json:"TypeNum"` //类型编号
  48 + TypeNum int64 `bson:"TypeNum" json:"TypeNum"` //类型编号
45 49 TypeName string `bson:"TypeName" json:"TypeName"` //类型名称
46 50 DateTime int64 `bson:"DateTime" json:"DateTime"` //时间戳
47 51 Location SLocation `bson:"Location" json:"Location"` //位置
48 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 65 type SCommodity struct {
51 66 Id *bson.ObjectId `bson:"_id" json:"Id" valid:"required"`
52 67 Name string `bson:"Name" json:"Name"`
... ...
Lib/Cache/redis.go 0 → 100644
... ... @@ -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 @@
  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 22 \ No newline at end of file
... ...
README.md
... ... @@ -20,6 +20,7 @@
20 20 1. [查询线路信息](#lineinfo-get)
21 21 1. [用户登录](#loginuser-post)
22 22 1. [返回景区基础信息](#scenicinfo-get)
  23 +1. [发送短信验证码](#sms/send-post)
23 24 1. [标签列表](#tags-get)
24 25 1. [更新商品](#updatecommodity-post)
25 26 1. [更新设施](#updateitem-post)
... ... @@ -166,6 +167,7 @@
166 167 | confirmpassword | 1 | string | 确认密码 | Yes |
167 168 | birthday | 2010.10.10 | string | 生日 | Yes |
168 169 | fullname | aarongao | string | 全名 | Yes |
  170 +| code | 12345678 | string | 6位验证码 | Yes |
169 171 | mobile | 18616619599 | string | 手机,同用户名 | Yes |
170 172 | openid | 12345 | string | 微信id | Yes |
171 173  
... ... @@ -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 279 <a name="tags-get"></a>
258 280  
259 281 #### /Tags (GET)
... ...
main.go
... ... @@ -8,6 +8,7 @@ import (
8 8 "letu/Api"
9 9 "letu/Config"
10 10 "letu/DB"
  11 + "letu/Lib/Cache"
11 12 "letu/Lib/Ws"
12 13 "os"
13 14 )
... ... @@ -30,6 +31,18 @@ func main() {
30 31 // 连接数据库
31 32 DB.DBSession, err = mgo.Dial(conf.DbPath)
32 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 47 DB.DBSession.SetMode(mgo.Monotonic, true)
35 48 //获取文档集
... ... @@ -43,6 +56,7 @@ func main() {
43 56 DB.CScenic = DB.DB.C("Scenic")
44 57 DB.CLine = DB.DB.C("Line")
45 58 DB.CAccessLog = DB.DB.C("AccessLog")
  59 + DB.CActionLog = DB.DB.C("ActionLog")
46 60  
47 61 r := gin.Default()
48 62 //r.Static("/.well-known", "./.well-known/")
... ... @@ -69,6 +83,7 @@ func main() {
69 83 r.GET("/AllScenic", Api.AllScenic)
70 84 r.POST("/AccessLog", Api.AccessLog)
71 85 r.GET("/AccessLog", Api.AccessLog)
  86 + r.POST("/Sms/Send", Api.Send)
72 87 //r.GET("/ws", Api.WsPage)
73 88  
74 89 r.Static("/Upload", "./Upload")
... ...