pax_global_header 0000666 0000000 0000000 00000000064 13616430655 0014523 g ustar 00root root 0000000 0000000 52 comment=5e3c7fd4dfa310cc025e3a87943c9bb99452d00e
leyoutu_server.git/ 0000775 0000000 0000000 00000000000 13616430655 0014745 5 ustar 00root root 0000000 0000000 leyoutu_server.git/.gitignore 0000664 0000000 0000000 00000000032 13616430655 0016730 0 ustar 00root root 0000000 0000000 main
tiles
Upload
Console
leyoutu_server.git/API/ 0000775 0000000 0000000 00000000000 13616430655 0015356 5 ustar 00root root 0000000 0000000 leyoutu_server.git/API/Complaint.go 0000664 0000000 0000000 00000003714 13616430655 0017640 0 ustar 00root root 0000000 0000000 package Api
import (
"encoding/json"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"letu/DB"
"regexp"
)
// @Title 增加投诉
// @Description 增加投诉
// @Accept json
// @Produce json
// @Param Mobile 18616619599 string true "联系电话"
// @Param Name 高先生 string true "姓名"
// @Param Code 123456 string true "验证码"
// @Param Sex 男 string true "性别"
// @Param ScenicId 5e1ed07524e03431008b4572 string true "景区id"
// @Param Type 1 string true "类型"
// @Param Content 卫生不干净 string true "投诉内容"
// @Param Image ["http://www.xx.com/123.jpg","http://www.xx.com/123.jpg"] string true "照片数组"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /CreateComplaint? [post]
func CreateComplaint(c *gin.Context) {
c.Header("Access-Control-Allow-Origin",c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials","true")
reg := regexp.MustCompile(Regular)
if !reg.MatchString(c.PostForm("Mobile")) {
c.JSON(200, tools.ResponseError{
1,
"手机号格式不正确",
})
return
}
if c.PostForm("Mobile") == ""{
c.JSON(200, tools.ResponseError{
1,
"手机号为空",
})
return
}
// 检查验证码
cacheCode := DB.Redis.Get(c.PostForm("Mobile"))
if cacheCode != c.PostForm("Code") {
c.JSON(200, tools.ResponseError{
1,
"验证码不正确",
})
return
}
var images []string
json.Unmarshal([]byte(c.PostForm("Image")), &images)
DB.CComplaint.Insert(DB.SComplaint{
c.PostForm("Type"),
c.PostForm("ScenicId"),
c.PostForm("Mobile"),
c.PostForm("Name"),
c.PostForm("Sex"),
c.PostForm("Content"),
images,
})
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
leyoutu_server.git/API/DealyMessage.go 0000664 0000000 0000000 00000005764 13616430655 0020264 0 ustar 00root root 0000000 0000000 package Api
import (
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2/bson"
"letu/Lib/DelayMessage"
)
// @Title 查询用户的定时提醒
// @Description 查询用户的定时提醒
// @Accept json
// @Produce json
// @Param UserId 5dfb03070a9ac17ac7a82054 string true "用户id"
// @Success 200 {object} tools.ResponseSeccess "DelayTime=执行时间;Type=类型(0请求url地址1发送app通知);Fail失败次数;Title=通知标题;Content=通知内容;UDID=设备id"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /DealyMessage/Info? [get]
func DealyMessageInfo(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var aDelayMessage []DelayMessage.Message
DelayMessage.CDelayMessage.Find(bson.M{"UserId": c.Query("UserId")}).All(&aDelayMessage)
if aDelayMessage == nil {
aDelayMessage = []DelayMessage.Message{}
}
c.JSON(200, tools.ResponseSeccess{
0,
aDelayMessage,
})
}
// @Title 创建提醒
// @Description 创建提醒
// @Accept json
// @Produce json
// @Param UserId 5dfb03070a9ac17ac7a82054 string true "用户id"
// @Param UDID 5dfb03070a9ac17ac7a82054 string true "设备id"
// @Param Title 表演时间提醒 string true "标题"
// @Param Content 5分钟后有表演 string true "内容"
// @Param DelayTime 1579066863 string true "到达这个时间戳就执行"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /DealyMessage/Create? [post]
func CreateDealyMessage(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
err := DelayMessage.GlobalDM.AddTaskForAppMessage(c.PostForm("DelayTime"), c.PostForm("UDID"), c.PostForm("Title"), c.PostForm("Content"), c.PostForm("UserId"))
if err == nil {
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
} else {
c.JSON(200, tools.ResponseError{
1,
err.Error(),
})
}
}
// @Title 删除提醒
// @Description 删除提醒
// @Accept json
// @Produce json
// @Param id 5dfb03070a9ac17ac7a82054 string true "提醒id"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /DealyMessage/Remove? [post]
func RemoveDealyMessage(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
if bson.IsObjectIdHex(c.PostForm("id")) == false {
c.JSON(200, tools.ResponseError{
1,
"id不正确",
})
return
}
DelayMessage.GlobalDM.DelTaskForId(c.PostForm("id"))
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
leyoutu_server.git/API/EventLog.go 0000664 0000000 0000000 00000003046 13616430655 0017433 0 ustar 00root root 0000000 0000000 package Api
import (
"encoding/json"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"letu/DB"
"strconv"
)
// @Title 增加访问日志
// @Description 增加访问日志
// @Accept json
// @Produce json
// @Param UserId 5dfb03070a9ac17ac7a82054 string true "用户ID"
// @Param UserName Aaron string true "用户名称"
// @Param TypeNum 9 int true "类型编号"
// @Param TypeName 点击个人中心 string true "类型名称"
// @Param DateTime 1578556751220 int true "时间戳"
// @Param Location {"Latitude": 119, "Longitude": 39} string true "位置"
// @Param Remarks 备注 string true "备注"
// @Success 200 {object} tools.ResponseSeccess ""
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /EventLog? [post]
func EventLog(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
if c.Request.Method == "post" {
var Location DB.SLocation
json.Unmarshal([]byte(c.PostForm("Location")), &Location)
DateTime, _ := strconv.ParseInt(c.PostForm("DateTime"), 0, 64)
TypeNum, _ := strconv.ParseInt("TypeNum", 0, 64)
DB.CEventLog.Insert(DB.SEventLog{
c.PostForm("UserId"),
c.PostForm("UserName"),
TypeNum,
c.PostForm("TypeName"),
DateTime,
Location,
c.PostForm("Remarks"),
})
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
}
leyoutu_server.git/API/Investigation.go 0000664 0000000 0000000 00000001766 13616430655 0020542 0 ustar 00root root 0000000 0000000 package Api
import (
"encoding/json"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"letu/DB"
)
// @Title 增加调查
// @Description 增加调查
// @Accept json
// @Produce json
// @Param UserId 1111111 string true "UserId"
// @Param Mobile 18616619599 string true "联系电话"
// @Param type 1 string true "类型"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /Investigation/Save? [post]
func SaveInvestigation(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var Data map[string]interface{}
json.Unmarshal([]byte(c.PostForm("Data")), &Data)
DB.CInvestigation.Insert(DB.SInvestigation{
c.PostForm("UserId"),
c.PostForm("Mobile"),
Data,
})
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
leyoutu_server.git/API/Item.go 0000664 0000000 0000000 00000012122 13616430655 0016601 0 ustar 00root root 0000000 0000000 package Api
import (
"encoding/json"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2/bson"
"letu/DB"
"time"
)
// @Title 查询设备信息
// @Description 设备管理 - 查询设备信息
// @Accept json
// @Produce json
// @Param id 5dfb03070a9ac17ac7a82054 string true "设备id"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":{"Name":"名称","Describe":"介绍","OpenHours":"开放时间","Mobile":"电话","Address":"地址","SLocation":{"Latitude":0,"Longitude":0},"Picture":["照片1","照片2"]}}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /ItemInfo? [get]
func ItemInfo(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") == "" {
c.JSON(200, tools.ResponseError{
1,
"空",
})
return
}
var SItem DB.SItem
DB.CItem.Find(bson.M{"_id": bson.ObjectIdHex(c.Query("id"))}).One(&SItem)
c.JSON(200, tools.ResponseSeccess{
0,
SItem,
})
}
// @Title 查询所有游玩项目
// @Description 查询所有游玩项目
// @Accept json
// @Produce json
// @Success 200 {object} tools.ResponseSeccess "Tags所属标签,标签有分类;LimitHeight限高;PlayDuration游玩时长;SceneTime场次时间;Picture照片;Voice音频;AverageConsumption平均消费;Menu菜单"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /AllItems? [get]
func AllItems(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var aItems []DB.SItem
DB.CItem.Find(bson.M{}).All(&aItems)
c.JSON(200, aItems)
}
// @Title 更新设施
// @Description 设备管理 - 更新设施
// @Accept json
// @Produce json
// @Success 200 {object} tools.ResponseSeccess "Tags所属标签,标签有分类;LimitHeight限高;PlayDuration游玩时长;SceneTime场次时间;Picture照片;Voice音频;AverageConsumption平均消费;Menu菜单"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /UpdateItem? [post]
func UpdateItem(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var Location DB.SLocation
json.Unmarshal([]byte(c.PostForm("Location")), &Location)
var Tags []DB.STag
json.Unmarshal([]byte(c.PostForm("Tags")), &Tags)
var Picture []string
json.Unmarshal([]byte(c.PostForm("Picture")), &Picture)
var id bson.ObjectId
if pid := c.PostForm("id"); pid == "null" {
id = bson.NewObjectId()
} else {
id = bson.ObjectIdHex(pid)
}
DB.CItem.UpsertId(
id,
bson.M{"$set": bson.M{
"Name": c.PostForm("Name"),
"SubName": c.PostForm("SubName"),
"Location": Location,
"Icon": c.PostForm("Icon"),
"LimitHeight": c.PostForm("LimitHeight"),
"PlayDuration": c.PostForm("PlayDuration"),
"SceneTime": c.PostForm("SceneTime"),
"Picture": Picture,
"Voice": c.PostForm("Voice"),
"Tel": c.PostForm("Tel"),
"AverageConsumption": c.PostForm("AverageConsumption"),
"Menu": c.PostForm("Menu"),
"Tags": Tags,
}},
)
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
type ItemTime struct {
Id string `json:"id"`
Time string `json:"time"`
}
// @Title 更新等待时间
// @Description 设备管理 - 更新等待时间
// @Accept json
// @Produce json
// @Param item [{"id":"5df864740a9ac17ac7a7feb8","time":"20"},{"id":"5df8660924e03417008b4567","time":"33"}] string true "设备列表"
// @Success 200 {object} tools.ResponseSeccess "{errcode: 0, result: "ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /UpdateItemTime? [post]
func UpdateItemTime(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var ItemTime []ItemTime
json.Unmarshal([]byte(c.PostForm("items")), &ItemTime)
var RedisData = make(map[string]string)
for _, v := range ItemTime {
RedisData[v.Id] = v.Time
}
DB.Redis.Set("AllItemTime", RedisData, time.Second*60*60*24*30)
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
// @Title 获得所有设备的等待时间
// @Description 设备管理 - 获得所有设备的等待时间
// @Accept json
// @Produce json
// @Success 200 {object} tools.ResponseSeccess "{5df864740a9ac17ac7a7feb8: '20',.....}"
// @Failure 500 {object} tools.ResponseError "{}"
// @Router /AllItemTime? [get]
func AllItemTime(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var ItemTime map[string]string
json.Unmarshal([]byte(c.PostForm("items")), &ItemTime)
allteim := DB.Redis.Get("AllItemTime")
if allteim != nil{
c.JSON(200, allteim)
}else{
c.String(200, "{}")
}
}
leyoutu_server.git/API/Line.go 0000664 0000000 0000000 00000005464 13616430655 0016605 0 ustar 00root root 0000000 0000000 package Api
import (
"encoding/json"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2/bson"
"letu/DB"
)
// @Title 查询线路信息
// @Description 查询线路信息
// @Accept json
// @Produce json
// @Param id 5dfb03070a9ac17ac7a82054 string true "id"
// @Success 200 {object} tools.ResponseSeccess "Name名称;SubName副标题;PlayDuration游玩时长;Suitable适合人群;Location线路点坐标;Annotations需要点亮的设施id;Distance距离"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /LineInfo? [get]
func LineInfo(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") == "" {
c.JSON(200, tools.ResponseError{
1,
"空",
})
return
}
var SLine DB.SLine
DB.CLine.Find(bson.M{"_id": bson.ObjectIdHex(c.Query("id"))}).One(&SLine)
c.JSON(200, tools.ResponseSeccess{
0,
SLine,
})
}
// @Title 查询所有线路
// @Description 查询所有线路
// @Accept json
// @Produce json
// @Success 200 {object} tools.ResponseSeccess "Name名称;SubName副标题;PlayDuration游玩时长;Suitable适合人群;Location线路点坐标;Annotations需要点亮的设施id;Distance距离"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /AllLine? [get]
func AllLine(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var aLine []DB.SLine
DB.CLine.Find(bson.M{}).All(&aLine)
c.JSON(200, aLine)
}
// @Title 更新线路
// @Description 更新线路
// @Accept json
// @Produce json
// @Success 200 {object} tools.ResponseSeccess ""
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /UpdateLine? [post]
func UpdateLine(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var Location []DB.SLocation
json.Unmarshal([]byte(c.PostForm("Location")), &Location)
var Annotations []string
json.Unmarshal([]byte(c.PostForm("Annotations")), &Annotations)
var id bson.ObjectId
if pid := c.PostForm("id"); pid == "null" {
id = bson.NewObjectId()
} else {
id = bson.ObjectIdHex(pid)
}
DB.CLine.UpsertId(
id,
bson.M{"$set": bson.M{
"Name": c.PostForm("Name"),
"SubName": c.PostForm("SubName"),
"PlayDuration": c.PostForm("PlayDuration"),
"Suitable": c.PostForm("Suitable"),
"Content": c.PostForm("Content"),
"Distance": c.PostForm("Distance"),
"Annotations": Annotations,
"Location": Location,
}},
)
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
leyoutu_server.git/API/Scenic.go 0000664 0000000 0000000 00000007246 13616430655 0017122 0 ustar 00root root 0000000 0000000 package Api
import (
"encoding/json"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2/bson"
"letu/DB"
)
// @Title 返回景区基础信息
// @Description 返回景区基础信息
// @Accept json
// @Produce json
// @Param id 5dfb03070a9ac17ac7a82054 string true "景区id"
// @Success 200 {object} tools.ResponseSeccess "Name名称;Describe介绍;OpenHours营业时间;Picture最上面图片;ShopAdPicture商城列表页图片;ItemScenicPicture项目场次照片;ActivityPicture活动照片;VideoList视频"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /ScenicInfo? [get]
func ScenicInfo(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") == "" {
c.JSON(200, tools.ResponseError{
1,
"空",
})
return
}
var Scenic *DB.SScenic
DB.CScenic.Find(bson.M{"_id": bson.ObjectIdHex(c.Query("id"))}).One(&Scenic)
c.JSON(200, tools.ResponseSeccess{
0,
Scenic,
})
}
// @Title 更新景区基础信息
// @Description 更新景区基础信息
// @Accept json
// @Produce json
// @Param id 5dfb03070a9ac17ac7a82054 string true "景区id"
// @Success 200 {object} tools.ResponseSeccess "Name名称;Describe介绍;OpenHours营业时间;Picture最上面图片;ShopAdPicture商城列表页图片;ItemScenicPicture项目场次照片;ActivityPicture活动照片;VideoList视频"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /UpdateScenic? [post]
func UpdateScenic(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var Location DB.SLocation
json.Unmarshal([]byte(c.PostForm("Location")), &Location)
var Picture []DB.SPicture
json.Unmarshal([]byte(c.PostForm("Picture")), &Picture)
var ShopAdPicture []DB.SPicture
json.Unmarshal([]byte(c.PostForm("ShopAdPicture")), &ShopAdPicture)
var ItemScenicPicture []DB.SPicture
json.Unmarshal([]byte(c.PostForm("ItemScenicPicture")), &ItemScenicPicture)
var ActivityPicture []DB.SPicture
json.Unmarshal([]byte(c.PostForm("ActivityPicture")), &ActivityPicture)
var VideoList []DB.SPicture
json.Unmarshal([]byte(c.PostForm("VideoList")), &VideoList)
var id bson.ObjectId
if pid := c.PostForm("id"); pid == "null" {
id = bson.NewObjectId()
} else {
id = bson.ObjectIdHex(pid)
}
DB.CScenic.UpsertId(
id,
bson.M{"$set": bson.M{
"Name": c.PostForm("Name"),
"Describe": c.PostForm("Describe"),
"Location": Location,
"OpenHours": c.PostForm("OpenHours"),
"Mobile": c.PostForm("Mobile"),
"Address": c.PostForm("Address"),
"Picture": Picture,
"ShopAdPicture": ShopAdPicture,
"ItemScenicPicture": ItemScenicPicture,
"ActivityPicture": ActivityPicture,
"VideoList": VideoList,
}},
)
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
// @Title 所有景区基础信息
// @Description 所有景区基础信息
// @Accept json
// @Produce json
// @Success 200 {object} tools.ResponseSeccess ""
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /AllScenic? [get]
func AllScenic(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var Scenic []*DB.SScenic
DB.CScenic.Find(bson.M{}).All(&Scenic)
if Scenic == nil {
Scenic = []*DB.SScenic{}
}
c.JSON(200, tools.ResponseSeccess{
0,
Scenic,
})
}
leyoutu_server.git/API/Shop.go 0000664 0000000 0000000 00000005572 13616430655 0016627 0 ustar 00root root 0000000 0000000 package Api
import (
"encoding/json"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2/bson"
"letu/DB"
)
// @Title 查询商品信息
// @Description 查询商品信息
// @Accept json
// @Produce json
// @Param id 5dfb03070a9ac17ac7a82054 string true "id"
// @Success 200 {object} tools.ResponseSeccess "Price=价格;ShopName=店铺名称;KvPhoto用于列表页的图片;TopPhoto详情页最上面的轮播图;Images详情页下面的产品详细图"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /CommodityInfo? [get]
func CommodityInfo(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") == "" {
c.JSON(200, tools.ResponseError{
1,
"空",
})
return
}
var SCommodity DB.SCommodity
DB.CCommodity.Find(bson.M{"_id": bson.ObjectIdHex(c.Query("id"))}).One(&SCommodity)
c.JSON(200, tools.ResponseSeccess{
0,
SCommodity,
})
}
// @Title 查询所有商品
// @Description 查询所有商品
// @Accept json
// @Produce json
// @Success 200 {object} tools.ResponseSeccess "Price=价格;ShopName=店铺名称;KvPhoto用于列表页的图片;TopPhoto详情页最上面的轮播图;Images详情页下面的产品详细图"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /AllCommodity? [get]
func AllCommodity(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var aCommoditys []DB.SCommodity
DB.CCommodity.Find(bson.M{}).All(&aCommoditys)
c.JSON(200, aCommoditys)
}
// @Title 更新商品
// @Description 更新商品
// @Accept json
// @Produce json
// @Success 200 {object} tools.ResponseSeccess ""
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /UpdateCommodity? [post]
func UpdateCommodity(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var Picture []string
json.Unmarshal([]byte(c.PostForm("Images")), &Picture)
var TopPhoto []DB.SPicture
json.Unmarshal([]byte(c.PostForm("TopPhoto")), &TopPhoto)
//var Location DB.SLocation
//json.Unmarshal([]byte(c.PostForm("Location")), &Location)
var id bson.ObjectId
if pid := c.PostForm("id"); pid == "null" {
id = bson.NewObjectId()
} else {
id = bson.ObjectIdHex(pid)
}
DB.CCommodity.UpsertId(
id,
bson.M{"$set": bson.M{
"Name": c.PostForm("Name"),
"Price": c.PostForm("Price"),
"ShopName": c.PostForm("ShopName"),
"KvPhoto": c.PostForm("KvPhoto"),
"TopPhoto": TopPhoto,
"ItemId": c.PostForm("ItemId"),
"Images": Picture,
}},
)
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
leyoutu_server.git/API/Sms.go 0000664 0000000 0000000 00000004537 13616430655 0016460 0 ustar 00root root 0000000 0000000 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"}验证码1分钟内有效"
// @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 = response.Code
if response.Code == "OK" {
DB.Redis.Set(c.PostForm("Mobile"), code, time.Second*60)
}
}
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() {
}
leyoutu_server.git/API/Tag.go 0000664 0000000 0000000 00000001526 13616430655 0016424 0 ustar 00root root 0000000 0000000 package Api
import (
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2/bson"
"letu/DB"
)
// @Title 标签列表
// @Description 标签列表
// @Accept json
// @Produce json
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":[{"Type":"menu","Name":"服务设施"},{"Type":"normal","Name":"不错"},{"Type":"thrilling","Name":"刺激"},{"Type":"recommend","Name":"必玩"}]}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /Tags? [get]
func AllTag(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var Stags []*DB.STag
DB.CTags.Find(bson.M{}).All(&Stags)
if Stags == nil {
Stags = []*DB.STag{}
}
c.JSON(200, tools.ResponseSeccess{
0,
Stags,
})
}
leyoutu_server.git/API/Tiles.go 0000664 0000000 0000000 00000001414 13616430655 0016765 0 ustar 00root root 0000000 0000000 package Api
import (
"fmt"
"github.com/gin-gonic/gin"
"io/ioutil"
"os"
)
func Tiles(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
dir, _ := os.Getwd()
//path := dir + "/tiles/" + c.Query("z") + "/" + c.Query("x") + "/" + c.Query("y") + ".jpg"
path := fmt.Sprintf("%s/tiles/%s/%s/%s.jpg",dir,c.Query("z"),c.Query("x"),c.Query("y"))
if !PathExists(path) {
path = dir + "/tiles/blank.png"
}
b, err := ioutil.ReadFile(path)
if err != nil {
fmt.Print(err)
}
c.Data(200, "Content-type: image/jpeg", b)
}
func PathExists(path string) (bool) {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}
leyoutu_server.git/API/Trajectory.go 0000664 0000000 0000000 00000001766 13616430655 0020045 0 ustar 00root root 0000000 0000000 package Api
import (
"encoding/json"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"letu/DB"
"time"
)
// @Title 保存用户移动轨迹
// @Description 保存用户移动轨迹
// @Accept json
// @Produce json
// @Param UserId 5dfb03070a9ac17ac7a82054 string true "用户id"
// @Param Location {"Latitude": 119, "Longitude": 39} string true "经纬度"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /Trajectory/Save? [post]
func SaveTrajectory(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
var Location DB.SLocation
json.Unmarshal([]byte(c.PostForm("Location")), &Location)
DB.CTrajectory.Insert(DB.STrajectory{
c.PostForm("UserId"),
Location,
time.Now().Unix(),
})
c.JSON(200, tools.ResponseSeccess{
0,
"ok",
})
}
leyoutu_server.git/API/Upload.go 0000664 0000000 0000000 00000002112 13616430655 0017125 0 ustar 00root root 0000000 0000000 package Api
import (
"fmt"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"path"
"strconv"
"time"
)
// @Title 上传文件
// @Description 上传
// @Accept json
// @Produce json
// @Param file 1 file true "文件"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"图片地址"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /Upload? [post]
func Upload(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
file, err := c.FormFile("file")
if err != nil {
c.JSON(200, tools.ResponseError{
1,
"a Bad request",
})
return
}
fileName := file.Filename
fileExt := path.Ext(fileName)
filePath := "Upload/" + strconv.Itoa(int(time.Now().UnixNano())) + fileExt
if err := c.SaveUploadedFile(file, filePath); err != nil {
fmt.Println(err)
c.JSON(200, tools.ResponseError{
1,
"upload file err",
})
return
}
c.JSON(200, tools.ResponseSeccess{
0,
"/" + filePath,
})
}
leyoutu_server.git/API/User.go 0000664 0000000 0000000 00000016743 13616430655 0016636 0 ustar 00root root 0000000 0000000 package Api
import (
"crypto/sha256"
"encoding/hex"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2/bson"
"letu/DB"
"regexp"
"strconv"
"time"
)
//
//// @Title 创建用户
//// @Description 用户注册
//// @Accept json
//// @Produce json
//// @Param password 1 string true "密码"
//// @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"}"
//// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
//// @Router /CreateUser? [post]
//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.JSON(200, tools.ResponseError{
// 1,
// "必须有手机号",
// })
// return
// }
// if c.PostForm("password") != c.PostForm("confirmpassword") {
// c.JSON(200, tools.ResponseError{
// 1,
// "密码错误",
// })
// return
// }
//
// // 检查验证码
// code := DB.Redis.Get(c.PostForm("mobile"))
// if code == "" || code != c.PostForm("code") {
// c.JSON(200, tools.ResponseError{
// 1,
// "验证码错误",
// })
// return
// }
//
// objectID := bson.NewObjectId()
// err := DB.CMember.Insert(DB.SMember{
// &objectID,
// c.PostForm("password"),
// c.PostForm("birthday"),
// c.PostForm("fullname"),
// c.PostForm("mobile"),
// c.PostForm("openid"),
// "",
// })
// if err == nil{
// c.JSON(200, tools.ResponseSeccess{
// 0,
// "ok",
// })
// }else{
// c.JSON(200, tools.ResponseError{
// 0,
// "此手机号已经注册",
// })
// }
//
//
//}
var Regular = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"
// @Title 登录
// @Description 用户管理 - 用户登录&注册
// @Accept json
// @Produce json
// @Param Mobile aaron string true "手机号"
// @Param Password 1 string true "密码或验证码(使用验证码的新手机号自动注册)"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":{"Id":"5e09c64c1c09c6f0f7ca2fa9","Token":"640bf934e425aba5d3c90998b2641f2f0ca07261d334d9615d1cd4790b5f34e7"}} 调用其它需要登陆的接口时携带token,有过期时间"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /LoginUser? [post]
func LoginUser(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
reg := regexp.MustCompile(Regular)
if !reg.MatchString(c.PostForm("Mobile")) {
c.JSON(200, tools.ResponseError{
1,
"手机号格式不正确",
})
return
}
if c.PostForm("Mobile") == "" || c.PostForm("Password") == "" {
c.JSON(200, tools.ResponseError{
1,
"空",
})
return
}
// 生成token
tokenunit8 := sha256.Sum256([]byte(c.PostForm("Mobile") + c.PostForm("Password") + strconv.FormatInt(time.Now().UnixNano(), 10)))
token := hex.EncodeToString(tokenunit8[:32])
// 检查验证码
cacheCode := DB.Redis.Get(c.PostForm("Mobile"))
selected := bson.M{}
var User *DB.SMember
if cacheCode == c.PostForm("Password") {
selected["Mobile"] = c.PostForm("Mobile")
DB.CMember.Find(selected).One(&User)
// 验证码匹配,但手机号不存在
if User == nil {
objectID := bson.NewObjectId()
oUser := DB.SMember{
&objectID,
"",
"",
"",
c.PostForm("Mobile"),
"",
token,
"",
}
DB.CMember.Insert(oUser)
//if err == nil {
c.JSON(200, tools.ResponseSeccess{
0,
oUser,
})
return
//}
}
} else {
selected["Mobile"] = c.PostForm("Mobile")
selected["Password"] = c.PostForm("Password")
DB.CMember.Find(selected).One(&User)
if User == nil {
c.JSON(200, tools.ResponseError{
1,
"用户不存在或密码不正确",
})
return
}
}
// 更新用户信息
DB.CMember.Update(
bson.M{"_id": User.Id},
bson.M{"$set": bson.M{"Token": token}},
)
User.Token = token
c.JSON(200, tools.ResponseSeccess{
0,
User,
})
}
// @Title 用户信息
// @Description 用户管理 - 获取用户信息
// @Accept json
// @Produce json
// @Param id aaron string true "用户id"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":{"Id":"5e09c64c1c09c6f0f7ca2fa9","Token":"640bf934e425aba5d3c90998b2641f2f0ca07261d334d9615d1cd4790b5f34e7"}}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /UserInfo? [get]
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") == "" {
c.JSON(200, tools.ResponseError{
1,
"空",
})
return
}
var User DB.SMember
DB.CMember.Find(bson.M{"_id": bson.ObjectIdHex(c.Query("id"))}).One(&User)
c.JSON(200, tools.ResponseSeccess{
0,
User,
})
}
// @Title 修改用户信息
// @Description 用户管理 - 修改用户信息
// @Accept json
// @Produce json
// @Param Password 1 string true "密码"
// @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 Sex 男 string true "性别"
// @Param Openid 12345 string true "微信id"
// @Success 200 {object} tools.ResponseSeccess "{"errcode":0,"result":"ok"}"
// @Failure 500 {object} tools.ResponseError "{"errcode":1,"errmsg":"错误原因"}"
// @Router /UpdateUser? [post]
func UpdateUser(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", c.Request.Header.Get("Origin"))
c.Header("Access-Control-Allow-Credentials", "true")
reg := regexp.MustCompile(Regular)
if !reg.MatchString(c.PostForm("Mobile")) {
c.JSON(200, tools.ResponseError{
1,
"手机号格式不正确",
})
return
}
if c.PostForm("Mobile") == "" || c.PostForm("Password") == "" {
c.JSON(200, tools.ResponseError{
1,
"手机号或密码为空",
})
return
}
if c.PostForm("Password") != c.PostForm("ConfirmPassword") {
c.JSON(200, tools.ResponseError{
1,
"2次密码不一致",
})
return
}
// 检查验证码
code := DB.Redis.Get(c.PostForm("Mobile"))
if code == "" || code != c.PostForm("Code") {
c.JSON(200, tools.ResponseError{
1,
"验证码错误",
})
return
}
err := DB.CMember.Update(
bson.M{"Mobile": c.PostForm("Mobile")},
bson.M{"$set": bson.M{
"Password": c.PostForm("Password"),
"Birthday": c.PostForm("Birthday"),
"FullName": c.PostForm("Fullname"),
"Mobile": c.PostForm("Mobile"),
"Sex": c.PostForm("Sex"),
}},
)
if err == nil {
var User *DB.SMember
DB.CMember.Find(bson.M{"Mobile": c.PostForm("Mobile")}).One(&User)
c.JSON(200, tools.ResponseSeccess{
0,
User,
})
} else {
c.JSON(200, tools.ResponseError{
1,
err.Error(),
})
}
}
leyoutu_server.git/API/Ws.go 0000664 0000000 0000000 00000001565 13616430655 0016305 0 ustar 00root root 0000000 0000000 package Api
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
uuid "github.com/satori/go.uuid"
"letu/Lib/Ws"
)
var wsupgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
func WsPage(c *gin.Context) {
conn, err := wsupgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
fmt.Println("Failed to set websocket upgrade: %+v", err)
return
}
// websocket connect
_uuid, _ := uuid.NewV4()
client := &Ws.Client{
_uuid.String(),
conn,
}
Ws.Manager.Register <- client
for {
_, msg, err := conn.ReadMessage()
if err != nil {
println(err.Error())
Ws.Manager.Unregister <- client
client.Socket.Close()
break
}
sMsg := string(msg)
println("收到消息:", sMsg)
switch sMsg {
case "test":
client.Send([]byte("hahaha"))
case "test2":
client.Send([]byte("hahaha2"))
}
}
}
leyoutu_server.git/Config/ 0000775 0000000 0000000 00000000000 13616430655 0016152 5 ustar 00root root 0000000 0000000 leyoutu_server.git/Config/AccessType/ 0000775 0000000 0000000 00000000000 13616430655 0020215 5 ustar 00root root 0000000 0000000 leyoutu_server.git/Config/AccessType/AccessType.go 0000664 0000000 0000000 00000001750 13616430655 0022612 0 ustar 00root root 0000000 0000000 package EventType
type EventType int32
const (
PageForIndex EventType = 1
PageForRecommendMenu EventType = 2
PageForPlayItemMenu EventType = 3
PageForPerformMenu EventType = 4
PageForServiceMenu EventType = 5
PageForRestaurantMenu EventType = 6
TouchAnnotation EventType = 7
TouchShopMenu EventType = 8
TouchMyMenu EventType = 9
TouchComplaintMenu EventType = 10
)
func (o EventType) String() string {
switch (o) {
case PageForIndex:
return "首页"
case PageForRecommendMenu:
return "推荐"
case PageForPlayItemMenu:
return "游玩项目"
case PageForPerformMenu:
return "演出活动"
case PageForServiceMenu:
return "服务设施"
case PageForRestaurantMenu:
return "餐饮购物"
case TouchAnnotation:
return "点击建筑图标"
case TouchShopMenu:
return "点击商店"
case TouchMyMenu:
return "点击个人中心"
case TouchComplaintMenu:
return "点击投诉&意见"
default:
return "UNKNOWN"
}
}
leyoutu_server.git/Config/config.go 0000664 0000000 0000000 00000000137 13616430655 0017747 0 ustar 00root root 0000000 0000000 package Config
type Config struct {
TagType []string
DbPath string
RedisPath string
}
leyoutu_server.git/Config/config.json 0000664 0000000 0000000 00000000143 13616430655 0020310 0 ustar 00root root 0000000 0000000 {
"tagType": ["menu","normal"],
"dbPath": "127.0.0.1:27017",
"redisPath": "127.0.0.1:6379"
}
leyoutu_server.git/DB/ 0000775 0000000 0000000 00000000000 13616430655 0015232 5 ustar 00root root 0000000 0000000 leyoutu_server.git/DB/db.go 0000664 0000000 0000000 00000015256 13616430655 0016157 0 ustar 00root root 0000000 0000000 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 //投诉
var CInvestigation *mgo.Collection //调查
var CMember *mgo.Collection //会员
var CCommodity *mgo.Collection //商城
var CTags *mgo.Collection //标签
var CScenic *mgo.Collection //景区
var CLine *mgo.Collection //推荐线路
var CEventLog *mgo.Collection //用户行为记录
var CActionLog *mgo.Collection //操作记录
var CTrajectory *mgo.Collection //移动轨迹
var DB *mgo.Database
type SItem struct {
Id *bson.ObjectId `bson:"_id" json:"Id" valid:"required"`
Name string `bson:"Name" json:"Name"`
SubName string `bson:"SubName" json:"SubName"`
Location SLocation `bson:"Location" json:"Location"`
Tags []STag `bson:"Tags" json:"Tags"`
Icon string `bson:"Icon" json:"Icon"`
LimitHeight string `bson:"LimitHeight" json:"LimitHeight"` //限高
PlayDuration string `bson:"PlayDuration" json:"PlayDuration"` //游玩时长
SceneTime string `bson:"SceneTime" json:"SceneTime"` //场次时间
Picture []string `bson:"Picture" json:"Picture"`
Voice string `bson:"Voice" json:"Voice"` //音频
Tel string `bson:"Tel" json:"Tel"`
AverageConsumption string `bson:"AverageConsumption" json:"AverageConsumption"` //人均消费
Menu string `bson:"Menu" json:"Menu"` //菜单
Time string `bson:"Time" json:"Time"`
}
type STrajectory struct {
UserId string `bson:"UserId" json:"UserId"` // 用户ID
Location SLocation `bson:"Location" json:"Location"`
Time int64 `bson:"Time" json:"Time"`
}
type SLocation struct {
Latitude float64 `bson:"Latitude" json:"Latitude"` //纬度
Longitude float64 `bson:"Longitude" json:"Longitude"` //经度
}
type SEventLog struct {
UserId string `bson:"UserId" json:"UserId"` // 用户ID
UserName string `bson:"UserName" json:"UserName"` //用户名称
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"`
Price string `bson:"Price" json:"Price"`
ShopName string `bson:"ShopName" json:"ShopName"`
ItemId string `bson:"ItemId" json:"ItemId"` //项目id
KvPhoto string `bson:"KvPhoto" json:"KvPhoto"` //用于列表页的图片
TopPhoto []SPicture `bson:"TopPhoto" json:"TopPhoto"` //详情页最上面的轮播图
Images []string `bson:"Images" json:"Images"` //详情页下面的产品详细图
}
type SLine struct {
Id *bson.ObjectId `bson:"_id" json:"Id" valid:"required"`
Name string `bson:"Name" json:"Name"`
SubName string `bson:"SubName" json:"SubName"` //游玩时长
Location []SLocation `bson:"Location" json:"Location"` //线路点坐标
PlayDuration string `bson:"PlayDuration" json:"PlayDuration"`
Suitable string `bson:"Suitable" json:"Suitable"` //适合人群
Content string `bson:"Content" json:"Content"`
Distance string `bson:"Distance" json:"Distance"` // 距离
Annotations []string `bson:"Annotations" json:"Annotations"` //需要点亮的设施id
}
type SComplaint struct {
Type string `bson:"Type" json:"Type"`
ScenicId string `bson:"ScenicId" json:"ScenicId"` // 景区id
Mobile string `bson:"Mobile" json:"Mobile"`
FullName string `bson:"FullName" json:"FullName"`
Sex string `bson:"Sex" json:"Sex"`
Content string `bson:"Content" json:"Content"`
Image []string `bson:"Image" json:"Image"`
}
type SInvestigation struct {
UserId string `bson:"UserId" json:"UserId"` // 用户ID
Mobile string `bson:"Mobile" json:"Mobile"` //手机号
Data interface{} `bson:"Data" json:"Data"`
}
type SMember struct {
Id *bson.ObjectId `bson:"_id" json:"Id" valid:"required"`
Password string `bson:"Password" json:"Password"`
Birthday string `bson:"Birthday" json:"Birthday"`
FullName string `bson:"FullName" json:"FullName"`
Mobile string `bson:"Mobile" json:"Mobile"`
Openid string `bson:"Openid" json:"Openid"`
Token string `bson:"Token" json:"Token"`
Sex string `bson:"Sex" json:"Sex"`
}
type STag struct {
Type string `bson:"Type" json:"Type"`
Name string `bson:"Name" json:"Name"`
}
type SPicture struct {
Src string `bson:"Src" json:"Src"`
Link string `bson:"Link" json:"Link"`
}
type SScenic struct {
Id *bson.ObjectId `bson:"_id" json:"Id" valid:"required"`
Name string `bson:"Name" json:"Name"`
Describe string `bson:"Describe" json:"Describe"`
OpenHours string `bson:"OpenHours" json:"OpenHours"` //营业时间
Mobile string `bson:"Mobile" json:"Mobile"`
Address string `bson:"Address" json:"Address"`
Location SLocation `bson:"Location" json:"Location"`
Picture []SPicture `bson:"Picture" json:"Picture"`
ShopAdPicture []SPicture `bson:"ShopAdPicture" json:"ShopAdPicture"` //商城列表页图片
ItemScenicPicture []SPicture `bson:"ItemScenicPicture" json:"ItemScenicPicture"` //项目场次照片
ActivityPicture []SPicture `bson:"ActivityPicture" json:"ActivityPicture"` //活动照片
VideoList []SPicture `bson:"VideoList" json:"VideoList"`
}
leyoutu_server.git/Lib/ 0000775 0000000 0000000 00000000000 13616430655 0015453 5 ustar 00root root 0000000 0000000 leyoutu_server.git/Lib/Cache/ 0000775 0000000 0000000 00000000000 13616430655 0016456 5 ustar 00root root 0000000 0000000 leyoutu_server.git/Lib/Cache/redis.go 0000664 0000000 0000000 00000004121 13616430655 0020111 0 ustar 00root root 0000000 0000000 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
}
leyoutu_server.git/Lib/Code.go 0000664 0000000 0000000 00000000502 13616430655 0016651 0 ustar 00root root 0000000 0000000 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()
} leyoutu_server.git/Lib/DelayMessage/ 0000775 0000000 0000000 00000000000 13616430655 0020016 5 ustar 00root root 0000000 0000000 leyoutu_server.git/Lib/DelayMessage/delaymessage.go 0000664 0000000 0000000 00000015505 13616430655 0023016 0 ustar 00root root 0000000 0000000 package DelayMessage
import (
"encoding/json"
"fmt"
"github.com/pkg/errors"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"io/ioutil"
"net/http"
"strconv"
"sync"
"time"
)
// 延迟消息
var CDelayMessage *mgo.Collection
var CDelayErrorLog *mgo.Collection
var GlobalDM *DelayMessage
type Message struct {
Id *bson.ObjectId `bson:"_id" json:"_id"`
//延时时间
DelayTime int64
//callbackUrl
CallbackUrl string `bson:"CallbackUrl" json:"CallbackUrl"`
//失败次数
Fail int
// 类型0=geturl;1=发送app消息
Type int8 `bson:"Type" json:"Type"`
Title string `bson:"Title" json:"Title"`
Content string `bson:"Content" json:"Content"`
UDID string `bson:"UDID" json:"UDID"`
UserId string `bson:"UserId" json:"UserId"`
}
// addTask
func (dm *DelayMessage) AddTaskForGetUrl(delayTime string, userid string, callbackUrl string) error {
iTIme, _ := strconv.Atoi(delayTime)
i64Time := int64(iTIme)
nowTimeU := time.Now().Unix()
iDelayTIme := i64Time - nowTimeU
if i64Time <= nowTimeU {
return errors.New("delayTime error...")
}
if callbackUrl == "" {
return errors.New("callbackUrl error...")
}
objectID := bson.NewObjectId()
_Message := &Message{&objectID, i64Time, callbackUrl, 0, 0, "", "", "", userid}
CDelayMessage.Insert(_Message)
//添加任务
//iDelayTIme = 3
dm.AddTask(time.Now().Add(time.Second*time.Duration(iDelayTIme)), Callback, _Message)
fmt.Println("增加新任务:", "当前位置", dm.curIndex, ",", iDelayTIme, "秒后触发", _Message.CallbackUrl)
println(objectID.Hex())
return nil
}
func (dm *DelayMessage) AddTaskForAppMessage(delayTime string, udid string, title string, content string, userid string) error {
iTIme, _ := strconv.Atoi(delayTime)
i64Time := int64(iTIme)
nowTimeU := time.Now().Unix()
iDelayTIme := i64Time - nowTimeU
if i64Time <= nowTimeU {
return errors.New("delayTime error...")
}
if udid == "" {
return errors.New("udid error...")
}
if title == "" {
return errors.New("title error...")
}
if content == "" {
return errors.New("content error...")
}
if userid == "" {
return errors.New("userid error...")
}
objectID := bson.NewObjectId()
_Message := &Message{&objectID, i64Time, "", 0, 1, title, content, udid, userid}
CDelayMessage.Insert(_Message)
//添加任务
//iDelayTIme = 3
dm.AddTask(time.Now().Add(time.Second*time.Duration(iDelayTIme)), Callback, _Message)
fmt.Println("增加新任务:", "当前位置", dm.curIndex, ",", iDelayTIme, "秒后触发", _Message.Title)
//println(objectID.Hex())
return nil
}
// delTask
func (dm *DelayMessage) DelTaskForId(id string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("[E]", r)
}
}()
CDelayMessage.Remove(bson.M{"_id": bson.ObjectIdHex(id)})
i := dm.DelTask(id)
println("删除定时任务:",strconv.Itoa(i))
}
func (dm *DelayMessage) Show() {
//取出当前的槽的任务
fmt.Println("---------------------------------")
for k, _ := range dm.slots {
tasks := dm.slots[k]
for _, v2 := range tasks {
fmt.Println("当前秒数:", dm.curIndex, "下一任务:", k, "圈数:", v2.cycleNum, v2.params.CallbackUrl)
}
}
fmt.Println("---------------------------------")
}
func Callback(key *bson.ObjectId, message *Message) {
var body string
var err error
if message.Type == 0 {
body, err = HttpGet(message.CallbackUrl)
if err != nil {
//fmt.Println(err,message)
}
} else if message.Type == 1 {
}
json, _ := json.Marshal(message)
if body != "ok" {
CDelayMessage.Remove(bson.M{"_id": *key})
fmt.Println("完成任务:", string(json))
} else {
//message.Fail++
//if message.Fail == 3 {
// fmt.Println(color.Red("放弃任务:"), message.CallbackUrl)
// CDelayMessage.Remove(bson.M{"_id": *key})
// dbErrorLog.Insert(message)
//} else {
// fmt.Println("重新添加任务:", message)
// dm.AddTask(time.Now().Add(time.Second*10), key, callback, message)
//}
fmt.Println("放弃任务:", string(json))
//CDelayMessage.Remove(bson.M{"_id": *key})
CDelayErrorLog.Insert(message)
}
}
type DelayMessage struct {
//当前下标
curIndex int
//环形槽
sync.RWMutex
slots [3600]map[*bson.ObjectId]*Task
//启动时间
startTime time.Time
}
//执行的任务函数
type TaskFunc func(key *bson.ObjectId, message *Message)
//任务
type Task struct {
//循环次数
cycleNum int
//执行的函数
exec TaskFunc
params *Message
}
//创建一个延迟消息
func NewDelayMessage() *DelayMessage {
dm := &DelayMessage{
curIndex: 0,
startTime: time.Now(),
}
for i := 0; i < 3600; i++ {
dm.slots[i] = make(map[*bson.ObjectId]*Task)
}
return dm
}
//启动延迟消息
func (dm *DelayMessage) Start() {
//go dm.taskLoop()
go dm.timeLoop()
select {}
}
//处理每1秒的任务
func (dm *DelayMessage) taskLoop() {
//取出当前的槽的任务
tasks := dm.slots[dm.curIndex]
if len(tasks) > 0 {
//遍历任务,判断任务循环次数等于0,则运行任务
//否则任务循环次数减1
for k, v := range tasks {
if v.cycleNum == 0 {
go v.exec(k, v.params)
//删除运行过的任务
dm.RLock()
delete(tasks, k)
dm.RUnlock()
} else {
v.cycleNum--
}
}
}
}
//处理每1秒移动下标
func (dm *DelayMessage) timeLoop() {
defer func() {
fmt.Println("timeLoop exit")
}()
for {
time.Sleep(time.Second)
//fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
//判断当前下标,如果等于3599则重置为0,否则加1
dm.taskLoop()
if dm.curIndex == 3599 {
dm.curIndex = 0
} else {
dm.curIndex++
}
}
}
//添加任务
func (dm *DelayMessage) AddTask(t time.Time, exec TaskFunc, message *Message) error {
if dm.startTime.After(t) {
return errors.New("时间错误")
}
//计算循环次数
cycleNum := int((t.Unix() - time.Now().Unix()) / 3600)
//计算任务所在的slots的下标
ix := (t.Unix() - time.Now().Unix() + int64(dm.curIndex)) % 3600
fmt.Println("AddTask-----", cycleNum, "圈后的第", ix, "位")
//把任务加入tasks中
tasks := dm.slots[ix]
//if _, ok := tasks[key]; ok {
// return errors.New("该slots中已存在key为" + key + "的任务")
//}
dm.Lock()
tasks[message.Id] = &Task{
cycleNum: cycleNum,
exec: exec,
params: message,
}
dm.Unlock()
return nil
}
//删除任务
func (dm *DelayMessage) DelTask(key string) int {
i := 0
for _, v := range dm.slots {
for k2, _ := range v {
if key == k2.Hex() {
i++
delete(v, k2)
}
}
}
return i
}
var c = &http.Client{
Timeout: 5 * time.Second,
}
func HttpGet(url string) (string, error) {
//fmt.Println(color.Yellow("http request: "), color.Yellow(url))
resp, err := c.Get(url)
if err != nil {
return "", err
}
defer func() {
if err := recover(); err == nil {
resp.Body.Close()
}
}()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
sBody := string(body)
//fmt.Println(color.Yellow(sBody))
return sBody, nil
}
leyoutu_server.git/Lib/Ws/ 0000775 0000000 0000000 00000000000 13616430655 0016044 5 ustar 00root root 0000000 0000000 leyoutu_server.git/Lib/Ws/Ws.go 0000664 0000000 0000000 00000003331 13616430655 0016764 0 ustar 00root root 0000000 0000000 package Ws
import (
"encoding/json"
"github.com/gorilla/websocket"
)
// ClientManager is a websocket manager
type ClientManager struct {
Clients map[*Client]bool
Broadcast chan []byte
Register chan *Client
Unregister chan *Client
}
// Client is a websocket client
type Client struct {
ID string
Socket *websocket.Conn
}
// Message is an object for websocket message which is mapped to json type
type Message struct {
Sender string `json:"sender,omitempty"`
Recipient string `json:"recipient,omitempty"`
Content string `json:"content,omitempty"`
}
// Manager define a ws server manager
var Manager = ClientManager{
Broadcast: make(chan []byte),
Register: make(chan *Client),
Unregister: make(chan *Client),
Clients: make(map[*Client]bool),
}
// Start is to start a ws server
func (manager *ClientManager) Start() {
for {
select {
case conn := <-manager.Register:
manager.Clients[conn] = true
jsonMessage, _ := json.Marshal(&Message{Content: "/A new socket has connected."})
manager.Send(jsonMessage, conn)
case conn := <-manager.Unregister:
if _, ok := manager.Clients[conn]; ok {
delete(manager.Clients, conn)
jsonMessage, _ := json.Marshal(&Message{Content: "/A socket has disconnected."})
manager.Send(jsonMessage, conn)
}
case message := <-manager.Broadcast:
for conn := range manager.Clients {
conn.Socket.WriteMessage(1, message)
}
}
}
}
// Send is to send ws message to ws client
func (manager *ClientManager) Send(message []byte, ignore *Client) {
for conn := range manager.Clients {
if conn != ignore {
conn.Socket.WriteMessage(1, message)
}
}
}
func (c *Client) Send(message []byte) {
c.Socket.WriteMessage(websocket.TextMessage, message)
} leyoutu_server.git/README.md 0000664 0000000 0000000 00000042743 13616430655 0016236 0 ustar 00root root 0000000 0000000
## 乐游图后端接口文档
| Specification | Value |
|-----|-----|
| API Version | 1.0.0 |
| BasePath | https://letu.api.imagchina.com |
### API List
1. [查询所有商品](#allcommodity-get)
1. [设备管理 - 获得所有设备的等待时间](#allitemtime-get)
1. [查询所有游玩项目](#allitems-get)
1. [查询所有线路](#allline-get)
1. [所有景区基础信息](#allscenic-get)
1. [查询商品信息](#commodityinfo-get)
1. [增加投诉](#createcomplaint-post)
1. [查询用户的定时提醒](#dealymessage-info-get)
1. [创建提醒](#dealymessage-create-post)
1. [删除提醒](#dealymessage-remove-post)
1. [增加访问日志](#eventlog-post)
1. [增加调查](#investigation-save-post)
1. [设备管理 - 查询设备信息](#iteminfo-get)
1. [查询线路信息](#lineinfo-get)
1. [用户管理 - 用户登录&注册](#loginuser-post)
1. [返回景区基础信息](#scenicinfo-get)
1. [发送短信验证码](#sms-send-post)
1. [标签列表](#tags-get)
1. [保存用户移动轨迹](#trajectory-save-post)
1. [更新商品](#updatecommodity-post)
1. [设备管理 - 更新设施](#updateitem-post)
1. [设备管理 - 更新等待时间](#updateitemtime-post)
1. [更新线路](#updateline-post)
1. [更新景区基础信息](#updatescenic-post)
1. [用户管理 - 修改用户信息](#updateuser-post)
1. [上传](#upload-post)
1. [用户管理 - 获取用户信息](#userinfo-get)
#### /AllCommodity (GET)
查询所有商品
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | Price=价格;ShopName=店铺名称;KvPhoto用于列表页的图片;TopPhoto详情页最上面的轮播图;Images详情页下面的产品详细图 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /AllItemTime (GET)
设备管理 - 获得所有设备的等待时间
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {5df864740a9ac17ac7a7feb8: '20',.....} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {} |
#### /AllItems (GET)
查询所有游玩项目
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | Tags所属标签,标签有分类;LimitHeight限高;PlayDuration游玩时长;SceneTime场次时间;Picture照片;Voice音频;AverageConsumption平均消费;Menu菜单 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /AllLine (GET)
查询所有线路
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | Name名称;SubName副标题;PlayDuration游玩时长;Suitable适合人群;Location线路点坐标;Annotations需要点亮的设施id;Distance距离 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /AllScenic (GET)
所有景区基础信息
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /CommodityInfo (GET)
查询商品信息
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| id | 5dfb03070a9ac17ac7a82054 | string | id | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | Price=价格;ShopName=店铺名称;KvPhoto用于列表页的图片;TopPhoto详情页最上面的轮播图;Images详情页下面的产品详细图 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /CreateComplaint (POST)
增加投诉
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| Mobile | 18616619599 | string | 联系电话 | Yes |
| Name | 高先生 | string | 姓名 | Yes |
| Code | 123456 | string | 验证码 | Yes |
| Sex | 男 | string | 性别 | Yes |
| ScenicId | 5e1ed07524e03431008b4572 | string | 景区id | Yes |
| Type | 1 | string | 类型 | Yes |
| Content | 卫生不干净 | string | 投诉内容 | Yes |
| Image | ["http://www.xx.com/123.jpg","http://www.xx.com/123.jpg"] | string | 照片数组 | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":"ok"} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /DealyMessage/Info (GET)
查询用户的定时提醒
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| UserId | 5dfb03070a9ac17ac7a82054 | string | 用户id | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | DelayTime=执行时间;Type=类型(0请求url地址1发送app通知);Fail失败次数;Title=通知标题;Content=通知内容;UDID=设备id |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /DealyMessage/Create (POST)
创建提醒
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| UserId | 5dfb03070a9ac17ac7a82054 | string | 用户id | Yes |
| UDID | 5dfb03070a9ac17ac7a82054 | string | 设备id | Yes |
| Title | 表演时间提醒 | string | 标题 | Yes |
| Content | 5分钟后有表演 | string | 内容 | Yes |
| DelayTime | 1579066863 | string | 到达这个时间戳就执行 | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":"ok"} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /DealyMessage/Remove (POST)
删除提醒
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| id | 5dfb03070a9ac17ac7a82054 | string | 提醒id | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":"ok"} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /EventLog (POST)
增加访问日志
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| UserId | 5dfb03070a9ac17ac7a82054 | string | 用户ID | Yes |
| UserName | Aaron | string | 用户名称 | Yes |
| TypeNum | 9 | int | 类型编号 | Yes |
| TypeName | 点击个人中心 | string | 类型名称 | Yes |
| DateTime | 1578556751220 | int | 时间戳 | Yes |
| Location | {"Latitude": 119, "Longitude": 39} | string | 位置 | Yes |
| Remarks | 备注 | string | 备注 | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /Investigation/Save (POST)
增加调查
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| UserId | 1111111 | string | UserId | Yes |
| Mobile | 18616619599 | string | 联系电话 | Yes |
| type | 1 | string | 类型 | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":"ok"} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /ItemInfo (GET)
设备管理 - 查询设备信息
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| id | 5dfb03070a9ac17ac7a82054 | string | 设备id | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":{"Name":"名称","Describe":"介绍","OpenHours":"开放时间","Mobile":"电话","Address":"地址","SLocation":{"Latitude":0,"Longitude":0},"Picture":["照片1","照片2"]}} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /LineInfo (GET)
查询线路信息
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| id | 5dfb03070a9ac17ac7a82054 | string | id | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | Name名称;SubName副标题;PlayDuration游玩时长;Suitable适合人群;Location线路点坐标;Annotations需要点亮的设施id;Distance距离 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /LoginUser (POST)
用户管理 - 用户登录&注册
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| Mobile | aaron | string | 手机号 | Yes |
| Password | 1 | string | 密码或验证码(使用验证码的新手机号自动注册) | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":{"Id":"5e09c64c1c09c6f0f7ca2fa9","Token":"640bf934e425aba5d3c90998b2641f2f0ca07261d334d9615d1cd4790b5f34e7"}} 调用其它需要登陆的接口时携带token,有过期时间 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /ScenicInfo (GET)
返回景区基础信息
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| id | 5dfb03070a9ac17ac7a82054 | string | 景区id | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | Name名称;Describe介绍;OpenHours营业时间;Picture最上面图片;ShopAdPicture商城列表页图片;ItemScenicPicture项目场次照片;ActivityPicture活动照片;VideoList视频 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /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"}验证码1分钟内有效 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /Tags (GET)
标签列表
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":[{"Type":"menu","Name":"服务设施"},{"Type":"normal","Name":"不错"},{"Type":"thrilling","Name":"刺激"},{"Type":"recommend","Name":"必玩"}]} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /Trajectory/Save (POST)
保存用户移动轨迹
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| UserId | 5dfb03070a9ac17ac7a82054 | string | 用户id | Yes |
| Location | {"Latitude": 119, "Longitude": 39} | string | 经纬度 | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":"ok"} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /UpdateCommodity (POST)
更新商品
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /UpdateItem (POST)
设备管理 - 更新设施
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | Tags所属标签,标签有分类;LimitHeight限高;PlayDuration游玩时长;SceneTime场次时间;Picture照片;Voice音频;AverageConsumption平均消费;Menu菜单 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /UpdateItemTime (POST)
设备管理 - 更新等待时间
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| item | [{"id":"5df864740a9ac17ac7a7feb8","time":"20"},{"id":"5df8660924e03417008b4567","time":"33"}] | string | 设备列表 | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {errcode: 0, result: "ok"} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /UpdateLine (POST)
更新线路
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /UpdateScenic (POST)
更新景区基础信息
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| id | 5dfb03070a9ac17ac7a82054 | string | 景区id | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | Name名称;Describe介绍;OpenHours营业时间;Picture最上面图片;ShopAdPicture商城列表页图片;ItemScenicPicture项目场次照片;ActivityPicture活动照片;VideoList视频 |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /UpdateUser (POST)
用户管理 - 修改用户信息
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| Password | 1 | string | 密码 | Yes |
| ConfirmPassword | 1 | string | 确认密码 | Yes |
| Birthday | 2010.10.10 | string | 生日 | Yes |
| Fullname | aarongao | string | 全名 | Yes |
| Code | 12345678 | string | 6位验证码 | Yes |
| Mobile | 18616619599 | string | 手机,同用户名 | Yes |
| Sex | 男 | string | 性别 | Yes |
| Openid | 12345 | string | 微信id | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":"ok"} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /Upload (POST)
上传
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| file | 1 | file | 文件 | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":"图片地址"} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
#### /UserInfo (GET)
用户管理 - 获取用户信息
| Param Name | Example | Data Type | Description | Required? |
|-----|-----|-----|-----|-----|
| id | aaron | string | 用户id | Yes |
| Code | Type | Model | Message |
|-----|-----|-----|-----|
| 200 | object | [ResponseSeccess](#github.com.aarongao.tools.ResponseSeccess) | {"errcode":0,"result":{"Id":"5e09c64c1c09c6f0f7ca2fa9","Token":"640bf934e425aba5d3c90998b2641f2f0ca07261d334d9615d1cd4790b5f34e7"}} |
| 500 | object | [ResponseError](#github.com.aarongao.tools.ResponseError) | {"errcode":1,"errmsg":"错误原因"} |
leyoutu_server.git/main.go 0000664 0000000 0000000 00000006655 13616430655 0016234 0 ustar 00root root 0000000 0000000 package main
import (
"encoding/json"
"github.com/aarongao/tools"
"github.com/gin-gonic/gin"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"letu/Api"
"letu/Config"
"letu/DB"
"letu/Lib/Cache"
"letu/Lib/DelayMessage"
"os"
"time"
)
// @APIVersion 1.0.0
// @APITitle 乐游图后端接口文档
// @BasePath https://letu.api.imagchina.com
func main() {
// 读取配置文件
dir, _ := os.Getwd()
//println(dir)
file, _ := os.Open(dir + "/Config/config.json")
defer file.Close()
decoder := json.NewDecoder(file)
conf := Config.Config{}
err := decoder.Decode(&conf)
tools.CheckError(err)
// 连接数据库
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)
//获取文档集
DB.DB = DB.DBSession.DB("LeYouTu")
DB.CItem = DB.DB.C("Item")
DB.CComplaint = DB.DB.C("Complaint")
DB.CInvestigation = DB.DB.C("Investigation")
DB.CMember = DB.DB.C("Member")
DB.CCommodity = DB.DB.C("Commodity")
DB.CTags = DB.DB.C("Tags")
DB.CScenic = DB.DB.C("Scenic")
DB.CLine = DB.DB.C("Line")
DB.CEventLog = DB.DB.C("EventLog")
DB.CActionLog = DB.DB.C("ActionLog")
DB.CInvestigation = DB.DB.C("Investigation")
DB.CTrajectory = DB.DB.C("Trajectory")
DelayMessage.CDelayMessage = DB.DB.C("DelayMessage")
DelayMessage.CDelayErrorLog = DB.DB.C("DelayErrorLog")
r := gin.Default()
//r.Static("/.well-known", "./.well-known/")
//r.Static("/tiles", dir+"/tiles")
r.GET("/Tiles", Api.Tiles)
r.GET("/AllItems", Api.AllItems)
r.GET("/AllItemTime", Api.AllItemTime)
r.GET("/AllCommodity", Api.AllCommodity)
r.GET("/AllLine", Api.AllLine)
r.GET("/ItemInfo", Api.ItemInfo)
r.GET("/CommodityInfo", Api.CommodityInfo)
r.POST("/CreateComplaint", Api.CreateComplaint)
//r.POST("/CreateUser", Api.CreateUser)
r.POST("/LoginUser", Api.LoginUser)
r.POST("/UpdateUser", Api.UpdateUser)
r.GET("/UserInfo", Api.UserInfo)
r.GET("/ScenicInfo", Api.ScenicInfo)
r.GET("/LineInfo", Api.LineInfo)
r.GET("/AllTag", Api.AllTag)
r.POST("/Upload", Api.Upload)
r.POST("/UpdateItem", Api.UpdateItem)
r.POST("/UpdateCommodity", Api.UpdateCommodity)
r.POST("/UpdateLine", Api.UpdateLine)
r.POST("/UpdateScenic", Api.UpdateScenic)
r.POST("/UpdateItemTime", Api.UpdateItemTime)
r.GET("/AllScenic", Api.AllScenic)
r.POST("/EventLog", Api.EventLog)
r.GET("/EventLog", Api.EventLog)
r.POST("/Sms/Send", Api.Send)
r.POST("/Investigation/Save", Api.SaveInvestigation)
r.POST("/Trajectory/Save", Api.SaveTrajectory)
r.POST("/DealyMessage/Create", Api.CreateDealyMessage)
r.GET("/DealyMessage/Info", Api.DealyMessageInfo)
r.POST("/DealyMessage/Remove", Api.RemoveDealyMessage)
//r.GET("/ws", Api.WsPage)
r.Static("/Upload", "./Upload")
r.Static("/Console", "./Console")
// go Ws.Manager.Start()
// 创建延迟消息
DelayMessage.GlobalDM = DelayMessage.NewDelayMessage()
go func() {
DelayMessage.GlobalDM.Start()
}()
// -初始化数据
var aMessage []DelayMessage.Message
DelayMessage.CDelayMessage.Find(bson.M{}).All(&aMessage)
nowTimeU := time.Now().Unix()
for i := 0; i < len(aMessage); i++ {
iDelayTIme := aMessage[i].DelayTime - nowTimeU
if iDelayTIme < 0 {
iDelayTIme = 1
}
DelayMessage.GlobalDM.AddTask(time.Now().Add(time.Second*time.Duration(iDelayTIme)), DelayMessage.Callback, &aMessage[i])
}
println("增加", len(aMessage), "条提醒任务")
r.Run(":8080")
}