添加部分功能

master
kanade 5 years ago
parent 4be28a4b80
commit fc07641fa2

@ -0,0 +1,5 @@
package constant
const (
RedisKeyPromotionGoodsList = "lists:promotion:goods"
)

@ -65,3 +65,16 @@ func (g *Goods) BrandGoodsList(c *gin.Context) {
list := (&goods.Goods{}).GoodsListByBrandId(argsBrandGoodsList.BrandId, argsBrandGoodsList.Page) list := (&goods.Goods{}).GoodsListByBrandId(argsBrandGoodsList.BrandId, argsBrandGoodsList.Page)
back.Suc(c, "操作成功", list) back.Suc(c, "操作成功", list)
} }
func (g *Goods) Hot(c *gin.Context) {
args := lib.Page{}
if err := tools.ParseParams(&args, c); err != nil {
back.Fail(c, err.Error())
return
}
list, total := (&goods.Goods{}).HotGoods(args)
back.Suc(c, "操作成功", gin.H{
"total": total,
"list": list,
})
}

@ -294,19 +294,20 @@ type argsLiveId struct {
} }
type replyLiveInfo struct { type replyLiveInfo struct {
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
HeadImgUrl string `json:"headImgUrl"` HeadImgUrl string `json:"headImgUrl"`
PlayUrl string `json:"playUrl"` PlayUrl string `json:"playUrl"`
UserId uint `json:"userId"` UserId uint `json:"userId"`
Id uint `json:"id"` Id uint `json:"id"`
IsFollow int `json:"isFollow"` IsFollow int `json:"isFollow"`
IsPraise int `json:"isPraise"` IsPraise int `json:"isPraise"`
Praise int `json:"praise"` Praise int `json:"praise"`
GoodsLists []GoodsItem `json:"goodsLists"` GoodsLists []GoodsItem `json:"goodsLists"`
GroupId string `json:"groupId"` GroupId string `json:"groupId"`
Topic uint `json:"topic"` Topic uint `json:"topic"`
Title string `json:"title"` Title string `json:"title"`
Cover string `json:"cover"` Cover string `json:"cover"`
InvitationNo string `json:"invitationNo"`
} }
type GoodsItem struct { type GoodsItem struct {
@ -385,19 +386,20 @@ func (l *Live) LiveInfo(c *gin.Context) {
topicInfo := (&topic.Topic{}).GetById(liveItem.Topic) topicInfo := (&topic.Topic{}).GetById(liveItem.Topic)
reply := replyLiveInfo{ reply := replyLiveInfo{
Nickname: (*users)[0].Nickname, Nickname: (*users)[0].Nickname,
HeadImgUrl: (*users)[0].HeadImgUrl, HeadImgUrl: (*users)[0].HeadImgUrl,
PlayUrl: tencent.Live.GetPlayUrl(liveRoom.StreamName, liveItem.Id), InvitationNo: (*users)[0].InvitationNo,
GroupId: liveRoom.GroupId, PlayUrl: tencent.Live.GetPlayUrl(liveRoom.StreamName, liveItem.Id),
UserId: liveItem.UserId, GroupId: liveRoom.GroupId,
Id: liveItem.Id, UserId: liveItem.UserId,
Cover: liveItem.Cover, Id: liveItem.Id,
IsFollow: isFollow, Cover: liveItem.Cover,
IsPraise: isPraise, IsFollow: isFollow,
Praise: liveData.Praise, IsPraise: isPraise,
GoodsLists: goodsList, Praise: liveData.Praise,
Topic: liveItem.Topic, GoodsLists: goodsList,
Title: topicInfo.Title, Topic: liveItem.Topic,
Title: topicInfo.Title,
} }
back.Suc(c, "操作成功", reply) back.Suc(c, "操作成功", reply)
} }
@ -467,16 +469,17 @@ func (l *Live) VideoInfo(c *gin.Context) {
} }
reply := replyLiveInfo{ reply := replyLiveInfo{
Nickname: (*users)[0].Nickname, Nickname: (*users)[0].Nickname,
HeadImgUrl: (*users)[0].HeadImgUrl, HeadImgUrl: (*users)[0].HeadImgUrl,
PlayUrl: liveItem.VideoUrl, InvitationNo: (*users)[0].InvitationNo,
UserId: liveItem.UserId, PlayUrl: liveItem.VideoUrl,
Id: liveItem.Id, UserId: liveItem.UserId,
Cover: liveItem.Cover, Id: liveItem.Id,
IsFollow: isFollow, Cover: liveItem.Cover,
IsPraise: isPraise, IsFollow: isFollow,
Praise: liveData.Praise, IsPraise: isPraise,
GoodsLists: goodsList, Praise: liveData.Praise,
GoodsLists: goodsList,
} }
back.Suc(c, "操作成功", reply) back.Suc(c, "操作成功", reply)
} }

@ -37,6 +37,29 @@ func (t *Topic) List(c *gin.Context) {
}) })
} }
type argsAdd struct {
Title string `json:"title" form:"title"`
}
// @Title 添加话题
func (t *Topic) Add(c *gin.Context) {
args := argsAdd{}
if err := tools.ParseParams(&args, c); err != nil {
back.Fail(c, err.Error())
return
}
if args.Title == "" {
back.Fail(c, "参数错误")
return
}
if err := (&topic.Topic{}).Add(args.Title); err != nil {
back.Fail(c, err.Error())
return
}
back.Suc(c, "操作成功", "")
}
// @Title 话题列表 // @Title 话题列表
func (t *Topic) Hot(c *gin.Context) { func (t *Topic) Hot(c *gin.Context) {
list := (&topic.Topic{}).Hot() list := (&topic.Topic{}).Hot()

@ -0,0 +1,36 @@
package aliyun
import (
"io/ioutil"
"live/app/lib/config"
"net/http"
"strings"
)
var (
client = &http.Client{}
appCode = config.Config.Section("aliyun").Key("appCode").String()
)
// @Title 请求
func request(method, url, data string, headers ...map[string]string) ([]byte, error) {
reqest, err := http.NewRequest(method, url, strings.NewReader(data))
if err != nil {
return nil, err
}
if len(headers) > 0 {
for key, value := range headers[0] {
reqest.Header.Add(key, value)
}
}
response, err := client.Do(reqest)
if err != nil {
return nil, err
}
defer response.Body.Close()
result, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
}
return result, nil
}

@ -0,0 +1,62 @@
package aliyun
// @Title 文本检测
import (
"encoding/json"
"net/url"
)
const (
actionTextUrl = "http://monitoring.market.alicloudapi.com/neirongjiance"
)
type text struct {
}
var (
Text = &text{}
)
type textResult struct {
Success bool `json:"success"`
Status int `json:"status"`
Data struct {
Out []CheckText `json:"out"`
} `json:"data"`
}
type CheckText struct {
Politics []string `json:"政治敏感监测"`
Contraband []string `json:"违禁品监测"`
Irrigation []bool `json:"恶意灌水监测"`
Salacity []string `json:"色情监测"`
Abuse []string `json:"辱骂监测"`
}
// @Title 敏感词检测
func (o *text) CheckText(text string) (result CheckText, err error) {
data := url.Values{
"in": []string{text},
}
resByte, err := o.exec(actionTextUrl, data.Encode())
if err != nil {
return
}
res := textResult{}
err = json.Unmarshal(resByte, &res)
if err != nil {
return
}
if len(res.Data.Out) > 0 {
result = res.Data.Out[0]
}
return
}
// @Title 执行请求
func (o *text) exec(action, data string) ([]byte, error) {
return request("POST", action, data, map[string]string{
"Authorization": "APPCODE " + appCode,
"Content-Type": "application/x-www-form-urlencoded",
})
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,52 @@
package db
import (
"github.com/go-redis/redis"
"live/app/lib/config"
"time"
)
type RedisConfig struct {
Name string `toml:"name"`
Proto string `toml:"proto"`
Addr string `toml:"addr"`
Idle int `toml:"idle"`
Active int `toml:"active"`
DialTimeout int `toml:"dialTimeout"`
ReadTimeout int `toml:"readTimeout"`
WriteTimeout int `toml:"writeTimeout"`
IdleTimeout int `toml:"idleTimeout"`
}
var (
Redis *redis.Client
)
func init() {
addr := config.Config.Section("redis").Key("addr").String()
password := config.Config.Section("redis").Key("password").String()
c := &RedisConfig{
Name: "recook.redis",
Addr: addr,
Idle: 10,
Active: 10,
DialTimeout: 1,
ReadTimeout: 1,
WriteTimeout: 1,
IdleTimeout: 10,
}
Redis = redis.NewClient(&redis.Options{
Addr: c.Addr,
Password: password,
DB: 0, // use default DB
ReadTimeout: time.Duration(c.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(c.WriteTimeout) * time.Second,
})
_, err := Redis.Ping().Result()
if err != nil {
panic(err)
}
}

@ -15,7 +15,7 @@ func (p *Page) GetPage() int {
} }
func (p *Page) GetLimit() int { func (p *Page) GetLimit() int {
if p.Limit >= config.Config.Section("page").Key("minLimit").MustInt(1) || p.Limit < config.Config.Section("page").Key("maxLimit").MustInt(100) { if p.Limit >= config.Config.Section("page").Key("minLimit").MustInt(1) && p.Limit < config.Config.Section("page").Key("maxLimit").MustInt(100) {
return p.Limit return p.Limit
} }
return config.Config.Section("page").Key("defaultLimit").MustInt(15) return config.Config.Section("page").Key("defaultLimit").MustInt(15)

@ -35,9 +35,10 @@ func (u *user) GetUserId(id uint, token string) uint {
} }
type ReplyUserItem struct { type ReplyUserItem struct {
UserId uint `json:"userId" mapstructure:"id"` UserId uint `json:"userId" mapstructure:"id"`
Nickname string `json:"nickname" mapstructure:"nickname"` Nickname string `json:"nickname" mapstructure:"nickname"`
HeadImgUrl string `json:"headImgUrl" mapstructure:"headImgUrl"` HeadImgUrl string `json:"headImgUrl" mapstructure:"headImgUrl"`
InvitationNo string `json:"invitationNo" mapstructure:"invitationNo"`
} }
// @Title 批量获取会员基础信息 // @Title 批量获取会员基础信息

@ -21,6 +21,7 @@ const (
action_useradd = "v4/im_open_login_svc/account_import" // 会员添加 action_useradd = "v4/im_open_login_svc/account_import" // 会员添加
action_userprofile = "v4/profile/portrait_set" // 会员资料信息修改 action_userprofile = "v4/profile/portrait_set" // 会员资料信息修改
action_groupadd = "v4/group_open_http_svc/create_group" // 群组添加 action_groupadd = "v4/group_open_http_svc/create_group" // 群组添加
action_groupdel = "v4/group_open_http_svc/destroy_group" // 群组解散
action_groupmessage = "v4/group_open_http_svc/send_group_system_notification" // 群组系统消息 action_groupmessage = "v4/group_open_http_svc/send_group_system_notification" // 群组系统消息
) )
@ -110,6 +111,20 @@ func (i *im) AddLiveGroup(userId, name, groupId string) error {
return i.Exec(action_groupadd, string(jsonData)) return i.Exec(action_groupadd, string(jsonData))
} }
// @Title 解散直播群
// @Param userId string true "im会员id"
// @Param name string true "直播群名称"
// @Param groupId string true "直播群id"
func (i *im) DelLiveGroup(groupId string) error {
jsonData, err := json.Marshal(map[string]string{
"GroupId": groupId,
})
if err != nil {
return err
}
return i.Exec(action_groupdel, string(jsonData))
}
// @Title 直播群发送消息 // @Title 直播群发送消息
// @Param groupId string true "直播群id" // @Param groupId string true "直播群id"
// @Param message string true "消息内容" // @Param message string true "消息内容"

@ -48,7 +48,7 @@ func (s *short) Sign() string {
random := Worker.Rander() random := Worker.Rander()
randomStr := strconv.FormatUint(uint64(random), 10) randomStr := strconv.FormatUint(uint64(random), 10)
original := "secretId=" + s.secretId + "&currentTimeStamp=" + timestampStr + "&expireTime=" + expireTimeStr + "&random=" + randomStr original := "secretId=" + s.secretId + "&currentTimeStamp=" + timestampStr + "&expireTime=" + expireTimeStr + "&random=" + randomStr + "&procedure=recook"
// 单次有效 // 单次有效
if s.oneTimeValid { if s.oneTimeValid {
original += "&oneTimeValid=1" original += "&oneTimeValid=1"

@ -1,8 +1,13 @@
package goods package goods
import ( import (
"encoding/json"
"live/app/constant"
"live/app/lib" "live/app/lib"
"live/app/lib/db"
"live/app/lib/recook" "live/app/lib/recook"
"live/app/model/promotion"
"time"
) )
type Goods struct { type Goods struct {
@ -28,3 +33,50 @@ func (g *Goods) GoodsListByBrandId(brandId uint, page lib.Page) *recook.GoodsLis
list, _ := recook.Goods.GetListByBrandId(brandId, page.GetPage(), page.GetLimit()) list, _ := recook.Goods.GetListByBrandId(brandId, page.GetPage(), page.GetLimit())
return list return list
} }
// @Title 指定品牌商品列表
func (g *Goods) HotGoods(page lib.Page) (result []recook.GoodsInfo, dataLen int) {
data := db.Redis.Get(constant.RedisKeyPromotionGoodsList).Val()
promotionGoods := []promotion.PromotionGoods{}
json.Unmarshal([]byte(data), &promotionGoods)
day := time.Now().Format("2006-01-02")
if len(promotionGoods) == 0 || promotionGoods[0].PromotionStartDate.Time.Format("2006-01-02") != day {
promotionGoodsModel := &promotion.PromotionGoods{}
lists := promotionGoodsModel.GetDayAll()
data := []promotion.PromotionGoods{}
index := 0
lastId := uint(0)
for _, list := range lists {
if lastId != list.PromotionTimeItemId {
index = 1
lastId = list.PromotionTimeItemId
}
if index > 5 {
continue
}
data = append(data, list)
index++
}
dataStr, _ := json.Marshal(data)
db.Redis.Set(constant.RedisKeyPromotionGoodsList, string(dataStr), time.Hour*24)
promotionGoods = data
}
dataLen = len(promotionGoods)
start := page.GetStart()
if dataLen >= start {
end := page.GetLimit() + start
if end > dataLen {
end = dataLen
}
goodsIds := []uint{}
for _, goods := range promotionGoods[start:end] {
goodsIds = append(goodsIds, goods.GoodsId)
}
ids, err := recook.Goods.GetListByIds(goodsIds)
if err != nil {
return
}
result = *ids
}
return
}

@ -57,6 +57,13 @@ func (l live) Start(userId uint, title, cover string, topic uint, goodsIds []uin
GroupId: groupId, GroupId: groupId,
} }
liveModel.Create(&liveRoom) liveModel.Create(&liveRoom)
} else {
err, info := ImLogic.LoginUserInfo(userId)
if err != nil {
return LiveInfo{}, err
}
if err = tencent.Im.AddLiveGroup(info.Identifier, "直播群", liveRoom.GroupId); err != nil {
}
} }
userAllFins := (&user.UserFollow{}).GetCountAll(userId) userAllFins := (&user.UserFollow{}).GetCountAll(userId)
liveItemModel := &live2.LiveItem{} liveItemModel := &live2.LiveItem{}
@ -145,6 +152,13 @@ func (l *live) Stop(userId, liveItemId uint) error {
liveDataModel := &live2.LiveData{} liveDataModel := &live2.LiveData{}
liveData := liveDataModel.GetByLiveItemId(liveItemId) liveData := liveDataModel.GetByLiveItemId(liveItemId)
// 解散直播群
liveRoom := live2.LiveRoom{}
userLiveRoom := liveRoom.GetLiveById(liveItem.RoomId)
if err := tencent.Im.DelLiveGroup(userLiveRoom.GroupId); err != nil {
log.Println(err)
}
return liveItemModel.Transaction(func(tx *gorm.DB) error { return liveItemModel.Transaction(func(tx *gorm.DB) error {
// 完成直播 // 完成直播
liveItemModel.SetDb(tx) liveItemModel.SetDb(tx)

@ -1,7 +1,9 @@
package topic package topic
import ( import (
"errors"
"live/app/lib" "live/app/lib"
"live/app/lib/aliyun"
"live/app/lib/config" "live/app/lib/config"
"live/app/model/topic" "live/app/model/topic"
) )
@ -24,6 +26,30 @@ func (t *Topic) List(keyword string, page lib.Page) (result *[]topic.Topic, coun
return return
} }
// @Title 添加话题
func (t *Topic) Add(title string) error {
topicModel := &topic.Topic{}
topicInfo := topicModel.GetByTitle(title)
if topicInfo.Id >= 0 {
return nil
}
text, err := aliyun.Text.CheckText(title)
if err != nil {
return err
}
if len(text.Politics) > 0 || len(text.Contraband) > 0 || len(text.Salacity) > 0 || len(text.Abuse) > 0 {
return errors.New("包含敏感词汇")
}
data := topic.Topic{
Title: title,
}
topicModel.Create(&data)
if data.Id <= 0 {
return errors.New("网络异常")
}
return nil
}
// @Title 获取热门话题 // @Title 获取热门话题
func (t *Topic) Hot() []topic.Topic { func (t *Topic) Hot() []topic.Topic {
topicModel := &topic.Topic{} topicModel := &topic.Topic{}

@ -0,0 +1,28 @@
package promotion
import (
"github.com/golangkit/formatime"
"live/app/lib/db"
"time"
)
type PromotionGoods struct {
db.BaseModel
Id uint `gorm:"column:id" json:"id"`
PromotionTimeItemId uint `gorm:"column:promotion_time_item_id" json:"promotionTimeItemId"`
GoodsId uint `gorm:"column:goods_id" json:"goodsId"`
PromotionStartDate formatime.Date `gorm:"column:promotion_start_date" json:"promotionStartDate"`
Order uint `gorm:"column:order" json:"order"`
}
func (p *PromotionGoods) TableName() string {
return "recook_promotion_goods"
}
// @Title 获取当日所有数据
func (p *PromotionGoods) GetDayAll() (result []PromotionGoods) {
day := time.Now().Format("2006-01-02")
day = "2020-09-19"
p.GetDb().Model(p).Where("promotion_start_date = ?", day).Order("promotion_time_item_id,`order`").Find(&result)
return
}

@ -80,3 +80,12 @@ func (t *Topic) AddPartake(topicId uint) int64 {
} }
return t.GetDb().Model(t).Where(Topic{Id: topicId}).Update("partake", gorm.Expr("partake + ?", 1)).RowsAffected return t.GetDb().Model(t).Where(Topic{Id: topicId}).Update("partake", gorm.Expr("partake + ?", 1)).RowsAffected
} }
// @Title 获取话题
func (t *Topic) GetByTitle(title string) (result Topic) {
if title == "" {
return
}
t.GetDb().Model(t).Where("title = ?", title).First(&result)
return
}

@ -41,6 +41,7 @@ func Router(router *gin.Engine) {
goodsR.POST("list", goodsC.List) // 商品列表 goodsR.POST("list", goodsC.List) // 商品列表
goodsR.POST("brandlist", goodsC.BrandList) // 品牌列表 goodsR.POST("brandlist", goodsC.BrandList) // 品牌列表
goodsR.POST("brandgoodslist", goodsC.BrandGoodsList) // 品牌商品列表 goodsR.POST("brandgoodslist", goodsC.BrandGoodsList) // 品牌商品列表
goodsR.POST("hot", goodsC.Hot) // 热门商品列表
} }
// 会员 // 会员
userR := liveRouter.Group("/user") userR := liveRouter.Group("/user")
@ -88,8 +89,9 @@ func Router(router *gin.Engine) {
topicR := liveRouter.Group("/topic") topicR := liveRouter.Group("/topic")
{ {
topicC := &topic.Topic{} topicC := &topic.Topic{}
topicR.POST("list", topicC.List) // 话题列表 topicR.POST("list", topicC.List) // 话题列表
topicR.POST("hot", topicC.Hot) // 热门话题 topicR.POST("add", auth, topicC.Add) // 话题列表
topicR.POST("hot", topicC.Hot) // 热门话题
topicR.POST("info", bothAuth, topicC.Info) // 话题基础信息 topicR.POST("info", bothAuth, topicC.Info) // 话题基础信息
topicR.POST("content/list", bothAuth, topicC.ContentList) // 话题内容列表 topicR.POST("content/list", bothAuth, topicC.ContentList) // 话题内容列表

@ -29,13 +29,13 @@ func (live *Live) Run() {
request1 := vod.NewConfirmEventsRequest() request1 := vod.NewConfirmEventsRequest()
for { for {
response, err := client.PullEvents(request) response, err := client.PullEvents(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok { if sdkErr, ok := err.(*errors.TencentCloudSDKError); ok {
log.Println("回调错误err:", err) if sdkErr.GetCode() == "ResourceNotFound" {
continue continue
} } else {
if err != nil { log.Println("回调错误err:", err)
log.Println("回调错误err:", err) continue
continue }
} }
handle := []string{} handle := []string{}
for _, event := range response.Response.EventSet { for _, event := range response.Response.EventSet {

@ -37,6 +37,9 @@ expire=600
oneTimeValid=1 oneTimeValid=1
key=c3nyGkDcot8aXKcgUZLe key=c3nyGkDcot8aXKcgUZLe
[aliyun]
appCode=1830f95365cb47488667ca1ef9aa9f6d
[recook] [recook]
url=https://api.reecook.cn/api/v1 url=https://api.reecook.cn/api/v1
private_key=MIIEowIBAAKCAQEAzNWyjYe3qt4YRTDwANxDPNLAJ9TZBuHsSqSjJM5B35fABwN3gwm5Q/SCz/6kgKTqeSgCVPFYhO/zOD6G8K7EJLgx95ZIeAB9EkW+xrhFDDthUZAkA03zHJO6SkFKOciLFVi94BdCdGlNFlnaBBqA+8XvCpD1V8DFc/9cpb5icZvngu8vEkwkbYceCXKUMNxoXY/E2cFe8f2tVFR5pRkQgRLbM70jt4yBGOD8pbuk6fcnD7ghGWgzMq/845N3wISSTp/gAQg8403Fk+8AoL+FKgxUkjUOpPI2XrcpQm0EphuAX4J0Xvo3Hu6TEPZYyqULEXGT2Jukmh0NSkNO0F39xwIDAQABAoIBAQCAqRYPWhkexYQ/Kb8G+1NsiABUxJhRf2UZeZJUEw5DcKEYhq/x6hCpw5LLLOqNN4lj8qKMUlBEqCeAw52k3lGrstsH5ii836mv6YksbyBHz6CQR9anELZM0+nmrF4AL5xVGzmg4VtHncDi8itD+pXcD3bXjzfcF+SuuM6r+QsCykgTc/jw+R6GqOHvD48mUQCI0/Xw6jjAWUUh0jRX2BvLQwcccan5ZCZD3C7M8gGuRFO2vr8lFliQwyFNgwrpE+brLeMNeLHz1S6vMwfqr3r4Mq78wTihoze+3kIs5tdE0YRkJpaPLdeCsvQ8iFfD9nat7wnNHgcQBU+3B+KjOJCZAoGBAOVC8AY8q0UeTFreo44Fgda9Jg+BsR0UwTzTxzozdwSMhIfzb6oDa6tWd8VO0V6FaqK+Urxj6UP3JshAQT8hsq6Hh8tEmUx3rxpQnWZ5bdFJD291apKwTVgDzcf7mo77Ypjpko+Y4Og3weUGOnM+hTdPiToUmkZv78OPgbRR+utdAoGBAOS5c3f7gdfd60mlABPIgpHQccaTyEg3YoCQoB1oXTMk881vzC6w8xwYR0gpKGj6/vG9FeEpgYLi+ydWiNnzH8ZknPiACYZ6g18CzlCUcHUG1PZhKot1zgXQN9/WAvjWZ62Ym4FcPrEaF3+u88Pjj27vQE5MDO8O2uVRQwIGXh9zAoGAGLjGHzYNle91dlsJsffgD2LoJsXqbmNdjwybMCh6jhAE/o/+m4uw4ZH6allcdF/YpuH1FAGGFuEg2nkrT/53QSC2QPINwdQqGqFUx8cSU34YXwF/U4AVZwdJ+mWkPgTXlfuh5UAsCH5ytxqb1O+J9/PorU2pcS0C4sinyOUKNLUCgYBFJNsHVnz2KRxL8xmG4YK3WfBLO7m8OyIIA7Cjsz0ZjP43CKkNJGkaASzrX6XbtqUDp0nJ+6YvTzbluX89hAYDD790UCCRCtBUFKESMw2cEyimItGdv0s87qk1fZkAaLCHBi9cd+pr15tq+hSvD0f5HVKvWMZALpl14Y8EObCSiQKBgCiSKMsn7W5eGVR4cHO5NQ8P6V20ZOGIKvUsJUtlzRtneJERqVXZqVp9MctpLzNluQMGzTR1dEngdnOa2sYgdd8ATYy0NGiZuBDMA3h0f0aVsQublPfUG+0QH/3qryNISWN+m8DnCtkpkUG1GI5/0x9ZVVlSybIvz7H8NltIxXr/ private_key=MIIEowIBAAKCAQEAzNWyjYe3qt4YRTDwANxDPNLAJ9TZBuHsSqSjJM5B35fABwN3gwm5Q/SCz/6kgKTqeSgCVPFYhO/zOD6G8K7EJLgx95ZIeAB9EkW+xrhFDDthUZAkA03zHJO6SkFKOciLFVi94BdCdGlNFlnaBBqA+8XvCpD1V8DFc/9cpb5icZvngu8vEkwkbYceCXKUMNxoXY/E2cFe8f2tVFR5pRkQgRLbM70jt4yBGOD8pbuk6fcnD7ghGWgzMq/845N3wISSTp/gAQg8403Fk+8AoL+FKgxUkjUOpPI2XrcpQm0EphuAX4J0Xvo3Hu6TEPZYyqULEXGT2Jukmh0NSkNO0F39xwIDAQABAoIBAQCAqRYPWhkexYQ/Kb8G+1NsiABUxJhRf2UZeZJUEw5DcKEYhq/x6hCpw5LLLOqNN4lj8qKMUlBEqCeAw52k3lGrstsH5ii836mv6YksbyBHz6CQR9anELZM0+nmrF4AL5xVGzmg4VtHncDi8itD+pXcD3bXjzfcF+SuuM6r+QsCykgTc/jw+R6GqOHvD48mUQCI0/Xw6jjAWUUh0jRX2BvLQwcccan5ZCZD3C7M8gGuRFO2vr8lFliQwyFNgwrpE+brLeMNeLHz1S6vMwfqr3r4Mq78wTihoze+3kIs5tdE0YRkJpaPLdeCsvQ8iFfD9nat7wnNHgcQBU+3B+KjOJCZAoGBAOVC8AY8q0UeTFreo44Fgda9Jg+BsR0UwTzTxzozdwSMhIfzb6oDa6tWd8VO0V6FaqK+Urxj6UP3JshAQT8hsq6Hh8tEmUx3rxpQnWZ5bdFJD291apKwTVgDzcf7mo77Ypjpko+Y4Og3weUGOnM+hTdPiToUmkZv78OPgbRR+utdAoGBAOS5c3f7gdfd60mlABPIgpHQccaTyEg3YoCQoB1oXTMk881vzC6w8xwYR0gpKGj6/vG9FeEpgYLi+ydWiNnzH8ZknPiACYZ6g18CzlCUcHUG1PZhKot1zgXQN9/WAvjWZ62Ym4FcPrEaF3+u88Pjj27vQE5MDO8O2uVRQwIGXh9zAoGAGLjGHzYNle91dlsJsffgD2LoJsXqbmNdjwybMCh6jhAE/o/+m4uw4ZH6allcdF/YpuH1FAGGFuEg2nkrT/53QSC2QPINwdQqGqFUx8cSU34YXwF/U4AVZwdJ+mWkPgTXlfuh5UAsCH5ytxqb1O+J9/PorU2pcS0C4sinyOUKNLUCgYBFJNsHVnz2KRxL8xmG4YK3WfBLO7m8OyIIA7Cjsz0ZjP43CKkNJGkaASzrX6XbtqUDp0nJ+6YvTzbluX89hAYDD790UCCRCtBUFKESMw2cEyimItGdv0s87qk1fZkAaLCHBi9cd+pr15tq+hSvD0f5HVKvWMZALpl14Y8EObCSiQKBgCiSKMsn7W5eGVR4cHO5NQ8P6V20ZOGIKvUsJUtlzRtneJERqVXZqVp9MctpLzNluQMGzTR1dEngdnOa2sYgdd8ATYy0NGiZuBDMA3h0f0aVsQublPfUG+0QH/3qryNISWN+m8DnCtkpkUG1GI5/0x9ZVVlSybIvz7H8NltIxXr/

@ -37,6 +37,9 @@ expire=600
oneTimeValid=1 oneTimeValid=1
key=c3nyGkDcot8aXKcgUZLe key=c3nyGkDcot8aXKcgUZLe
[aliyun]
appCode=1830f95365cb47488667ca1ef9aa9f6d
[recook] [recook]
url=https://testapi.reecook.cn/api/v1 url=https://testapi.reecook.cn/api/v1
private_key=MIIEowIBAAKCAQEAzNWyjYe3qt4YRTDwANxDPNLAJ9TZBuHsSqSjJM5B35fABwN3gwm5Q/SCz/6kgKTqeSgCVPFYhO/zOD6G8K7EJLgx95ZIeAB9EkW+xrhFDDthUZAkA03zHJO6SkFKOciLFVi94BdCdGlNFlnaBBqA+8XvCpD1V8DFc/9cpb5icZvngu8vEkwkbYceCXKUMNxoXY/E2cFe8f2tVFR5pRkQgRLbM70jt4yBGOD8pbuk6fcnD7ghGWgzMq/845N3wISSTp/gAQg8403Fk+8AoL+FKgxUkjUOpPI2XrcpQm0EphuAX4J0Xvo3Hu6TEPZYyqULEXGT2Jukmh0NSkNO0F39xwIDAQABAoIBAQCAqRYPWhkexYQ/Kb8G+1NsiABUxJhRf2UZeZJUEw5DcKEYhq/x6hCpw5LLLOqNN4lj8qKMUlBEqCeAw52k3lGrstsH5ii836mv6YksbyBHz6CQR9anELZM0+nmrF4AL5xVGzmg4VtHncDi8itD+pXcD3bXjzfcF+SuuM6r+QsCykgTc/jw+R6GqOHvD48mUQCI0/Xw6jjAWUUh0jRX2BvLQwcccan5ZCZD3C7M8gGuRFO2vr8lFliQwyFNgwrpE+brLeMNeLHz1S6vMwfqr3r4Mq78wTihoze+3kIs5tdE0YRkJpaPLdeCsvQ8iFfD9nat7wnNHgcQBU+3B+KjOJCZAoGBAOVC8AY8q0UeTFreo44Fgda9Jg+BsR0UwTzTxzozdwSMhIfzb6oDa6tWd8VO0V6FaqK+Urxj6UP3JshAQT8hsq6Hh8tEmUx3rxpQnWZ5bdFJD291apKwTVgDzcf7mo77Ypjpko+Y4Og3weUGOnM+hTdPiToUmkZv78OPgbRR+utdAoGBAOS5c3f7gdfd60mlABPIgpHQccaTyEg3YoCQoB1oXTMk881vzC6w8xwYR0gpKGj6/vG9FeEpgYLi+ydWiNnzH8ZknPiACYZ6g18CzlCUcHUG1PZhKot1zgXQN9/WAvjWZ62Ym4FcPrEaF3+u88Pjj27vQE5MDO8O2uVRQwIGXh9zAoGAGLjGHzYNle91dlsJsffgD2LoJsXqbmNdjwybMCh6jhAE/o/+m4uw4ZH6allcdF/YpuH1FAGGFuEg2nkrT/53QSC2QPINwdQqGqFUx8cSU34YXwF/U4AVZwdJ+mWkPgTXlfuh5UAsCH5ytxqb1O+J9/PorU2pcS0C4sinyOUKNLUCgYBFJNsHVnz2KRxL8xmG4YK3WfBLO7m8OyIIA7Cjsz0ZjP43CKkNJGkaASzrX6XbtqUDp0nJ+6YvTzbluX89hAYDD790UCCRCtBUFKESMw2cEyimItGdv0s87qk1fZkAaLCHBi9cd+pr15tq+hSvD0f5HVKvWMZALpl14Y8EObCSiQKBgCiSKMsn7W5eGVR4cHO5NQ8P6V20ZOGIKvUsJUtlzRtneJERqVXZqVp9MctpLzNluQMGzTR1dEngdnOa2sYgdd8ATYy0NGiZuBDMA3h0f0aVsQublPfUG+0QH/3qryNISWN+m8DnCtkpkUG1GI5/0x9ZVVlSybIvz7H8NltIxXr/ private_key=MIIEowIBAAKCAQEAzNWyjYe3qt4YRTDwANxDPNLAJ9TZBuHsSqSjJM5B35fABwN3gwm5Q/SCz/6kgKTqeSgCVPFYhO/zOD6G8K7EJLgx95ZIeAB9EkW+xrhFDDthUZAkA03zHJO6SkFKOciLFVi94BdCdGlNFlnaBBqA+8XvCpD1V8DFc/9cpb5icZvngu8vEkwkbYceCXKUMNxoXY/E2cFe8f2tVFR5pRkQgRLbM70jt4yBGOD8pbuk6fcnD7ghGWgzMq/845N3wISSTp/gAQg8403Fk+8AoL+FKgxUkjUOpPI2XrcpQm0EphuAX4J0Xvo3Hu6TEPZYyqULEXGT2Jukmh0NSkNO0F39xwIDAQABAoIBAQCAqRYPWhkexYQ/Kb8G+1NsiABUxJhRf2UZeZJUEw5DcKEYhq/x6hCpw5LLLOqNN4lj8qKMUlBEqCeAw52k3lGrstsH5ii836mv6YksbyBHz6CQR9anELZM0+nmrF4AL5xVGzmg4VtHncDi8itD+pXcD3bXjzfcF+SuuM6r+QsCykgTc/jw+R6GqOHvD48mUQCI0/Xw6jjAWUUh0jRX2BvLQwcccan5ZCZD3C7M8gGuRFO2vr8lFliQwyFNgwrpE+brLeMNeLHz1S6vMwfqr3r4Mq78wTihoze+3kIs5tdE0YRkJpaPLdeCsvQ8iFfD9nat7wnNHgcQBU+3B+KjOJCZAoGBAOVC8AY8q0UeTFreo44Fgda9Jg+BsR0UwTzTxzozdwSMhIfzb6oDa6tWd8VO0V6FaqK+Urxj6UP3JshAQT8hsq6Hh8tEmUx3rxpQnWZ5bdFJD291apKwTVgDzcf7mo77Ypjpko+Y4Og3weUGOnM+hTdPiToUmkZv78OPgbRR+utdAoGBAOS5c3f7gdfd60mlABPIgpHQccaTyEg3YoCQoB1oXTMk881vzC6w8xwYR0gpKGj6/vG9FeEpgYLi+ydWiNnzH8ZknPiACYZ6g18CzlCUcHUG1PZhKot1zgXQN9/WAvjWZ62Ym4FcPrEaF3+u88Pjj27vQE5MDO8O2uVRQwIGXh9zAoGAGLjGHzYNle91dlsJsffgD2LoJsXqbmNdjwybMCh6jhAE/o/+m4uw4ZH6allcdF/YpuH1FAGGFuEg2nkrT/53QSC2QPINwdQqGqFUx8cSU34YXwF/U4AVZwdJ+mWkPgTXlfuh5UAsCH5ytxqb1O+J9/PorU2pcS0C4sinyOUKNLUCgYBFJNsHVnz2KRxL8xmG4YK3WfBLO7m8OyIIA7Cjsz0ZjP43CKkNJGkaASzrX6XbtqUDp0nJ+6YvTzbluX89hAYDD790UCCRCtBUFKESMw2cEyimItGdv0s87qk1fZkAaLCHBi9cd+pr15tq+hSvD0f5HVKvWMZALpl14Y8EObCSiQKBgCiSKMsn7W5eGVR4cHO5NQ8P6V20ZOGIKvUsJUtlzRtneJERqVXZqVp9MctpLzNluQMGzTR1dEngdnOa2sYgdd8ATYy0NGiZuBDMA3h0f0aVsQublPfUG+0QH/3qryNISWN+m8DnCtkpkUG1GI5/0x9ZVVlSybIvz7H8NltIxXr/

@ -7,6 +7,7 @@ require (
github.com/gin-gonic/gin v1.6.3 github.com/gin-gonic/gin v1.6.3
github.com/go-playground/locales v0.13.0 github.com/go-playground/locales v0.13.0
github.com/go-playground/universal-translator v0.17.0 github.com/go-playground/universal-translator v0.17.0
github.com/go-redis/redis v6.15.9+incompatible
github.com/golangkit/formatime v0.0.0-20191104073810-5264c15ae8ec github.com/golangkit/formatime v0.0.0-20191104073810-5264c15ae8ec
github.com/gorilla/websocket v1.4.2 github.com/gorilla/websocket v1.4.2
github.com/json-iterator/go v1.1.10 github.com/json-iterator/go v1.1.10

@ -21,6 +21,8 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=

Loading…
Cancel
Save