commit a1c60eb29de0a9db20ef103cf149cdf27c411ca8 Author: tommy <3405129587@qq.com> Date: Mon Mar 9 09:52:53 2020 +0800 互动专家 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6ec77ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +.idea +hudongzhuanjia-go-build +hudongzhuanjia +go_build_main_go +.vscode +.log + + +services/pay/bindata.go \ No newline at end of file diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..02109e4 --- /dev/null +++ b/README.en.md @@ -0,0 +1,36 @@ +# 互动专家 + +#### Description +欧轩网络互动专家 + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..111d77a --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# 互动专家 + +#### 介绍 +欧轩网络互动专家 + +#### 软件架构 +软件架构说明 + + +#### 安装教程 + +1. xxxx +2. xxxx +3. xxxx + +#### 使用说明 + +1. xxxx +2. xxxx +3. xxxx + +#### 参与贡献 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request + + +#### 码云特技 + +1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md +2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) +3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 +4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 +5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) +6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) \ No newline at end of file diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..95ade2e --- /dev/null +++ b/build.bat @@ -0,0 +1,5 @@ +SET CGO_ENABLED=0 +SET GOOS=linux +SET GOARCH=amd64 + +go build main.go diff --git a/config.json b/config.json new file mode 100644 index 0000000..eba0c8a --- /dev/null +++ b/config.json @@ -0,0 +1,8 @@ +{ + "port": "20181", + "host": "127.0.0.1", + "cross_domain": "*", + "post_max_memory": 1024000, + "api_router": "/PcClient/*", + "update_path": "./" +} \ No newline at end of file diff --git a/controllers/author.go b/controllers/author.go new file mode 100644 index 0000000..f5f4466 --- /dev/null +++ b/controllers/author.go @@ -0,0 +1,63 @@ +package controllers + +import ( + "hudongzhuanjia/libs/jwt" + "hudongzhuanjia/utils/define" +) + +//执行路由方法前校验登陆态,并且解析page、pageSize +type AuthorCtl struct { + BaseCtl + claims *jwt.JwtClaims +} + +func (t *AuthorCtl) Prepare() { + t.BaseCtl.Prepare() + token := "" + if tokenStr, ok := t.Request.SESSION[define.TOKEN]; ok { + token = tokenStr + } else if tokenStr, ok := t.Request.REQUEST[define.TOKEN]; ok { + token = tokenStr + } else if tokenStr, ok := t.Request.HEADER[define.TOKEN]; ok { + token = tokenStr + } else { + var param = make(map[string]interface{}, 0) + err := t.RequestToStruct(¶m) + t.CheckErr(err) + if tokenStr, ok := param[define.TOKEN]; ok { + token = tokenStr.(string) + } + } + claims, err := jwt.ParseAccessToken(token) + t.CheckErr(err) + t.claims = claims + // 最后多地区:子账号的area_id = area_id, 但是主账号的area_id 需要通过activity_id 进行获取 +} + +func (t *AuthorCtl) MustGetUID() int64 { + return t.claims.AccountId +} + +// token 应该携带某个主活动i +func (t *AuthorCtl) MustGetActivityId() int64 { + return t.MustGetInt64("activity_id") +} + +func (t *AuthorCtl) MustGetName() string { + return t.claims.Username +} + +func (t *AuthorCtl) MustGetCustomerId() int64 { + return t.claims.CustomerId +} + +func (t *AuthorCtl) MustGetCustomerPid() int64 { + return t.claims.CustomerPid +} + +func (t *AuthorCtl) MustGetAreaId() int64 { + return t.claims.AreaId +} + +// 对各种角色进行不同的接口权限限定 +// role: main sub entry user : 主账号 子账号 录入人员 用户 diff --git a/controllers/base.go b/controllers/base.go new file mode 100644 index 0000000..33d891c --- /dev/null +++ b/controllers/base.go @@ -0,0 +1,219 @@ +package controllers + +import ( + "fmt" + "hudongzhuanjia/logger" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "runtime" + "strconv" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +//解析page、pageSize +type BaseCtl struct { + core.Controller + Page int + PageSize int + Limit int // page * pagesize +} + +func (t *BaseCtl) Prepare() { + t.OriginResponseWriter.Header().Set("Access-Control-Allow-Origin", "*") + t.Page, _ = t.GetInt("page") + t.PageSize, _ = t.GetInt("page_size") + t.Limit = t.Page * t.PageSize +} + +type M map[string]interface{} + +func (t *BaseCtl) Get(key string) (value string, exist bool) { + value, exist = t.Request.REQUEST[key] + return +} + +func (t *BaseCtl) MustGet(key string) string { + value, exist := t.Get(key) + t.Assert(exist, code.MSG_ERR_Param, fmt.Sprintf("%s不能为空", key)) + return value +} + +func (t *BaseCtl) Default(key string, def string) string { + value, exist := t.Get(key) + if exist { + return value + } + return def +} + +func (t *BaseCtl) GetInt64(key string) (int64, bool) { + v, ok := t.Get(key) + if !ok { + return 0, false + } + value, err := strconv.ParseInt(v, 10, 64) + if err != nil { + logger.Sugar.Infof("get int64 from request error", err) + t.ERROR(fmt.Sprintf("%v的数据类型不为int", key), code.MSG_ERR_Param) + } + + return value, true +} + +func (t *BaseCtl) MustGetInt64(key string) int64 { + value, exist := t.GetInt64(key) + t.Assert(exist, code.MSG_ERR_Param, fmt.Sprintf("%v不能为空", key)) + return value +} + +func (t *BaseCtl) DefaultInt64(key string, def int64) int64 { + value, exist := t.GetInt64(key) + if exist { + return value + } + return def +} + +func (t *BaseCtl) GetInt(key string) (int, bool) { + value, exist := t.GetInt64(key) + return int(value), exist +} + +func (t *BaseCtl) MustGetInt(key string) int { + value, exist := t.GetInt(key) + t.Assert(exist, code.MSG_ERR_Param, fmt.Sprintf("%s不能为空", key)) + return value +} + +func (t *BaseCtl) DefaultInt(key string, def int) int { + value, exist := t.GetInt(key) + if exist { + return value + } + return def +} + +func (t *BaseCtl) GetBool(key string) (bool, bool) { + v, ok := t.Get(key) + if !ok { + return false, false + } + value, err := strconv.ParseBool(v) + if err != nil { + logger.Sugar.Infof("get bool from request error", err) + t.ERROR(fmt.Sprintf("%v的数据类型不为bool", key), code.MSG_ERR_Param) + } + return value, true +} + +func (t *BaseCtl) MustGetBool(key string) bool { + value, exist := t.GetBool(key) + t.Assert(exist, code.MSG_ERR_Param, fmt.Sprintf("%s不能为空", key)) + return value +} + +func (t *BaseCtl) DefaultBool(key string, def bool) bool { + value, exist := t.GetBool(key) + if exist { + return value + } + return def +} + +func (t *BaseCtl) GetDouble(key string) (float64, bool) { + v, ok := t.Get(key) + if !ok { + return 0, false + } + value, err := strconv.ParseFloat(v, 64) + if err != nil { + logger.Sugar.Infof("get double from request error", err) + t.ERROR(fmt.Sprintf("%v的数据类型不为double", key), code.MSG_ERR_Param) + } + return value, true +} + +func (t *BaseCtl) MustGetDouble(key string) float64 { + value, exist := t.GetDouble(key) + t.Assert(exist, code.MSG_ERR_Param, fmt.Sprintf("%s不能为空", key)) + return value +} + +func (t *BaseCtl) DefaultDouble(key string, def float64) float64 { + value, exist := t.GetDouble(key) + if exist { + return value + } + return def +} + +func (t *BaseCtl) GetFloat(key string) (float32, bool) { + value, exist := t.GetDouble(key) + return float32(value), exist +} + +func (t *BaseCtl) MustGetFloat(key string) float32 { + value, exist := t.GetFloat(key) + t.Assert(exist, code.MSG_ERR_Param, fmt.Sprintf("%s不能为空", key)) + return value +} + +func (t *BaseCtl) DefaultFloat(key string, def float32) float32 { + value, exist := t.GetFloat(key) + if exist { + return value + } + return def +} + +func (t *BaseCtl) JSON(m map[string]interface{}) { + t.DisplayByData(m) +} + +func (t BaseCtl) XML(data []byte) { + t.OriginResponseWriter.Header().Add("Content-Type", "application/xml; charset=utf-8") + t.OriginResponseWriter.Write(data) + panic(nil) +} + +func (t *BaseCtl) ERROR(errStr string, code int, data ...string) { + t.DisplayByError(errStr, code, data...) +} + +func (t *BaseCtl) CheckInSuccess(str string) { + t.DisplayByError(str, 1) +} + +func (t *BaseCtl) SUCCESS(str string) { + t.DisplayByError(str, 0) +} + +func (t *BaseCtl) STRING(str string) { + t.Display(nil, str, 0) +} +func (t *BaseCtl) RAW(data interface{}) { + t.DisplayByData(data) +} + +func (t *BaseCtl) CheckErr(err error) { + if err != nil { + pc, file, line, ok := runtime.Caller(1) + logger.Sugar.Debugf("error:%v, pc: %v, file: %v, line:%v, ok: %v", err, pc, file, line, ok) + t.CheckErrDisplayByError(err) + } +} + +// false +func (t *BaseCtl) Assert(b bool, errcode int, errmsg string) { + if !b { + t.ERROR(errmsg, errcode) + } + return +} + +func (t *BaseCtl) CheckRunning(status string) { + if status != define.StatusRunning { + t.ERROR(fmt.Sprintf("该活动%s", status), code.MSG_MODULE_STATUS_NOT_RUNNING) + } +} diff --git a/controllers/client/activity.go b/controllers/client/activity.go new file mode 100644 index 0000000..35bf8f9 --- /dev/null +++ b/controllers/client/activity.go @@ -0,0 +1,72 @@ +package client + +import ( + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + activity_service "hudongzhuanjia/services/activity" + auction_service "hudongzhuanjia/services/auction" + bahe_service "hudongzhuanjia/services/bahe" + bully_screen_service "hudongzhuanjia/services/bully_screen" + calorie_service "hudongzhuanjia/services/calorie" + red_envelope_service "hudongzhuanjia/services/red_envelope" + vote_service "hudongzhuanjia/services/vote" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" +) + +type ActivityCtl struct { + controllers.AuthorCtl +} + +func (t *ActivityCtl) ModuleStatus() { + activityId := t.MustGetActivityId() + moduleName := t.MustGet("module_name") + exist, err := activity_service.ExistModuleByActivityId(activityId, moduleName) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "status": exist, + }) +} + +// 某个模块的活动状态 +func (t *ActivityCtl) ModuleCurrent() { + activityId := t.MustGetActivityId() + moduleName := t.MustGet("module_name") + uid := t.MustGetUID() + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + switch moduleName { + case define.MODULE_TUGWAR: // 拔河 + data, err := bahe_service.GetCurrentTugWar(activityId, uid, activity.RehearsalId) + t.CheckErr(err) + t.JSON(data) + case define.MODULE_CALORIE: // 卡路里 + data, err := calorie_service.GetCurrentCalorie(activityId, uid, activity.RehearsalId) + t.CheckErr(err) + t.JSON(data) + case define.MODULE_SHAKRB: // 摇红包 + // 没有初始状态 // 记下参与人数 + data, err := red_envelope_service.GetCurrentRB(activityId, uid, activity.RehearsalId) + t.CheckErr(err) + t.JSON(data) + case define.MODULE_AUCTION: + // 竞拍 + data, err := auction_service.GetCurrentAuction(activityId, activity.RehearsalId, t.MustGetUID()) + t.CheckErr(err) + t.JSON(data) + case define.MODULE_VOTE: + data, err := vote_service.GetCurrentVote(activityId, uid, activity.RehearsalId) + t.CheckErr(err) + t.JSON(data) + case define.MODULE_BULLYS: + data, err := bully_screen_service.GetCurrentBullyScreen(activityId) + t.CheckErr(err) + t.JSON(data) + default: + t.ERROR("不存在该模块", code.MSG_MODULE_NOT_EXIST) + } +} diff --git a/controllers/client/auction.go b/controllers/client/auction.go new file mode 100644 index 0000000..a78f533 --- /dev/null +++ b/controllers/client/auction.go @@ -0,0 +1,179 @@ +package client + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + auction_service "hudongzhuanjia/services/auction" + ws_send_service "hudongzhuanjia/services/ws_send" + "hudongzhuanjia/utils/code" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type AuctionCtl struct { + controllers.AuthorCtl +} + +// 竞拍动作 +func (t *AuctionCtl) Auction() { + auctionId := t.MustGetInt64("auction_activity_id") + totalMoney := t.MustGetDouble("total_money") + uid := t.MustGetUID() + + if totalMoney < 0 { + t.ERROR("金额不能为0", code.MSG_ERR) + } + + auction := new(models.NewAuctionActivity) + exist, err := models.GetById(auction, auctionId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "竞拍活动不存在") + t.CheckRunning(auction.Status) + + activity := new(models.Activity) + exist, err = models.GetById(activity, auction.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + user := new(models.User) + exist, err = models.GetById(user, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") + + area := new(models.AreaStore) + exist, err = models.GetById(area, user.AreaId) + t.CheckErr(err) + t.Assert(exist, code.MSG_AREASTORE_NOT_EXIST, "地区不存在") + + player := new(models.AuctionPlayer) + exist, err = player.GetByAuctionIdAndUid(auction.Id, uid, activity.RehearsalId) + t.CheckErr(err) + t.Assert(exist, code.MSG_AUCTION_NOT_EXIST, "竞拍编号不存在") + + history := new(models.AuctionHistory) + history.AuctionActivityId = auction.Id + history.AuctionGoodsName = auction.AuctionGoodsName + history.ActivityId = activity.Id + history.RehearsalId = activity.RehearsalId + history.UserId = uid + history.AreaId = user.AreaId + history.UserName = user.Nickname + history.AreaName = area.Name + history.UserPhone = user.Phone + history.Money = totalMoney + history.Unit = auction.Unit + history.PlayerCode = player.Code + history.UserId = uid + history.IsDelete = false + history.CreatedAt = time.Now() + history.UpdatedAt = time.Now() + _, err = core.GetXormAuto().InsertOne(history) + t.CheckErr(err) + + if auction.AuctionModel == "加价竞拍" { + maxHistory := new(models.AuctionHistory) + exist, err := maxHistory.GetHighestMoney(activity.RehearsalId, auction.Id) + t.CheckErr(err) + if exist && (history.Money < maxHistory.Money || history.UserId != maxHistory.UserId) { + _, err = history.SoftDelete() + t.CheckErr(err) + t.ERROR("加价失败, 价格低于当前最高价", code.MSG_ERR) + return + } + + go ws_send_service.SendAuction(fmt.Sprintf("%d", activity.Id), + "", 0, map[string]interface{}{ + "type": "auction", + "data": map[string]interface{}{ + "max_money": maxHistory.Money, + "avatar": user.Avatar, + "nickname": user.Nickname, + "num": 0, + "user_id": user.Id, + "status": "进行中", + "model": "加价竞拍", + }, + }) + // 成功 + + } else { // 减价竞拍 + record := new(models.AuctionResultRecord) + count, err := record.CountHistory(activity.RehearsalId, auction.Id) + t.CheckErr(err) + if int(count) >= auction.GoodsNum { + t.ERROR("所有商品已经竞拍完毕", code.MSG_ERR) + } + + record.AuctionActivityId = auctionId + record.AuctionGoodsName = auction.AuctionGoodsName + record.ActivityId = auction.ActivityId + record.UserId = uid + record.UserPhone = user.Phone + record.UserName = user.Nickname + record.AreaId = user.AreaId + record.AreaName = user.AreaName + record.DealPrice = totalMoney + record.RehearsalId = activity.RehearsalId + record.PlayerCode = player.Code + record.Unit = auction.Unit + record.UpdatedAt = time.Now() + record.CreatedAt = time.Now() + record.IsDelete = false + _, err = core.GetXormAuto().InsertOne(record) + t.CheckErr(err) + + go ws_send_service.SendAuction(fmt.Sprintf("%d", activity.Id), + "", 0, map[string]interface{}{ + "type": "auction", + "data": map[string]interface{}{ + "max_money": 0, + "avatar": user.Avatar, + "nickname": user.Nickname, + "user_id": user.Id, + "status": "进行中", + "num": auction.GoodsNum - int(count) - 1, + "model": "减价竞拍", + }, + }) + } + // 加价 + t.STRING("加价成功") +} + +func (t *AuctionCtl) ExistRecord() { + auctionId := t.MustGetInt64("auction_activity_id") + uid := t.MustGetUID() + + auction := new(models.NewAuctionActivity) + exist, err := models.GetById(auction, auctionId) + t.CheckErr(err) + t.Assert(exist, code.MSG_AUCTION_NOT_EXIST, "竞拍活动不存在") + + activity := new(models.Activity) + exist, err = models.GetById(activity, auction.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + record := new(models.AuctionResultRecord) + exist, err = core.GetXormAuto().Where("is_delete=0 and user_id=? and auction_activity_id=? and rehearsal_id=?", uid, auctionId, activity.RehearsalId).Get(record) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "show": exist, + }) +} + +// 已经竞拍到了 +func (t *AuctionCtl) UserAuctions() { + uid := t.MustGetUID() + activityId := t.MustGetActivityId() + + records, err := auction_service.GetUserAuctions(activityId, uid) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "list": records, + "total": len(records), + }) +} diff --git a/controllers/client/barrage.go b/controllers/client/barrage.go new file mode 100644 index 0000000..fdd89e9 --- /dev/null +++ b/controllers/client/barrage.go @@ -0,0 +1,69 @@ +package client + +import ( + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + ws_send_service "hudongzhuanjia/services/ws_send" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" +) + +//弹幕 +type BarrageCtl struct { + controllers.AuthorCtl +} + +//发送弹幕 +func (t *BarrageCtl) Send() { + uid := t.MustGetUID() + customerId := t.MustGetCustomerId() + activityId := t.MustGetActivityId() + content := t.MustGet("content") + + //检查内容是否包含敏感 + if models.IsSensitive(content) { + t.ERROR("内容包含敏感字", code.MSG_ERR) + } + + //查询该活动的所属客户 + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + //查询当前的用户信息 + user := new(models.User) + exist, err = models.GetById(user, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") + + //插入弹幕消息 + _, err = core.GetXormAuto().InsertOne(&models.BarrageHistory{ + ActivityId: activityId, + UserId: uid, + Content: content, + CreateAt: time.Now(), + UpdateAt: time.Now(), + }) + t.CheckErr(err) + + customer := new(models.Customer) + exist, err = models.GetById(customer, customerId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + go ws_send_service.SendBarrage(fmt.Sprintf("%d", activity.Id), + define.TYPE_CUSTOMER, 0, map[string]interface{}{ + "type": "barrage", + "customer_id": 0, + "data": map[string]interface{}{ + "avatar": user.Avatar, + "content": content, + }, + }) + + t.SUCCESS("发送成功") +} diff --git a/controllers/client/bully_screen.go b/controllers/client/bully_screen.go new file mode 100644 index 0000000..37ea1f8 --- /dev/null +++ b/controllers/client/bully_screen.go @@ -0,0 +1,105 @@ +package client + +import ( + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + bully_screen_service "hudongzhuanjia/services/bully_screen" + "hudongzhuanjia/services/pay" + "hudongzhuanjia/utils/code" + "strings" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +//霸屏 +type BullyScreenCtl struct { + controllers.AuthorCtl +} + +//用户霸屏 +// todo: 支付接口 +func (t *BullyScreenCtl) PaScreen() { + activityId := t.MustGetActivityId() + uid := t.MustGetUID() + content := t.MustGet("content") + second := t.MustGetDouble("second") + style := t.MustGetInt("style") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + //检查内容是否包含敏感 + if models.IsSensitive(content) { + t.ERROR("内容包含敏感字", code.MSG_ERR) + } + + //查询该活动的的霸屏服务id + bullyScreenServer := new(models.BullyScreenServer) + exist, err = bullyScreenServer.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_BULLY_SCREEN_SERVER_NOT_EXIST, "霸屏不存在") + + //查询用户信息 + user := new(models.User) + exist, err = models.GetById(user, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") + + //扣除用户的金额 + // todo:微信直接付款 + // 调用微信统一下单接口 + amount := bullyScreenServer.Price * second + ip := strings.Split(t.Request.OriginRequest.RemoteAddr, ":") + res, err := pay_service.Order("欧轩互动-霸屏支付", ip[0], user.Openid, int(amount*100), 1, user.Id, activityId) + t.CheckErr(err) + + history := &models.BullyScreenHistory{ + UserOrderId: res["user_order_id"].(int64), + BullyScreenServerId: bullyScreenServer.Id, + ActivityId: activityId, + UserId: user.Id, + Nickname: user.Nickname, + CustomerId: t.MustGetCustomerId(), + RehearsalId: activity.RehearsalId, + Second: int(second), + Amount: amount, + Style: style, + ReviewTime: 0, + Status: -1, + Content: content, + IsDelete: false, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + } + _, err = core.GetXormAuto().InsertOne(history) + t.CheckErr(err) + delete(res, "out_trade_no") + delete(res, "user_order_id") + t.JSON(res) +} + +// 审核列表 [未审核,未通过,已通过] +func (t *BullyScreenCtl) List() { + uid := t.MustGetUID() + activityId := t.MustGetActivityId() + + bss := new(models.BullyScreenServer) + exist, err := bss.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_BULLY_SCREEN_SERVER_NOT_EXIST, "霸屏不存在") + + // 查询是否已经付款 + t.CheckErr(pay_service.BatchQueryByUserId(uid)) + t.CheckErr(pay_service.BatchQueryRefundByUserId(uid)) + + list, err := bully_screen_service.GetReviewList(uid, bss.Id) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "total": len(list), + "list": list, + }) +} diff --git a/controllers/client/calorie.go b/controllers/client/calorie.go new file mode 100644 index 0000000..4f9ba2a --- /dev/null +++ b/controllers/client/calorie.go @@ -0,0 +1,83 @@ +package client + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" +) + +type CalorieCtl struct { + controllers.AuthorCtl +} + +// h5 1/s +func (t *CalorieCtl) Shake() { + calorieId := t.MustGetInt64("calorie_id") + score := t.DefaultInt("score", 0) + uid := t.MustGetUID() + + calorie := new(models.Calorie) + exist, err := models.GetById(calorie, calorieId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CALORIE_NOT_EXIST, "卡路里不存在") + + activity := new(models.Activity) + exist, err = models.GetById(activity, calorie.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + calorieUser := new(models.CalorieUser) + exist, err = calorieUser.GetByCalorieIdAndUserId(calorieId, uid, activity.RehearsalId) + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "您尚未参与卡路里活动") + + // 增加score + if calorie.Status == define.StatusRunning && score > 0 { + _, err = calorieUser.IncrScore(score) + t.CheckErr(err) + calorieUser.Score += int64(score) // 增加 + } + + count, err := core.GetXormAuto().Where("is_delete=0 and calorie_id=? and rehearsal_id=?", calorie.Id, activity.RehearsalId).Count(new(models.CalorieUser)) + t.CheckErr(err) + + users := make([]*models.CalorieUser, 0) + err = core.GetXormAuto().Where("is_delete=0 and calorie_id=? and rehearsal_id=? and score<=?", + calorie.Id, activity.RehearsalId, calorieUser.Score).Desc("score").Asc("join_time").Find(&users) + t.CheckErr(err) + + var rank int + for index, user := range users { + if user.Id == calorieUser.Id { + rank = int(count) - len(users) + index + 1 + break + } + } + + // 活动时长 + //duration := calorie.GameDuration - (time.Now().Unix() - calorie.StartTime) + 6 // 加上倒计时的6s + //if calorie.StartTime == 0 { + // duration = calorie.GameDuration + //} + // 3s 倒计时 + //var countDown float64 = 0 + //if duration-calorie.GameDuration > 0 { + // countDown = math.Ceil(float64(duration-calorie.GameDuration) / 2.0) + //} + + //// 活动结束 + //if calorie.Status == define.StatusEnding || duration <= 0 { + // duration = 0 + //} + + t.JSON(map[string]interface{}{ + "rank": rank, + "score": calorieUser.Score, // 分数 + //"time": duration - 2*int64(countDown), //时长 + //"count_down": countDown, // 倒计时 + //"status": calorie.Status, // 状态 + }) +} diff --git a/controllers/client/invite_envelope.go b/controllers/client/invite_envelope.go new file mode 100644 index 0000000..805633c --- /dev/null +++ b/controllers/client/invite_envelope.go @@ -0,0 +1,88 @@ +package client + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/code" + "time" +) + +type InvitationLetterCtl struct { + controllers.AuthorCtl +} + +// InviteEnvelope doc +// @Summary InviteEnvelope +// @Description 填写要求信息 +// @Tags invite envelope +// @Accept json +// @Produce json +// @Param activity_id query int true "邀请函内容" +// @Success 0 {string} string "success" +// @Failure 404 {string} string "参数不存在" +// @Failure 405 {string} string "用户不存在" +// @Router /Client/InviteEnvelopeCtl/invite [post] +func (t *InvitationLetterCtl) Invite() { + uid := t.MustGetUID() + activityId := t.MustGetActivityId() + invitationId := t.MustGetInt64("invitation_id") + answer := t.MustGet("answer") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + letter := new(models.InvitationLetter) + exist, err = letter.GetByUserIdAndActivityId(uid, activityId, activity.RehearsalId) + t.CheckErr(err) + t.Assert(!exist, code.MSG_INVITE_LETTER_EXIST, "您已经接受过邀请") + + letter.UserId = uid + letter.ActivityId = activityId + letter.InvitationId = invitationId + letter.RehearsalId = activity.RehearsalId + letter.ExtraData = answer + letter.IsDelete = false + letter.CreatedAt = time.Now() + letter.UpdatedAt = time.Now() + _, err = core.GetXormAuto().InsertOne(letter) + t.CheckErr(err) + + t.STRING("success") +} + +// InviteEnvelope doc +// @Summary InviteEnvelope +// @Description get invite envelope setting +// @Tags invite envelope +// @Accept json +// @Produce json +// @Param activity_id query int true "Activity ID" +// @Success 0 {object} models.Invitation +// @Failure 404 {string} string "参数不存在" +// @Failure 405 {string} string "用户不存在" +// @Router /Client/InviteEnvelopeCtl/setting [get] +func (t *InvitationLetterCtl) Setting() { + activityId := t.MustGetActivityId() + uid := t.MustGetUID() + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + letter := new(models.InvitationLetter) + exist, err = letter.GetByUserIdAndActivityId(uid, activityId, activity.RehearsalId) + t.CheckErr(err) + t.Assert(!exist, code.MSG_INVITE_LETTER_EXIST, "您已经接受过邀请") + + invitation := new(models.Invitation) + exist, err = invitation.GetInvitationByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_INVITE_SETTING_NOT_EXIST, "邀请函设置不存在") + t.JSON(map[string]interface{}{ + "setting": invitation, + }) +} diff --git a/controllers/client/login.go b/controllers/client/login.go new file mode 100644 index 0000000..e37fcf0 --- /dev/null +++ b/controllers/client/login.go @@ -0,0 +1,184 @@ +package client + +import ( + "hudongzhuanjia/controllers" + "hudongzhuanjia/libs/jwt" + "hudongzhuanjia/libs/wx" + "hudongzhuanjia/models" + activity_service "hudongzhuanjia/services/activity" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +//用户 +type UserCtl struct { + controllers.BaseCtl +} + +// 录入登录 +func (t *UserCtl) EntryLogin() { + account := t.MustGet("account") + password := t.MustGet("password") + activityId := t.MustGetInt64("activity_id") // 需要获取 + + entryPeople := new(models.OrderEntryPerson) + exist, err := core.GetXormAuto().Where("is_delete=0 and account = ? and password = ? and activity_id = ?", + account, password, activityId).Get(entryPeople) + t.CheckErr(err) + t.Assert(exist, code.MSG_ENTRYPEOPLE_NOT_EXIST, "录入人员不存在") + + area := new(models.AreaStore) + exist, err = models.GetById(area, entryPeople.AreaId) + t.CheckErr(err) + t.Assert(exist, code.MSG_AREASTORE_NOT_EXIST, "地区不存在") + + activity := new(models.Activity) + exist, err = models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + customer := new(models.Customer) + exist, err = models.GetById(customer, entryPeople.Pid) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + // 怎讲activity + token, err := jwt.GenJwtToken("entry", entryPeople.Id, customer.Id, customer.Pid, entryPeople.AreaId, entryPeople.ActivityId, entryPeople.Name) + t.CheckErr(err) + t.SetSession(define.TOKEN, token) + entryPeople.Token = token + entryPeople.AreaName = area.Name + entryPeople.ActivityName = activity.Name + t.JSON(map[string]interface{}{ + "people": entryPeople, + }) +} + +func (t *UserCtl) WxLogin() { + activityId := t.MustGetInt64("activity_id") + wxcode := t.MustGet("code") + + activity, exist, err := activity_service.GetActivityById(activityId) + t.CheckErr(err) + + customerId := t.DefaultInt64("customer_id", activity.CustomerId) + customer := new(models.Customer) + exist, err = models.GetById(customer, customerId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + area := new(models.AreaStore) + if customer.Pid == 0 { + exist, err = area.GetMainAreaById(activityId) + } else { + exist, err = area.GetAreaStoreById(customer.AreaId) + } + t.CheckErr(err) + t.Assert(exist, code.MSG_AREASTORE_NOT_EXIST, "地区不存在") + + token, err := wx.GetToken(wxcode) + t.CheckErr(err) + if token.AccessToken == "" || token.Openid == "" { + t.ERROR("code无效", code.MSG_ERR) + } + info, err := wx.GetUserInfo(token.AccessToken, token.Openid) + t.CheckErr(err) + user := new(models.User) + exist, err = user.GetUserByOpenid(info.Openid) + t.CheckErr(err) + user.Nickname = info.Nickname + user.Openid = info.Openid + user.Gender = func() string { + if info.Sex == 1 { + return "男" + } + return "女" + }() + user.ActivityId = activityId + user.AreaId = area.Id + user.AreaName = area.Name + user.Avatar = info.Headimgurl + user.Unionid = info.Unionid + user.City = info.City + user.Province = info.Province + user.Country = info.Country + user.CreatedAt = time.Now() + user.UpdatedAt = time.Now() + if exist { + core.GetXormAuto().Id(user.Id).AllCols().Update(user) + } else { + core.GetXormAuto().InsertOne(user) + } + t.CheckErr(err) + + signIn := "未签到" + history := new(models.SignHistory) + exist, err = history.GetByUserId(activityId, user.Id, activity.RehearsalId, area.Id) + t.CheckErr(err) + if exist { // 存在数据 + signIn = "已签到" + } + + jwtToken, err := jwt.GenJwtToken(define.TYPE_USER, user.Id, customer.Id, customer.Pid, area.Id, activityId, user.Nickname) + t.CheckErr(err) + t.SetSession(define.TOKEN, jwtToken) + + t.JSON(map[string]interface{}{ + "user": user, + "token": jwtToken, + "activity": activity, + "sign_in": signIn, + "tag": "activity", + }) +} + +// 模拟wx login +func (t *UserCtl) DebugLogin() { + uid := t.DefaultInt64("user_id", 19) + customerId := t.DefaultInt64("customer_id", 125) + activityId := t.DefaultInt64("activity_id", 592) + + user := new(models.User) + exist, err := models.GetById(user, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") + + customer := new(models.Customer) + exist, err = models.GetById(customer, customerId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + area := new(models.AreaStore) + if customer.Pid == 0 { + exist, err = area.GetMainAreaById(activityId) + } else { + exist, err = area.GetAreaStoreById(customer.AreaId) + } + t.CheckErr(err) + t.Assert(exist, code.MSG_AREASTORE_NOT_EXIST, "地区不存在") + + jwtToken, err := jwt.GenJwtToken("user", user.Id, customer.Id, customer.Pid, + area.Id, activityId, user.Nickname) + t.CheckErr(err) + t.SetSession(define.TOKEN, jwtToken) + t.JSON(map[string]interface{}{ + "user": user, + "token": jwtToken, + }) +} + +type UserAuthCtl struct { + controllers.AuthorCtl +} + +//退出 +func (t *UserAuthCtl) Logout() { + if _, ok := t.Request.SESSION[define.TOKEN]; !ok { + t.ERROR("未登录", code.MSG_ERR_Authority) + } + t.DeleteSession(define.TOKEN) + t.SUCCESS("退出成功") +} diff --git a/controllers/client/login_test.go b/controllers/client/login_test.go new file mode 100644 index 0000000..514e230 --- /dev/null +++ b/controllers/client/login_test.go @@ -0,0 +1,83 @@ +package client + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + . "github.com/smartystreets/goconvey/convey" + "hudongzhuanjia/libs/jwt" + "hudongzhuanjia/models" + "hudongzhuanjia/test" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "net/http" + "testing" +) + +func TestEntryLogin(t *testing.T) { + type Data struct { + People *models.OrderEntryPerson `json:"people"` + } + + type Result struct { + core.ResponseData + Data Data `json:"data"` + } + + conf := test.GetConfig() + Convey("测试录入人员登录", t, func() { + path := test.ApiUrl("PcClient/Client/UserCtl/entryLogin") + // 正确登录 + param := map[string]interface{}{ + "account": conf.EntryAccount, + "password": conf.EntryPwd, + "activity_id": conf.ActivityId, + } + resp, err := test.Api("").Get(path, param) // 并不需要token + So(err, ShouldBeNil) // 检测是否请求出错 + So(resp.StatusCode(), ShouldEqual, http.StatusOK) // 检测请求连接是否正确 + res := new(Result) + err = resp.Json(res) + So(err, ShouldBeNil) // 检测json 解析是否正确 + So(res.Code, ShouldEqual, 0) // 返回code是否为0 + So(res.Data.People, ShouldNotBeNil, nil) // 检测返回数据是否为空 + So(res.Data.People.ActivityId, ShouldEqual, conf.ActivityId) + So(res.Data.People.Account, ShouldEqual, conf.EntryAccount) + So(res.Data.People.Password, ShouldEqual, conf.EntryPwd) + So(res.Data.People.Token, ShouldNotBeEmpty) + // 校验token + claims, err := jwt.ParseAccessToken(res.Data.People.Token) + So(err, ShouldNotBeNil) + So(claims.ActivityId, ShouldEqual, conf.ActivityId) + So(claims.AccountType, ShouldEqual, define.TYPE_ENTRY) + So(claims.Username, ShouldEqual, conf.EntryAccount) + + // 登录失败的场景 + // 录入人员不存在 + param = map[string]interface{}{ + "account": "tommy", + "password": conf.EntryPwd, + "activity_id": conf.ActivityId, + } + resp, err = test.Api("").Get(path) + So(err, ShouldBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + res = new(Result) + err = resp.Json(res) + So(err, ShouldBeNil) + So(res.Code, ShouldEqual, code.MSG_ENTRYPEOPLE_NOT_EXIST) + + // 互动不存在 + param = map[string]interface{}{ + "account": conf.EntryAccount, + "password": conf.EntryPwd, + "activity_id": 0, + } + resp, err = test.Api("").Get(path) + So(err, ShouldBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + res = new(Result) + err = resp.Json(res) + So(err, ShouldBeNil) + So(res.Code, ShouldEqual, code.MSG_ACTIVITY_NOT_EXIST) + // done + }) +} diff --git a/controllers/client/lottery.go b/controllers/client/lottery.go new file mode 100644 index 0000000..d810138 --- /dev/null +++ b/controllers/client/lottery.go @@ -0,0 +1,24 @@ +package client + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" +) + +type LotteryCtl struct { + controllers.AuthorCtl +} + +func (t *LotteryCtl) UserLotteries() { + uid := t.MustGetUID() + + userPrizes := make([]*models.UserPrize, 0) + err := core.GetXormAuto().Where("is_delete=0 and user_id=? ", uid).Desc("created_at").Find(&userPrizes) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "list": userPrizes, + "total": len(userPrizes), + }) +} diff --git a/controllers/client/order_entry.go b/controllers/client/order_entry.go new file mode 100644 index 0000000..4553131 --- /dev/null +++ b/controllers/client/order_entry.go @@ -0,0 +1,228 @@ +package client + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + invitation_service "hudongzhuanjia/services/invitation" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" + "github.com/ouxuanserver/osmanthuswine/src/helper" +) + +type OrderEntryCtl struct { + controllers.AuthorCtl +} + +// 商品 == > 用户查看所有商品 +func (t *OrderEntryCtl) List() { + uid := t.MustGetUID() + activityId := t.MustGetActivityId() + goods := make([]*models.CustomerGoods, 0) + err := core.GetXormAuto().Where("is_delete=0 and activity_id=?", activityId). + Asc("created_at").Find(&goods) + t.CheckErr(err) + for index := range goods { + url := fmt.Sprintf("%s/PcClient/Client/OrderEntryCtl/order?"+ + "user_id=%d&activity_id=%d&good_id=%d", define.HOST, uid, activityId, goods[index].Id) + qrcode, err := utils.Qrcode2Base64(url) + t.CheckErr(err) + goods[index].Qrcode = qrcode + } + + t.JSON(map[string]interface{}{ + "list": goods, + "total": len(goods), + }) +} + +// 下订单 == > 二维码跳转 +func (t *OrderEntryCtl) Order() { + userId := t.MustGetInt64("user_id") + activityId := t.MustGetInt64("activity_id") + goodId := t.MustGetInt64("good_id") + entryId := t.MustGetUID() + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + entryPerson := new(models.OrderEntryPerson) + exist, err = models.GetById(entryPerson, entryId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ENTRYPEOPLE_NOT_EXIST, "录入人员不存在") + + area := new(models.AreaStore) + exist, err = area.GetAreaStoreById(entryPerson.AreaId) + t.CheckErr(err) + t.Assert(exist, code.MSG_AREASTORE_NOT_EXIST, "地区不存在") + + good := new(models.CustomerGoods) + exist, err = models.GetById(good, goodId) + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "商品不存在") + + orderGift := new(models.OrderGift) + exist, err = orderGift.GetByActivityId(activityId) + t.CheckErr(err) + + userPrize := new(models.UserPrize) + userPrize.UserId = userId + userPrize.ActivityId = activityId + userPrize.RehearsalId = activity.RehearsalId + userPrize.ActivityName = activity.Name + userPrize.PrizeName = orderGift.GiftName + userPrize.PrizeImg = orderGift.GiftPicUrl + userPrize.PrizeType = 3 + userPrize.IsDelete = false + userPrize.CreatedAt = time.Now() + userPrize.UpdatedAt = time.Now() + if exist && orderGift.Num == 0 { // 存在无限制 + _, err := core.GetXormAuto().Insert(userPrize) + t.CheckErr(err) + } + + order := new(models.CustomerOrder) + order.UserPrizeId = userPrize.Id + order.AreaId = entryPerson.AreaId + order.AreaName = area.Name + order.RehearsalId = activity.RehearsalId + order.BuyerId = userId + order.GoodsId = goodId + order.ActivityId = activityId + order.OrderEntryPersonId = entryPerson.Id + order.GoodsName = good.Name + order.TotalAmount = good.Price + order.OutTradeNo = helper.CreateUUID() + order.IsDelete = false + order.UpdatedAt = time.Now() + order.CreatedAt = time.Now() + _, err = core.GetXormAuto().Insert(order) + t.CheckErr(err) + + // 查出这个订单多少名 + // 防止并发出现错误 + if exist && orderGift.Num > 0 { + count, err := core.GetXormAuto().Where("created_at >= ? and activity_id=? and rehearsal_id=? and is_delete=0", + order.CreatedAt, activityId, activity.RehearsalId).Count(new(models.CustomerOrder)) + t.CheckErr(err) + if orderGift.Num >= int(count) { + _, err = core.GetXormAuto().InsertOne(userPrize) + t.CheckErr(err) + order.UserPrizeId = userPrize.Id + _, err := core.GetXormAuto().Id(order.Id).Cols("user_prize_id").Update(order) + t.CheckErr(err) + } + } + + t.SUCCESS("success") +} + +func (t *OrderEntryCtl) DeleteOrder() { + orderId := t.MustGetInt64("order_id") + order := new(models.CustomerOrder) + exist, err := core.GetXormAuto().Where("is_delete=0 and id=?", orderId).Get(order) + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "订单不存在") + _, err = new(models.CustomerOrder).SoftDeleteById(orderId) + t.CheckErr(err) + if order.UserPrizeId != 0 { + _, err = new(models.UserPrize).SoftDeleteById(order.UserPrizeId) + t.CheckErr(err) + } + t.SUCCESS("删除成功") +} + +type OrderListResult struct { + OrderId int64 `json:"order_id"` + UserId int64 `json:"user_id"` + EntryName string `json:"entry_name"` + GoodName string `json:"good_name"` + OrderTime string `json:"order_time"` + OrderMoney float64 `json:"order_money"` + Extra []map[string]interface{} `json:"extra"` // 额外信息 + ExtraData string `json:"-"` +} + +func (t *OrderEntryCtl) EntryOrders() { + uid := t.MustGetUID() + activityId := t.MustGetInt64("activity_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + list := make([]*OrderListResult, 0) + err = core.GetXormAuto().Table(new(models.CustomerOrder)).Alias("o"). + Select("l.extra_data as extra_data, g.name as good_name, o.buyer_id as user_id, o.total_amount as order_money, "+ + " o.id as order_id, DATE_FORMAT(o.created_at, '%Y-%m-%d %H:%i:%S') AS order_time"). + Join("LEFT", new(models.CustomerGoods).Alias("g"), + "o.goods_id=g.id and o.activity_id=g.activity_id and g.is_delete=0"). + Join("LEFT", new(models.InvitationLetter).Alias("l"), + "l.user_id = o.buyer_id and o.activity_id=l.activity_id and l.is_delete=0"). + Where("o.activity_id=? and o.order_entry_person_id=? and o.rehearsal_id=? and o.is_delete=0", + activityId, uid, activity.RehearsalId).Desc("o.created_at").Find(&list) + t.CheckErr(err) + + // 添加邀请函的内容 + optionItems, err := invitation_service.GetOptionItem(activityId) + t.CheckErr(err) + for i := range list { + data, err := invitation_service.GetOptionValue(optionItems, list[i].ExtraData) + t.CheckErr(err) + list[i].Extra = data + list[i].EntryName = t.MustGetName() + } + + t.JSON(map[string]interface{}{ + "list": list, + "total": len(list), + }) +} + +// 用户订单列表 +type UserOrdersResult struct { + models.CustomerOrder `xorm:"extends"` + Good *models.CustomerGoods `json:"good" xorm:"extends"` +} + +// 用户查看订单列表 +func (t *OrderEntryCtl) UserOrders() { + uid := t.MustGetUID() + + orders := make([]UserOrdersResult, 0) + s := core.GetXormAuto().Table(new(models.CustomerOrder)).Alias("o"). + Join("LEFT", new(models.CustomerGoods).Alias("g"), "o.goods_id=g.id and g.is_delete=0"). + Desc("o.created_at").Where("o.buyer_id=? and o.is_delete=0", uid) + + if t.PageSize > 0 { + s = s.Limit(t.PageSize, t.Page*t.PageSize) + } + total, err := s.Desc("o.created_at").FindAndCount(&orders) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "list": orders, + "total": total, + }) +} + +// 二维码 +func (t *OrderEntryCtl) Qrcode() { + userId := t.MustGetInt64("user_id") + activityId := t.MustGetInt64("activity_id") + goodId := t.MustGetInt64("good_id") + Url := fmt.Sprintf("%s/PcClient/Client/OrderEntryCtl/order?user_id=%d&activity_id=%d&good_id=%d", + define.HOST, userId, activityId, goodId) + qr, err := utils.Qrcode2Base64(Url) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "qrcode": qr, + }) +} diff --git a/controllers/client/reward.go b/controllers/client/reward.go new file mode 100644 index 0000000..e9e539c --- /dev/null +++ b/controllers/client/reward.go @@ -0,0 +1,104 @@ +package client + +import ( + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + pay_service "hudongzhuanjia/services/pay" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "strings" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +//打赏 +type RewardCtl struct { + controllers.AuthorCtl +} + +// todo: 支付接口 +func (t *RewardCtl) Reward() { + activityId := t.MustGetInt64("activity_id") + content := t.MustGet("content") + amount := t.MustGetDouble("amount") + uid := t.MustGetUID() + if amount <= 0 { + t.ERROR("打赏金额不能小于0", code.MSG_ERR_Param) + } + //检查内容是否包含敏感 + if models.IsSensitive(content) { + t.ERROR("内容包含敏感字", code.MSG_ERR) + } + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + //查询该活动的的打赏服务id + rewardServer := new(models.RewardServer) + exist, err = rewardServer.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_REWARD_NOT_EXIST, "打赏不存在") + + amount = utils.Float64CusDecimal(amount, 2) + + //查询用户信息 + user := new(models.User) + exist, err = models.GetById(user, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") + + ip := strings.Split(t.Request.OriginRequest.RemoteAddr, ":") + res, err := pay_service.Order("欧轩互动-打赏支付", ip[0], user.Openid, int(amount*100), 2, user.Id, activityId) + t.CheckErr(err) + + _, err = core.GetXormAuto().InsertOne(&models.RewardHistory{ + UserOrderId: res["user_order_id"].(int64), + RewardServerId: rewardServer.Id, + CustomerId: t.MustGetCustomerId(), + UserId: user.Id, + Amount: amount, + Content: content, + RehearsalId: activity.RehearsalId, + Status: -1, + ReviewTime: 0, + IsDelete: false, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + }) + t.CheckErr(err) + delete(res, "user_order_id") + delete(res, "out_trade_no") + t.JSON(res) +} + +type RWListResult struct { + Id int64 `json:"id"` + Content string `json:"content"` + Amount float64 `json:"amount"` + Status int `json:"status"` +} + +func (t *RewardCtl) List() { + uid := t.MustGetUID() + activityId := t.MustGetActivityId() + + rs := new(models.RewardServer) + exist, err := rs.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_REWARD_NOT_EXIST, "打赏不存在") + + t.CheckErr(pay_service.BatchQueryByUserId(uid)) + t.CheckErr(pay_service.BatchQueryRefundByUserId(uid)) + + list := make([]*RWListResult, 0) + err = core.GetXormAuto().Table(new(models.RewardHistory)).Select("id, content, amount, status"). + Where("is_delete=0 and user_id=? and reward_server_id=? and status <> -1", uid, rs.Id). + Desc("created_at").Find(&list) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "total": len(list), + "list": list, + }) +} diff --git a/controllers/client/shake_red_envelope.go b/controllers/client/shake_red_envelope.go new file mode 100644 index 0000000..3b85d3a --- /dev/null +++ b/controllers/client/shake_red_envelope.go @@ -0,0 +1,164 @@ +package client + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/libs/wx" + "hudongzhuanjia/models" + activity_service "hudongzhuanjia/services/activity" + pay_service "hudongzhuanjia/services/pay" + ws_send_service "hudongzhuanjia/services/ws_send" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "math/rand" + "time" +) + +type ShakeRedEnvelopeCtl struct { + controllers.AuthorCtl +} + +func (t *ShakeRedEnvelopeCtl) Status() { + ruleId := t.MustGetInt64("shake_red_envelope_rule_id") + rule := new(models.ShakeRedEnvelopeRule) + exist, err := models.GetById(rule, ruleId) + t.CheckErr(err) + t.Assert(exist, code.MSG_SHAKERB_RECORD_NOT_EXIST, "摇红包规则不存在") + t.JSON(map[string]interface{}{ + "status": rule.ShakeRedEnvelopeStatus, + }) +} + +// todo:调用支付接口 +func (t *ShakeRedEnvelopeCtl) Shake() { + customerId := t.MustGetInt64("customer_id") + ruleId := t.MustGetInt64("shake_red_envelope_rule_id") + userId := t.MustGetUID() + + // 查询摇红包规则 + rule := new(models.ShakeRedEnvelopeRule) + exist, err := models.GetById(rule, ruleId) + t.CheckErr(err) + t.Assert(exist, code.MSG_SHAKERB_RULE_NOT_EXIST, "摇红包规则不存在") + t.CheckRunning(rule.ShakeRedEnvelopeStatus) + + area := new(models.AreaStore) + exist, err = area.GetAreaStoreById(t.MustGetAreaId()) + t.CheckErr(err) + t.Assert(exist, code.MSG_SHAKERB_NOT_EXIST, "摇红包不存在") + + // 查询摇红包活动主id, is_pay=1给钱了,给摇 + envelope := new(models.ShakeRedEnvelopeActivity) + exist, err = envelope.GetPayedById(rule.ShakeRedEnvelopeActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_SHAKERB_NOT_EXIST, "摇红包不存在") + + activity := new(models.Activity) + exist, err = models.GetById(activity, envelope.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + moduleService, exist, err := activity_service.GetModuleService(define.MODULE_SHAKRB, activity.Id) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "活动模块不存在") + + record := new(models.ShakeRedEnvelopeRecord) /// 之后使用, 存入乐观锁 + if moduleService.BesideRepeat == define.MODULE_BESIDE_REPEAT { // 剔除摇过红包的用户 + exist, err := record.ExistRecord(activity.RehearsalId, activity.Id, rule.Id, envelope.Id, userId) + t.CheckErr(err) + t.Assert(!exist, code.MSG_SHAKERB_RECORD_NOT_EXIST, "您已经摇过红包了,请等待下一轮.") // 不存在继续往下走 + } + // done: 增加概率, 修改概率 + r := rand.New(rand.NewSource(time.Now().UnixNano())) + t.Assert(r.Float64()*100 <= rule.Probability, code.MSG_ERR, "您与红包擦肩而过") // 必须在红包概率以内才能获取 + + // 增加session 或者乐观锁 + exist, err = record.GetByRuleId(ruleId, activity.RehearsalId) + t.CheckErr(err) + t.Assert(exist, code.MSG_SHAKERB_RECORD_NOT_EXIST, "红包已经派发完毕") + + // 查询用户 + user := new(models.User) + exist, err = models.GetById(user, userId) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") + + + record.IsDraw = 0 + // 记录红包 ---> 非彩排才能 + if activity.RehearsalId == 0 { + res, err := pay_service.SendRedPack("欧轩互动", user.Openid, fmt.Sprintf("感谢您参加%s", activity.Name), + "", rule.Model, "摇得越快抢得越多", int(record.Amount * 100), 1, 1) + t.CheckErr(err) + record.MchBillno = res.MchBillno + record.Reason = fmt.Sprintf("%s:%s", res.ErrCode, res.ErrCodeDes) + record.Status = res.ResultCode + record.ReOpenid = user.Openid + if res.ResultCode == wx.CODE_SUCCESS && res.ErrCode == wx.CODE_SUCCESS { + record.IsDraw = 1 + } + } + + record.UserId = user.Id + record.UserName = user.Nickname + record.UserPhone = user.Phone + record.AreaName = area.Name + record.Name = activity.Name + row, err := record.UpdateAllColsById(record.Id) + t.CheckErr(err) + t.Assert(row == 1, code.MSG_ERR, "您与红包擦肩而过") // 那么 row == 1 为已经成功抢到 + + // 通知大屏 + total, err := new(models.ShakeRedEnvelopeRecord).Total(activity.Id, activity.RehearsalId, envelope.Id, rule.Id) + remaining, err := new(models.ShakeRedEnvelopeRecord).Count(activity.Id, activity.RehearsalId, envelope.Id, rule.Id, -1) + t.CheckErr(err) + + customer := new(models.Customer) + exist, err = models.GetById(customer, customerId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + go ws_send_service.SendShakeRedEnvelope(fmt.Sprintf("%d", activity.Id), + define.TYPE_USER, userId, map[string]interface{}{ + "customer_id": customer.Id, + "user_id": user.Id, + "type": "shake_rb", + "data": map[string]interface{}{ + "amount": record.Amount, + "nickname": user.Nickname, + "avatar": user.Avatar, + "total": total - remaining, // + "remaining": remaining, // + }, + }) + + go ws_send_service.SendShakeRedEnvelope(fmt.Sprintf("%d", activity.Id), + define.TYPE_CUSTOMER, customerId, map[string]interface{}{ + "customer_id": customer.Id, + "user_id": user.Id, + "type": "shake_rb", + "data": map[string]interface{}{ + "amount": record.Amount, + "nickname": user.Nickname, + "avatar": user.Avatar, + "total": total - remaining, // + "remaining": remaining, // + }, + }) + + t.JSON(map[string]interface{}{ + "amount": record.Amount, + "shake_red_envelope_record_id": record.Id, + }) +} + +// 用户红包 +func (t *ShakeRedEnvelopeCtl) UserRedEnvelopes() { + records, err := models.GetRedEnvelopesByUserId(t.MustGetUID()) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "list": records, + "total": len(records), + }) +} diff --git a/controllers/client/sign.go b/controllers/client/sign.go new file mode 100644 index 0000000..7159217 --- /dev/null +++ b/controllers/client/sign.go @@ -0,0 +1,96 @@ +package client + +import ( + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + ws_send_service "hudongzhuanjia/services/ws_send" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" +) + +//签到 +type SignCtl struct { + controllers.AuthorCtl +} + +//签到动作 +func (t *SignCtl) Sign() { + uid := t.MustGetUID() + activityId := t.MustGetInt64("activity_id") + customerId := t.MustGetInt64("customer_id") + + //根据activity_id查找主活动的信息 + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + customer := new(models.Customer) + exist, err = models.GetById(customer, customerId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + user := new(models.User) + exist, err = models.GetById(user, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") + + //根据activity_id查找副活动的规则信息 + signUp := new(models.SignUp) + exist, err = signUp.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "签到规则不存在") + + if signUp.OnlyInvitation == 1 { // + // 邀请函才能签到 + letter := new(models.InvitationLetter) + exist, err := letter.GetByUserIdAndActivityId(uid, activityId, activity.RehearsalId) + t.CheckErr(err) + t.Assert(exist, code.MSG_INVITE_LETTER_NOT_EXIST, "您没收到邀请函") + } + //检查是否已经签到了 + signHistory := new(models.SignHistory) + exist, err = signHistory.GetByUserId(activityId, uid, activity.RehearsalId, t.MustGetAreaId()) + t.CheckErr(err) + t.Assert(!exist, code.MSG_SIGN_HISTORY_EXIST, "您已经签到过了") // 存在判断 + + // 签到人数 + signTotal, err := core.GetXormAuto().Where("is_delete=0 and sign_rule_id=? and rehearsal_id=? and activity_id=?", + signUp.Id, activity.RehearsalId, activity.Id).Count(signHistory) + t.CheckErr(err) + + signUpTotal, err := core.GetXormAuto().Where("is_delete=0 and activity_id=?", activity.Id).Count(new(models.InvitationLetter)) + t.CheckErr(err) + + if activity.RehearsalId != 0 && signTotal >= 10 { + t.ERROR("彩排人数不能超过10人", code.MSG_SIGN_UP_REHEARSAL_LIMIT) + } + + signHistory = new(models.SignHistory) + signHistory.UserId = uid + signHistory.RehearsalId = activity.RehearsalId + signHistory.ActivityId = activityId + signHistory.SignRuleId = signUp.Id + signHistory.AreaId = user.AreaId + signHistory.IsDelete = false + signHistory.UpdatedAt = time.Now() + signHistory.CreatedAt = time.Now() + _, err = core.GetXormAuto().InsertOne(signHistory) + t.CheckErr(err) + + go ws_send_service.SendSign(fmt.Sprintf("%d", activity.Id), + define.TYPE_CUSTOMER, customerId, map[string]interface{}{ + "type": "sign_up", + "customer_id": customer.Id, + "data": map[string]interface{}{ + "avatar": user.Avatar, + "sign_total": signTotal + 1, + "sign_up_total": signUpTotal, + }, + }) + t.SUCCESS("签到成功") +} diff --git a/controllers/client/tug_war.go b/controllers/client/tug_war.go new file mode 100644 index 0000000..5a7f0c5 --- /dev/null +++ b/controllers/client/tug_war.go @@ -0,0 +1,211 @@ +package client + +import ( + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + bahe_service "hudongzhuanjia/services/bahe" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type TugOfWarCtl struct { + controllers.AuthorCtl +} + +// 获取当前状态(废弃) +// @Summary client tug war +// @Description get current status +// @Tags client tug war +// @Accept json +// @Produce json +// @Param bahe_activity_id query int true "Bahe Activity ID" +// @Success 0 {object} models.TugOfWar +// @Failure 503 {string} string "参数不存在" +// @Failure 504 {object} string "用户不存在" +// @Router /Client/TugOfWarCtl/status [get] +func (t *TugOfWarCtl) Status() { + // 获取此次活动的状态 + baheId := t.MustGetInt64("bahe_activity_id") + uid := t.MustGetUID() + // 找到活动 + bahe := new(models.TugOfWar) + exist, err := models.GetById(bahe, baheId) + t.CheckErr(err) + t.Assert(exist, code.MSG_TUGWAR_NOT_EXIST, "拔河不存在") + + // 主活动 + activity := new(models.Activity) + exist, err = models.GetById(activity, bahe.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存") + + // 找到用户 + member := new(models.BaheTeamMember) + exist, err = member.GetMemberByBaheIdAndUserId(uid, bahe.Id, activity.RehearsalId) + t.CheckErr(err) + t.Assert(exist, code.MSG_TUGWAR_MEMBER_NOT_EXIST, "队员不存在") + + score, err := bahe_service.GetScoreByTeamId(member.TeamId, activity.RehearsalId) + t.CheckErr(err) + rank := 1 + team := new(models.BaheTeam) + exist, err = models.GetById(team, member.TeamId) + t.CheckErr(err) + t.Assert(exist, code.MSG_TUGWAR_TEAM_NOT_EXIST, "队伍不存在") + + otherTeam := new(models.BaheTeam) + exist, err = otherTeam.GetOtherTeam(member.TeamId, team.BaheActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_TUGWAR_TEAM_NOT_EXIST, "队伍不存在") + + otherScore, err := bahe_service.GetScoreByTeamId(otherTeam.Id, activity.RehearsalId) + t.CheckErr(err) + if otherScore > score { + rank = 2 + } + + t.JSON(map[string]interface{}{ + "status": bahe.Status, + "score": score, + "rank": rank, + }) +} + +// tug_war doc +// @Summary tug war +// @Description shake bahe activity +// @Tags tug war +// @Accept json +// @Produce json +// @Param bahe_activity_id query int true "Bahe Activity ID" +// @Success 0 {object} models.TugOfWar +// @Success 0 {object} models.BaheTeamMember +// @Success 0 {object} models.BaheTeam +// @Failure 404 {string} string "参数不存在" +// @Failure 405 {object} string "用户不存在" +// @Router /Client/TugOfWarCtl/shake [get] +func (t *TugOfWarCtl) Shake() { + uid := t.MustGetUID() + baheId := t.MustGetInt64("bahe_activity_id") + score := t.MustGetInt64("score") // 增加的分数 + + bahe := new(models.TugOfWar) + exist, err := models.GetById(bahe, baheId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "拔河活动不存在") + t.CheckRunning(bahe.Status) + + activity := new(models.Activity) + exist, err = models.GetById(activity, bahe.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + member := new(models.BaheTeamMember) + exist, err = member.GetMemberByBaheIdAndUserId(uid, baheId, activity.RehearsalId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ERR, "该用户尚未加入队伍") + + if score != 0 { + _, err = member.IncrScoreById(member.Id, score) + t.CheckErr(err) + member.Score += score + } + + // 根据team_id 获取所有成员的分数 + members := make([]*models.BaheTeamMember, 0) + err = core.GetXormAuto().Where("is_delete=0 and team_id=? and rehearsal_id=?", + member.TeamId, member.RehearsalId).Desc("score").Asc("sort_time").Find(&members) + t.CheckErr(err) + + var rank int + for index, m := range members { + if m.Id == member.Id { + rank = index + 1 + break + } + } + + t.JSON(map[string]interface{}{ + "rank": rank, // 队内排名 + "score": member.Score, // 人员分数 + }) +} + +type JoinTeamResult struct { + Number int + TeamId int64 + TeamName string +} + +func (t *TugOfWarCtl) JoinTeam() { + teamId := t.MustGetInt64("bahe_team_id") + baheActivityId := t.MustGetInt64("bahe_activity_id") + uid := t.MustGetUID() + + bahe := new(models.TugOfWar) + exist, err := models.GetById(bahe, baheActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_TUGWAR_TEAM_OVER_LIMIT, "拔河不存在") + if bahe.Status == define.StatusEnding { + t.ERROR("该拔河活动已结束", code.MSG_MODULE_STATUS_END) + } + + activity := new(models.Activity) + exist, err = models.GetById(activity, bahe.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + // 判斷是否已經存在该用户 + member := new(models.BaheTeamMember) + exist, err = member.GetMemberByBaheIdAndUserId(uid, bahe.Id, activity.RehearsalId) + t.CheckErr(err) + if exist { // 存在改用户 + t.JSON(map[string]interface{}{ + "member": member, + }) + return + } + + team := new(JoinTeamResult) + session := core.GetXormAuto().Table(new(models.BaheTeam)).Alias("t"). + Select("t.id as team_id, t.bahe_team_name as team_name, count(m.id) as number"). + Join("LEFT", new(models.BaheTeamMember).Alias("m"), + "m.team_id=t.id and m.is_delete=0 and m.rehearsal_id=?", activity.RehearsalId) + if teamId == 0 { // 人数最少的一队 + session = session.Where("t.is_delete=0 and t.bahe_activity_id=? ", bahe.Id). + GroupBy("t.id").Asc("number") + } else { + session = session.Where("t.is_delete=0 and t.id=?", teamId).GroupBy("t.id") + } + exist, err = session.Get(team) + t.CheckErr(err) + t.Assert(exist, code.MSG_ERR, "队伍信息错误, 请重新扫码") + t.Assert(team.Number < bahe.Number, code.MSG_TUGWAR_TEAM_OVER_LIMIT, "队伍满人,请等待下一轮") + + // done: 均等分配 + 人数限制 + user := new(models.User) + exist, err = models.GetById(user, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") + + member.TeamId = team.TeamId + member.TeamName = team.TeamName + member.MemberId = uid + member.Avatar = user.Avatar + member.NickName = user.Nickname + member.BaheActivityId = baheActivityId + member.RehearsalId = activity.RehearsalId + member.SortTime = time.Now().UnixNano() + member.CreatedAt = time.Now() + member.UpdatedAt = time.Now() + _, err = core.GetXormAuto().InsertOne(member) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "member": member, + }) +} diff --git a/controllers/client/upper_wall.go b/controllers/client/upper_wall.go new file mode 100644 index 0000000..e3ceb10 --- /dev/null +++ b/controllers/client/upper_wall.go @@ -0,0 +1,86 @@ +package client + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/code" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type UpperWallCtl struct { + controllers.AuthorCtl +} + +//发送上墙消息 +// todo: 支付接口 +func (t *UpperWallCtl) Send() { + uid := t.MustGetUID() + activityId := t.MustGetActivityId() + category := t.MustGetInt("category") + content, _ := t.Get("content") + img, _ := t.Get("img") + + //获取主活动信息 + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + msgWall := new(models.MsgWallServer) + exist, err = msgWall.GetByActivityId(activityId) + t.CheckErr(err) + if !exist || msgWall.UpWallStatus == "关闭" { + t.ERROR("上墙活动尚未开启", code.MSG_ERR) + } + + //获取用信息 + user := new(models.User) + exist, err = models.GetById(user, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") + + uw := new(models.UpperWall) + uw.RehearsalId = activity.RehearsalId + uw.ActivityId = activityId + uw.Category = fmt.Sprintf("%v", category) + uw.UserId = user.Id + uw.Content = content + uw.Img = img + uw.Status = 0 + uw.CreatedAt = time.Now() + uw.UpdatedAt = time.Now() + _, err = core.GetXormAuto().Insert(uw) + t.CheckErr(err) + t.SUCCESS("成功") +} + +type UWListResult struct { + Id int64 `json:"id"` + Content string `json:"content"` + Img string `json:"img"` + Category string `json:"category"` + Status int `json:"status"` +} + +func (t *UpperWallCtl) List() { + activityId := t.MustGetActivityId() + uid := t.MustGetUID() + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + list := make([]*UWListResult, 0) + err = core.GetXormAuto().Table(new(models.UpperWall)).Select("id, content, img, category, status"). + Where("is_delete=0 and user_id=? and activity_id=? and rehearsal_id=?", uid, activityId, activity.RehearsalId). + OrderBy("created_at desc").Find(&list) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "list": list, + "total": len(list), + }) +} diff --git a/controllers/client/vote.go b/controllers/client/vote.go new file mode 100644 index 0000000..5c7c992 --- /dev/null +++ b/controllers/client/vote.go @@ -0,0 +1,128 @@ +package client + +import ( + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/code" + "time" +) + +type VoteCtl struct { + controllers.AuthorCtl +} + +//投票 +func (t *VoteCtl) Vote() { + uid := t.MustGetUID() + ladderId := t.MustGetInt64("vote_activity_ladder_id") + + //检查是否可以投票 + ladder := new(models.NewVoteActivityLadder) + exist, err := models.GetById(ladder, ladderId) + t.CheckErr(err) + t.Assert(exist, code.MSG_VOTE_LADDER_NOT_EXIST, "投票人不存在") + + vote := new(models.NewVoteActivity) + exist, err = models.GetById(vote, ladder.VoteActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "投票活动不存在") + t.CheckRunning(vote.VoteStatus) + + activity := new(models.Activity) + exist, err = models.GetById(activity, vote.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + history := new(models.NewVoteActivityHistory) + exist, err = history.ExistByLadderId(uid, ladderId, activity.RehearsalId) + t.CheckErr(err) + t.Assert(!exist, code.MSG_VOTE_HISTORY_EXIST, "您已经投过票了") + + if vote.Model == "单选" { + //检查是否已经投过票了 + exist, err = history.ExistByVoteId(uid, vote.Id, activity.RehearsalId) + t.CheckErr(err) + t.Assert(!exist, code.MSG_VOTE_HISTORY_EXIST, "您已经投过票了") + } else { + num, err := history.CountUser(uid, activity.RehearsalId, vote.Id) + t.CheckErr(err) + if num >= vote.ModelNum { + t.ERROR(fmt.Sprintf("您投票人数已超过%d人", vote.ModelNum), code.MSG_ERR) + } + } + // done: 增加人数限制 + history.UserId = uid + history.RehearsalId = activity.RehearsalId + history.VoteActivityId = vote.Id + history.VoteActivityLadderId = ladderId + history.IsDelete = false + history.CreatedAt = time.Now() + history.UpdatedAt = time.Now() + _, err = core.GetXormAuto().InsertOne(history) + t.CheckErr(err) + + // vote ladder total_number + 1 + _, err = ladder.Incr(ladderId, 1) + t.CheckErr(err) + + t.SUCCESS("投票成功") +} + +// 投票活动列表 +func (t *VoteCtl) List() { + activityId := t.MustGetInt64("activity_id") + + // 该活动是否进行中 + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + votes := make([]*models.NewVoteActivity, 0) + err = core.GetXormAuto().Where("is_delete=0 and activity_id=?", activityId).Desc("created_at").Find(&votes) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(votes), + "votes": votes, + }) +} + +func (t *VoteCtl) Detail() { + voteActivityId := t.MustGetInt64("vote_activity_id") + uid := t.MustGetUID() + activityId := t.MustGetActivityId() + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + ladders := make([]*models.NewVoteActivityLadder, 0) + err = core.GetXormAuto().Where("is_delete=0 and vote_activity_id=?", voteActivityId). + Desc("total_number").Asc("updated_at").Find(&ladders) + t.CheckErr(err) + + histories := make([]*models.NewVoteActivityHistory, 0) + err = core.GetXormAuto().Where("is_delete=0 and user_id=? and rehearsal_id=? and vote_activity_id=?", + uid, activity.RehearsalId, voteActivityId).Find(&histories) + t.CheckErr(err) + + for i := range ladders { + for j := range histories { + if ladders[i].Id == histories[j].VoteActivityLadderId { + ladders[i].IsVote = true + break + } + } + } + + t.JSON(map[string]interface{}{ + "total": len(ladders), + "members": ladders, + }) +} diff --git a/controllers/client/wx.go b/controllers/client/wx.go new file mode 100644 index 0000000..c9511b3 --- /dev/null +++ b/controllers/client/wx.go @@ -0,0 +1,80 @@ +package client + +import ( + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/helper" + "hudongzhuanjia/controllers" + "hudongzhuanjia/libs/wx" + "hudongzhuanjia/utils" + "time" +) + +type WxCtl struct { + controllers.AuthorCtl +} + +const SignUrl = "jsapi_ticket=%s&noncestr=%s×tamp=%d&url=%s" + +type TicketCache struct { + Url string `json:"url" xorm:"not null comment('路径')"` + Token string `json:"-" xorm:"not null comment('token')"` + TokenExpired int64 `json:"ticket_expired" xorm:"not null default(0) comment('token过期时间')"` + Ticket string `json:"ticket" xorm:"not null comment('ticket')"` + TicketExpired int64 `json:"ticket_expired" xorm:"not null default(0) comment('ticket 过期时间')"` +} + +var cache TicketCache + +// 检测token是否过期 +// 检测ticket是否过期 +func (t *WxCtl) Ticket() { + url := t.MustGet("url") + nonceStr := helper.CreateUUID() + timestamp := time.Now().Unix() + + if cache.TokenExpired <= time.Now().Unix() { + token, err := wx.GetTicketToken() + t.CheckErr(err) + if token.ErrCode != 0 { + t.ERROR(token.ErrMsg, token.ErrCode) + } + cache.Token = token.AccessToken + cache.TokenExpired = token.ExpiresIn + 7200 + } + if cache.TicketExpired <= time.Now().Unix() { + ticket, err := wx.GetTicket(cache.Token) + t.CheckErr(err) + if ticket.ErrCode != 0 { + t.ERROR(ticket.ErrMsg, ticket.ErrCode) + } + cache.TicketExpired = ticket.ExpiresIn + 7200 + cache.Ticket = ticket.Ticket + } + query := fmt.Sprintf(SignUrl, cache.Ticket, nonceStr, timestamp, url) + signature := utils.Sha1(query) + t.JSON(map[string]interface{}{ + "signature": signature, + "noncestr": nonceStr, + "timestamp": timestamp, + "ticket": cache.Ticket, + "appid": wx.Appid, + }) +} + +type WechatPay struct { +} + +//func (t *WxCtl) Order() { +// userId := t.MustGetUID() +// content := t.MustGet("content") +// amount := t.MustGetInt("amount") +// +// user := new(models.User) +// exist, err := models.GetById(user, userId) +// t.CheckErr(err) +// t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在") +// +// ip := strings.Split(t.Request.OriginRequest.RemoteAddr, ":") +// res, err := pay_service.Order(content, ip[0], user.Openid, amount, 1, user.Id) +// t.JSON(res) +//} diff --git a/controllers/common/annex.go b/controllers/common/annex.go new file mode 100644 index 0000000..63ffc32 --- /dev/null +++ b/controllers/common/annex.go @@ -0,0 +1,41 @@ +package common + +import ( + "github.com/ouxuanserver/osmanthuswine/src/helper" + "context" + "fmt" + "hudongzhuanjia/controllers" + "net/http" + "net/url" + "path" + "time" + + "github.com/tencentyun/cos-go-sdk-v5" +) + +const upload_base_path = "html/annex" + +type AnnexCtl struct { + controllers.AuthorCtl +} + +//上传 +func (t *AnnexCtl) Upload() { + //计算文件得md5 + uploadFile, err := t.Request.FILE.Open() + u, _ := url.Parse("https://hudongzhuanjia-1251209212.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{BucketURL: u} + client := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: "AKIDo2B9WqpvkSKQPPpplVAdv65QdpDfMRIz", + SecretKey: "fEcu35xdCbpU3azFLH2lU2f8UpAOQHZs", + }, + }) + picName := fmt.Sprintf("hdzj/upload/%d%s%s", time.Now().UnixNano(), helper.CreateUUID(), path.Ext(t.Request.FILE.Filename)) + _, err = client.Object.Put(context.Background(), picName, uploadFile, nil) + t.CheckErrDisplayByError(err) + + t.DisplayByData(map[string]interface{}{ + "url": fmt.Sprintf("%s/%s", u.String(), picName), + }) +} diff --git a/controllers/common/test/123.gif b/controllers/common/test/123.gif new file mode 100644 index 0000000..e60572b Binary files /dev/null and b/controllers/common/test/123.gif differ diff --git a/controllers/common/test/annex_test.go b/controllers/common/test/annex_test.go new file mode 100644 index 0000000..beb2630 --- /dev/null +++ b/controllers/common/test/annex_test.go @@ -0,0 +1,43 @@ +package test + +import ( + "context" + "fmt" + "github.com/tencentyun/cos-go-sdk-v5" + "net/http" + "net/url" + "os" + "path" + "testing" + "time" +) + +func TestAnnexUpload(t *testing.T) { + u, _ := url.Parse("https://hudongzhuanjia-1251209212.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{BucketURL: u} + client := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: "AKIDo2B9WqpvkSKQPPpplVAdv65QdpDfMRIz", + SecretKey: "fEcu35xdCbpU3azFLH2lU2f8UpAOQHZs", + }, + }) + gifFile, err := os.OpenFile("123.gif", os.O_RDONLY, os.ModePerm) + if err != nil { + t.Fatal(err) + } + + picName := fmt.Sprintf("hdzj/upload/%d%s", time.Now().UnixNano(), path.Ext(gifFile.Name())) + _, err = client.Object.Put(context.Background(), picName, gifFile, nil) + if err != nil { + t.Fatal(err) + } + fmt.Println("上传成功,路径:", fmt.Sprintf("%s/%s", u.String(), picName)) + objs := []cos.Object{cos.Object{Key: picName}} + odmo := new(cos.ObjectDeleteMultiOptions) + odmo.Objects = objs + odmr, _, err := client.Object.DeleteMulti(context.Background(), odmo) + if err != nil { + t.Fatal(err) + } + fmt.Println(odmr) +} diff --git a/controllers/common/wechat_oauth.go b/controllers/common/wechat_oauth.go new file mode 100644 index 0000000..6612729 --- /dev/null +++ b/controllers/common/wechat_oauth.go @@ -0,0 +1,96 @@ +package common + +import ( + "crypto/sha1" + "encoding/xml" + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/logger" + "hudongzhuanjia/services/pay" + "time" +) + +var Now = time.Now() + +type WeChatOauthCtl struct { + controllers.BaseCtl +} + +const token = "hd_oauth" + +// 验证服务器资源配置 +func (t *WeChatOauthCtl) Oauth() { + signature := t.MustGet("signature") + timestamp := t.MustGet("timestamp") + nonce := t.MustGet("nonce") + echoStr := t.MustGet("echostr") + tokenStr := fmt.Sprintf("%s%s%s", token, timestamp, nonce) + s := fmt.Sprintf("%s", sha1.New().Sum([]byte(tokenStr))) + if s == signature { + t.OriginResponseWriter.Write([]byte(echoStr)) + } + t.OriginResponseWriter.Write([]byte("failed")) +} + +func (t *WeChatOauthCtl) Checkin() { + t.JSON(map[string]interface{}{ + "success": "你好, tommy黄梓健", + "version": Now, + "ip": t.Request.OriginRequest.RemoteAddr, + }) +} + +// +//func init() { +// ticker := time.NewTicker(5 * time.Second) +// go func() { +// fmt.Println("循环查询订单数据") +// for range ticker.C { +// pay_service.BatchQuery() +// } +// }() +// +//} + +type CallbackParam struct { + XMLName xml.Name `xml:"xml"` + ReturnCode string `xml:"return_code"` + ReturnMsg string `xml:"return_msg"` +} + +func (t *WeChatOauthCtl) CallbackOrder() { + // 搜索支付的order表, 查找到某条记录 + logger.Sugar.Infof("%s", t.Request.OriginRequest.RemoteAddr) + t.CheckErr(pay_service.CallbackOrder(t.Request.OriginRequest)) + param := new(CallbackParam) + param.ReturnCode = "SUCCESS" + param.ReturnMsg = "OK" + xmlRes, _ := xml.Marshal(param) + t.XML(xmlRes) +} + +func (t *WeChatOauthCtl) CallbackRefund() { + logger.Sugar.Infof("%s", t.Request.OriginRequest.RemoteAddr) + t.CheckErr(pay_service.CallbackRefund(t.Request.OriginRequest)) + param := new(CallbackParam) + param.ReturnCode = "SUCCESS" + param.ReturnMsg = "OK" + xmlRes, _ := xml.Marshal(param) + t.XML(xmlRes) +} + +//func (t *WeChatOauthCtl) SendRedPack() { +// user := new(models.User) +// exist, err := models.GetById(user, 234) +// t.CheckErr(err) +// if !exist { +// t.ERROR(fmt.Sprintf("error occur: %s", err), 120) +// } +// res, err := pay_service.SendRedPack("欧轩互动", user.Openid, "测试", "123.207.246.51", +// "测试", "测试", 100, 1, 1, user.Id, 1) +// t.CheckErr(err) +// fmt.Printf("%+v", res) +// t.JSON(map[string]interface{}{ +// "result": res, +// }) +//} diff --git a/controllers/pc/activity.go b/controllers/pc/activity.go new file mode 100644 index 0000000..2bc1662 --- /dev/null +++ b/controllers/pc/activity.go @@ -0,0 +1,150 @@ +package pc + +import ( + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" +) + +//活动 +type ActivityCtl struct { + controllers.AuthorCtl +} + +// 废弃 +func (t *ActivityCtl) List() { + customerId := t.MustGetUID() + list := make([]*models.Activity, 0) + err := core.GetXormAuto().Where("is_delete=0 and customer_id=? and status<>?", + customerId, define.StatusEnding).Find(&list) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "list": list, + "total": len(list), + }) +} + +func (t *ActivityCtl) StartActivity() { + activityId := t.MustGetInt64("activity_id") + mode := t.MustGetInt("mode") // 标识彩排 mode=0正式 mode=1彩排 + uid := t.MustGetUID() + limit := t.DefaultInt64("limit", 10) + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + // 检测活动状态 ==》 必须为未开始 + if activity.Status != define.StatusNotBegin { + t.ERROR(fmt.Sprintf("该活动状态%s", activity.Status), code.MSG_ERR) + } + + // 检测彩排活动是否进行中 + if activity.RehearsalId != 0 { + t.ERROR("该活动在彩排中", code.MSG_ERR) + } + + var rehearsalId int64 = 0 + if mode == 1 { + rehearsal := new(models.Rehearsal) + rehearsal.Status = 1 + rehearsal.ActivityId = activityId + rehearsal.CustomerId = uid + rehearsal.LimitNumber = limit + rehearsal.IsDelete = false + rehearsal.UpdatedAt = time.Now() + rehearsal.CreatedAt = time.Now() + _, err := core.GetXormAuto().InsertOne(rehearsal) + t.CheckErr(err) + rehearsalId = rehearsal.Id + } + + activity.Status = define.StatusRunning + activity.RehearsalId = rehearsalId + activity.UpdatedAt = time.Now() + // todo: 校验 + err = models.Save(map[string]interface{}{ + "id=": activityId, + "is_delete=": 0, + }, activity, "status", "rehearsal_id", "updated_at") + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "rehearsal_id": rehearsalId, + }) +} + +func (t *ActivityCtl) StopActivity() { + activityId := t.MustGetInt64("activity_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + if activity.Status != define.StatusRunning { + t.ERROR(fmt.Sprintf("该活动%s", activity.Status), code.MSG_ERR) + } + + if activity.RehearsalId != 0 { // 彩排回归最初结果 + // todo:其他的活动也要回复到最初的状态 + // 竞拍 + _, err = models.UpdateAuctionStatusByActivityId(activityId) + t.CheckErr(err) + + // 抽奖 + lotteryIds, err := models.GetLDActivityIdsByActivityId(activityId) + t.CheckErr(err) + //_, err = models.UpdateLDRuleStatusByLDActiviytIds(lotteryIds) + lotteryRuleIds, err := models.GetLDRuleIdsByLDActivityId(lotteryIds) + t.CheckErr(err) + _, err = models.UpdateLDLadderStatusByLDRuleIds(lotteryRuleIds) + t.CheckErr(err) + + // 订单抽奖 + orderIds, err := models.GetODActivityIdsByActivityId(activityId) + t.CheckErr(err) + //_, err = models.UpdateODRuleStatusByODActivityIds(orderIds) + orderRuleIds, err := models.GetODRuleIdsByODActivityIds(orderIds) + t.CheckErr(err) + _, err = models.UpdateODLadderStatusByODRuleIds(orderRuleIds) + t.CheckErr(err) + + // 摇红包 + shakeRbIds, err := models.GetSREActivityIdsByActivityId(activityId) + t.CheckErr(err) + _, err = models.UpdateSRERuleStatusBySREActivityIds(shakeRbIds) + t.CheckErr(err) + + // 拔河 + _, err = models.UpdateTOWStatusByActivityId(activityId) + t.CheckErr(err) + + // 投票 + _, err = models.UpdateVoteStatusByActiviytId(activityId) + t.CheckErr(err) + + // 卡路里 + _, err = models.UpdateCalorieStatusByActivityId(activityId) + t.CheckErr(err) + + // 订单开启 + _, err = new(models.CustomerOrderOption).Switch(activityId, 0) + t.CheckErr(err) + + activity.Status = define.StatusNotBegin + } else { + activity.Status = define.StatusEnding + } + activity.UpdatedAt = time.Now() + activity.RehearsalId = 0 + models.Save(map[string]interface{}{ + "id=": activity.Id, + }, activity, "status", "rehearsal_id", "updated_at") + t.SUCCESS("success") +} diff --git a/controllers/pc/area_store.go b/controllers/pc/area_store.go new file mode 100644 index 0000000..936dce9 --- /dev/null +++ b/controllers/pc/area_store.go @@ -0,0 +1,31 @@ +package pc + +import ( + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" +) + +//地区店铺 +type AreaStoreCtl struct { + controllers.AuthorCtl +} + +// all area store doc +// @Summary activity +// @Description get all area store +// @Tags pc +// @Accept json +// @Produce json +// @Success 200 {string} string "success" +// @Router /Pc/ActivityCtl/list [get] +func (t *AreaStoreCtl) List() { + activityId := t.MustGetInt64("activity_id") + + list, err := models.GetAreaStoresByActivityId(activityId) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(list), + "list": list, + }) +} diff --git a/controllers/pc/auction.go b/controllers/pc/auction.go new file mode 100644 index 0000000..694fa82 --- /dev/null +++ b/controllers/pc/auction.go @@ -0,0 +1,264 @@ +package pc + +import ( + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + ws_send_service "hudongzhuanjia/services/ws_send" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "strconv" + "time" +) + +//竞拍 +type AuctionCtl struct { + controllers.AuthorCtl +} + +// 竞拍准备状态 +func (t *AuctionCtl) ReadyAuction() { + auctionId := t.MustGetInt64("auction_activity_id") + auction := new(models.NewAuctionActivity) + exist, err := models.GetById(auction, auctionId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "竞拍活动不存在") + if auction.Status != define.StatusNotBegin { + t.ERROR(fmt.Sprintf("该活动%s", auction.Status), code.MSG_ERR) + } + _, err = auction.UpdateToStatusByAid(auction.ActivityId, define.StatusReady, define.StatusNotBegin) + t.CheckErr(err) + + _, err = auction.UpdateStatusById(auction.Id, define.StatusReady) + t.CheckErr(err) + t.SUCCESS("success") +} + +//开始竞拍 +// auction doc +// @Summary auction +// @Description 开始竞拍 +// @Tags pc +// @Accept json +// @Produce json +// @Param auction_activity_id query int true "竞拍id" +// @Success 200 {string} string "success" +// @Router /Pc/AuctionCtl/startAuction [get] +func (t *AuctionCtl) StartAuction() { + auctionId := t.MustGetInt64("auction_activity_id") + + auction := new(models.NewAuctionActivity) + exist, err := models.GetById(auction, auctionId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "竞拍活动不存在") + //彩排 + if auction.Status != define.StatusReady { + t.ERROR(fmt.Sprintf("该活动%s", auction.Status), code.MSG_ERR) + } + auction.Status = define.StatusRunning + auction.UpdatedAt = time.Now() + duration, _ := strconv.ParseInt(auction.AuctionDuration, 10, 64) + auction.AuctionEndTime = time.Now().Unix() + duration + _, err = core.GetXormAuto().Where("is_delete=0 and id=?", auctionId). + Cols("status", "auction_end_time", "updated_at").Update(auction) + t.CheckErr(err) + + t.STRING("操作成功") +} + +//停止竞拍 +// auction doc +// @Summary auction +// @Description 结束竞拍 +// @Tags pc +// @Accept json +// @Produce json +// @Param auction_activity_id query int true "竞拍id" +// @Success 200 {string} string "success" +// @Router /Pc/AuctionCtl/stopAuction [get] +func (t *AuctionCtl) StopAuction() { + auctionId := t.MustGetInt64("auction_activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + auction := new(models.NewAuctionActivity) + exist, err := models.GetById(auction, auctionId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "竞拍活动不存在") + + if auction.Status != define.StatusRunning { + t.ERROR(fmt.Sprintf("该活动%s", auction.Status), code.MSG_ERR) + } + auction.Status = define.StatusEnding + auction.UpdatedAt = time.Now() + auction.AuctionEndTime = 0 // 消除结束时间计时 + _, err = core.GetXormAuto().Where("is_delete=0 and id=?", auctionId). + Cols("status", "auction_end_time", "updated_at").Update(auction) + t.CheckErr(err) + + // todo: 记录用户最高价 + if auction.AuctionModel == define.INCR_AUCTION { + history := new(models.AuctionHistory) + _, err := history.GetHighestMoney(rehearsalId, auction.Id) // 区分彩排数据 + t.CheckErr(err) + + user := new(models.User) + exist, err := models.GetById(user, history.UserId) + t.CheckErr(err) + if exist { + record := new(models.AuctionResultRecord) + record.AuctionActivityId = auctionId + record.RehearsalId = rehearsalId // 彩排 + record.AuctionGoodsName = auction.AuctionGoodsName + record.ActivityId = auction.ActivityId + record.UserId = history.UserId + record.UserPhone = user.Phone + record.UserName = user.Nickname + record.Unit = history.Unit + record.DealPrice = history.Money + record.PlayerCode = history.PlayerCode + record.UpdatedAt = time.Now() + record.CreatedAt = time.Now() + record.IsDelete = false + + go ws_send_service.SendAuction(fmt.Sprintf("%d", record.ActivityId), + "", 0, map[string]interface{}{ + "type": "auction", + "data": map[string]interface{}{ + "auction_activity_id": auction.Id, + "activity_id": auction.ActivityId, + "max_money": history.Money, + "user_id": user.Id, + "avatar": user.Avatar, + "nickname": user.Nickname, + "num": 0, + "status": "已结束", + "model": auction.AuctionModel, + }, + }) + _, err = core.GetXormAuto().InsertOne(record) + t.CheckErr(err) + } + } else { + go ws_send_service.SendAuction(fmt.Sprintf("%d", auction.ActivityId), + "", 0, map[string]interface{}{ + "type": "auction", + "customer_id": 0, + "user_id": 0, + "data": map[string]interface{}{ + "auction_activity_id": auction.Id, + "activity_id": auction.ActivityId, + "max_money": 0, + "user_id": 0, + "avatar": "", + "nickname": "", + "num": 0, + "status": "已结束", + "model": auction.AuctionModel, + }, + }) + } + + t.STRING("操作成功") +} + +// 增加数据 +func (t *AuctionCtl) History() { + auctionId := t.MustGetInt64("auction_activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + auction := new(models.NewAuctionActivity) + exist, err := models.GetById(auction, auctionId) + t.CheckErr(err) + t.Assert(exist, code.MSG_AUCTION_NOT_EXIST, "竞拍不存在") + + orderBy := "money asc" + if auction.AuctionModel == "加价竞拍" { + orderBy = "money desc" + } + + histories, err := models.GetAuctionHistoriesByAuctionId(auctionId, rehearsalId, orderBy) + t.CheckErr(err) + + userIdMap := make(map[int64]struct{}, 0) // 去重操作 + for u := range histories { + if _, ok := userIdMap[histories[u].UserId]; ok { + //去掉重复的 + continue + } else { + userIdMap[histories[u].UserId] = struct{}{} // 增加,下次进行检测 + } + auction.Histories = append(auction.Histories, histories[u]) + } + + t.JSON(map[string]interface{}{ + "auction": auction, + }) +} + +func (t *AuctionCtl) List() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + auctions, err := models.GetAuctionsByActivityId(activityId, "created_at asc") + t.CheckErr(err) + // 更具某个数据进行 + upIds := make([]int64, 0) + for _, item := range auctions { + if item.AuctionModel == "加价竞拍" { + upIds = append(upIds, item.Id) + } + } + upH, err := models.GetAuctionHistoriesByAuctionIds(upIds, rehearsalId, "money desc") + t.CheckErr(err) + + for i := range auctions { + if auctions[i].AuctionModel == "加价竞拍" { + userIdMap := make(map[int64]struct{}, 0) // 去重操作 + for u := range upH { + if _, ok := userIdMap[upH[u].UserId]; ok { + //去掉重复的 + continue + } + + if auctions[i].Id == upH[u].AuctionActivityId && len(auctions[i].Histories) <= 3 { + auctions[i].Histories = append(auctions[i].Histories, upH[u]) + userIdMap[upH[u].UserId] = struct{}{} // 增加,下次进行检测 + } + } + } + } + + t.JSON(map[string]interface{}{ + "total": len(auctions), + "list": auctions, + }) +} + +// 成交记录 +func (t *AuctionCtl) Records() { + rehearsalId := t.MustGetInt64("rehearsal_id") // 彩排 + auctionId := t.MustGetInt64("auction_activity_id") + + records, err := models.GetAuctionRecordsByAuctionId(auctionId, rehearsalId, "created_at desc") + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "records": records, + "total": len(records), + }) +} + +//获取二维码 +func (t *AuctionCtl) Qrcode() { + //将服务器得地址和activity_id,动态生成二维码 + qrcode, err := utils.GenH5Qrcode(define.H5Auction, map[string]interface{}{ + "activity_id": t.MustGetInt64("activity_id"), + "customer_id": t.MustGetUID(), + "auction_id": t.MustGetInt64("auction_activity_id"), + "rehearsal_id": t.MustGetInt64("rehearsal_id"), + }) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "qrcode": qrcode, + }) +} diff --git a/controllers/pc/barrage.go b/controllers/pc/barrage.go new file mode 100644 index 0000000..ba944e4 --- /dev/null +++ b/controllers/pc/barrage.go @@ -0,0 +1,48 @@ +package pc + +import ( + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/code" +) + +//弹幕 +type BarrageCtl struct { + controllers.AuthorCtl +} + +//获取活动的详情 +func (t *BarrageCtl) Details() { + activityId := t.MustGetInt64("activity_id") + server := new(models.DanMuServer) + exist, err := server.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_BARRAGE_SERVER_NOT_EXIST, "弹幕不存在") + + t.JSON(map[string]interface{}{ + "server": server, + }) +} + +func (t *BarrageCtl) SaveSetting() { + activityId := t.MustGetInt64("activity_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + danmuId := t.MustGetInt64("danmu_server_id") + server := new(models.DanMuServer) + server.DanmuFontSize = t.MustGet("font_size") + server.DanmuOpacity = t.MustGetInt("opacity") + server.DanmuPosition = t.MustGet("position") + server.DanmuSpeed = t.MustGetInt("speed") + server.ServerDisplay = t.MustGet("display") + models.Save(map[string]interface{}{ + "is_delete=": 0, + "id=": danmuId, + }, server, "danmu_font_size", "danmu_opacity", "danmu_position", "danmu_speed", "server_display") + t.CheckErr(err) + t.SUCCESS("success") +} diff --git a/controllers/pc/bully_screen.go b/controllers/pc/bully_screen.go new file mode 100644 index 0000000..1bff351 --- /dev/null +++ b/controllers/pc/bully_screen.go @@ -0,0 +1,242 @@ +package pc + +import ( + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/services/pay" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "strings" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type BullyScreenCtl struct { + controllers.AuthorCtl +} + +type BullyScreenBaseResult struct { + models.BullyScreenHistory `xorm:"extends"` + User *models.User `json:"user" xorm:"extends"` +} + +//获取待审核列表 +func (t *BullyScreenCtl) WaitReview() { + activityId := t.MustGetInt64("activity_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + //获取霸屏服务得id + bullyScreenServer := new(models.BullyScreenServer) + exist, err = bullyScreenServer.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_BULLY_SCREEN_SERVER_NOT_EXIST, "霸屏不存在") + + t.CheckErr(pay_service.BatchQueryByActivityId(activityId)) + t.CheckErr(pay_service.BatchQueryRefundByActivityId(activityId)) + + //根据霸屏服务得id获取待审核得霸屏列表 + result := make([]*BullyScreenBaseResult, 0) + err = core.GetXormAuto().Table(new(models.BullyScreenHistory)).Alias("h"). + Join("LEFT", "ox_user as u", "h.user_id=u.id and u.is_delete=0"). + Where("h.bully_screen_server_id=? and h.is_delete=0 and h.status=0 and h.rehearsal_id=?", + bullyScreenServer.Id, activity.RehearsalId).Desc("h.created_at").Find(&result) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +//审核操作 +func (t *BullyScreenCtl) Review() { + idList := t.MustGet("ids") + status := t.MustGetBool("status") + ids := strings.Split(idList, "|") + //rehearsalId := t.MustGetInt64("rehearsal_id") + + //将金额退回给用户 + result := make([]*models.BullyScreenHistory, 0) + err := core.GetXormAuto().Where("is_delete=0").In("id", ids).Find(&result) + t.CheckErr(err) + + for _, v := range result { + if v.Status != 0 { + t.ERROR("该霸屏已处理", code.MSG_USER_DATA_ERROR) + } + if status { // true 失败 、、 false 成功 + _, err := v.UpdateStatus(v.Id, 1) + t.CheckErr(err) + + //if rehearsalId != 0 { // 彩排 + // continue + //} + + //todo: 回退金额给用户 ==> 直接微信退款 + // 1. 提请微信退款 + // 2. 查询退款是否成功 + // 3. 退款成功设置状态 + // 4. 写入金额流水记录 + order := new(models.UserOrder) + exist, err := models.GetById(order, v.UserOrderId) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_ORDER_NOT_EXIST, "用户支付订单不存在") + + _, err = pay_service.Refund("欧轩互动-霸屏拉黑", order.OutTradeNo, order.OpenId, order.GoodType, order.TotalFee, order.TotalFee, order.UserId, order.ActivityId) + t.CheckErr(err) + + } else { + _, err := v.UpdateStatus(v.Id, 2) + t.CheckErr(err) + // todo: 审核成功 + // 1. 金额打入主账号的打赏钱包里面 + // 2. 记录金额流水 + + //if rehearsalId != 0 { + // continue + //} + + uid := t.MustGetUID() + customer := new(models.Customer) + exist, err := models.GetById(customer, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + wallet := new(models.BullyScreenWallet) + _, err = wallet.IncrBalance(customer.Id, v.Amount) + t.CheckErr(err) + + _, err = core.GetXormAuto().InsertOne(&models.BullyScreenWalletHistory{ + CustomerId: customer.Id, + UserId: v.UserId, + Money: v.Amount, + Type: "霸屏", + Status: "交易成功", + Mark: "霸屏金额", + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + }) + t.CheckErr(err) + } + } + t.SUCCESS("审核成功") +} + +//获取黑名单列表 +func (t *BullyScreenCtl) Blacklist() { + activityId := t.MustGetInt64("activity_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + //获取霸屏服务得id + bullyScreenServer := new(models.BullyScreenServer) + exist, err = bullyScreenServer.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_BULLY_SCREEN_SERVER_NOT_EXIST, "霸屏活动不存在") + + //根据霸屏服务得id获取待审核得霸屏列表 + result := make([]*BullyScreenBaseResult, 0) + err = core.GetXormAuto().Table(new(models.BullyScreenHistory)).Alias("h"). + Join("LEFT", new(models.User).Alias("u"), "u.id=h.user_id and u.is_delete=0"). + Where("h.is_delete=0 and h.bully_screen_server_id=? and h.status=1 and h.rehearsal_id=?", + bullyScreenServer.Id, activity.RehearsalId).Desc("review_time").Find(&result) + t.CheckErr(err) + + t.DisplayByData(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +//获取目前霸屏得总金额 +func (t *BullyScreenCtl) Amount() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + //获取霸屏服务得id + bullyScreenServer := new(models.BullyScreenServer) + exist, err := bullyScreenServer.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_BULLY_SCREEN_SERVER_NOT_EXIST, "霸屏不存在") + + totalSecond, err := core.GetXormAuto().Where("bully_screen_server_id=? and status=3 and "+ + " is_delete=false and rehearsal_id=?", bullyScreenServer.Id, rehearsalId). + Sum(new(models.BullyScreenHistory), "second") + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "amount": utils.Float64CusDecimal(totalSecond*bullyScreenServer.Price, 2), + }) +} + +type ModuleService struct { + models.ActivityModuleService `xorm:"extends"` + History models.ModuleServiceHistory `xorm:"extends"` +} + +//获取最新得霸屏记录 +func (t *BullyScreenCtl) Latest() { + activityId := t.MustGetInt64("activity_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + //获取霸屏服务得id + bullyScreenServer := new(models.BullyScreenServer) + exist, err = bullyScreenServer.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_BULLY_SCREEN_SERVER_NOT_EXIST, "霸屏不存在") + + result := new(BullyScreenBaseResult) + exist, err = core.GetXormAuto().Table(new(models.BullyScreenHistory)).Alias("h"). + Join("LEFT", new(models.User).Alias("u"), "u.id=h.user_id and u.is_delete=0"). + Where("h.bully_screen_server_id=? and h.status=2 and h.rehearsal_id=? and h.is_delete=0", + bullyScreenServer.Id, activity.RehearsalId).Desc("review_time").Get(result) + t.CheckErr(err) + if !exist { + t.RAW(result) + } + + //根据主活动得id获取所有得模块列表 + module := new(ModuleService) + exist, err = core.GetXormAuto().Table(new(models.ActivityModuleService)).Alias("s"). + Join("LEFT", new(models.ModuleServiceHistory).Alias("h"), + "s.service_module_history_id=h.id and h.is_delete=0 and h.name=?", define.MODULE_BULLYS). + Where("s.activity_id=? and s.is_delete=0", bullyScreenServer.ActivityId). + Get(module) + t.CheckErr(err) + if !exist { + t.ERROR("该服务模块尚未开通", code.MSG_ERR_Param) + } + + //更改推送状态 + result.BullyScreenHistory.Status = 3 + result.BullyScreenHistory.UpdatedAt = time.Now() + t.CheckErr(models.Save(map[string]interface{}{ + "id =": result.BullyScreenHistory.Id, + }, &result.BullyScreenHistory, "status", "updated_at")) + t.RAW(result) +} + +// 霸屏服务器开关 +func (t *BullyScreenCtl) Details() { + activityId := t.MustGetInt64("activity_id") + server := new(models.BullyScreenServer) + exist, err := server.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_BULLY_SCREEN_SERVER_NOT_EXIST, "霸屏不存在") + t.JSON(map[string]interface{}{ + "server": server, + }) +} diff --git a/controllers/pc/calorie.go b/controllers/pc/calorie.go new file mode 100644 index 0000000..990a11e --- /dev/null +++ b/controllers/pc/calorie.go @@ -0,0 +1,178 @@ +package pc + +import ( + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" +) + +type CalorieCtl struct { + controllers.AuthorCtl +} + +func (t *CalorieCtl) Ready() { + calorieId := t.MustGetInt64("calorie_id") + + calorie := new(models.Calorie) + exist, err := models.GetById(calorie, calorieId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CALORIE_NOT_EXIST, "卡路里活动不存在") + if calorie.Status != define.StatusNotBegin { + t.ERROR(fmt.Sprintf("该活动%s", calorie.Status), code.MSG_MODULE_STATUS_ERROR) + } + + activity := new(models.Activity) + exist, err = models.GetById(activity, calorie.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + _, err = calorie.UpdateToStatusByActivityId(calorie.ActivityId, define.StatusReady, define.StatusNotBegin) + t.CheckErr(err) + + calorie.StartTime = 0 + _, err = calorie.UpdateStatusById(calorieId, define.StatusReady) + t.CheckErr(err) + t.SUCCESS("操作成功") +} + +// 开始, 加一个开始时间 +func (t *CalorieCtl) Start() { + calorieId := t.MustGetInt64("calorie_id") + + calorie := new(models.Calorie) + exist, err := models.GetById(calorie, calorieId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CALORIE_NOT_EXIST, "卡路里活动不存在") + if calorie.Status != define.StatusReady { + t.ERROR(fmt.Sprintf("该活动%s", calorie.Status), code.MSG_MODULE_STATUS_ERROR) + } + activity := new(models.Activity) + exist, err = models.GetById(activity, calorie.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + calorie.StartTime = time.Now().Unix() + _, err = calorie.UpdateStatusById(calorieId, define.StatusRunning) + t.CheckErr(err) + t.SUCCESS("操作成功") +} + +// 彩排活动需要恢复 +func (t *CalorieCtl) Stop() { + calorieId := t.MustGetInt64("calorie_id") + + calorie := new(models.Calorie) + exist, err := models.GetById(calorie, calorieId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CALORIE_NOT_EXIST, "卡路里活动不存在") + if calorie.Status != define.StatusRunning { + t.ERROR(fmt.Sprintf("该活动%s", calorie.Status), code.MSG_MODULE_STATUS_ERROR) + } + + activity := new(models.Activity) + exist, err = models.GetById(activity, calorie.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + _, err = calorie.UpdateStatusById(calorieId, define.StatusEnding) + t.CheckErr(err) + t.SUCCESS("操作成功") +} + +// 列出轮次, 包括倒计时 +func (t *CalorieCtl) List() { + activityId := t.MustGetInt64("activity_id") + calories := make([]*models.Calorie, 0) + err := core.GetXormAuto().Where("is_delete=0 and activity_id=?", activityId).Find(&calories) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "list": calories, + "count": len(calories), + }) +} + +// 二维码 +func (t *CalorieCtl) Qrcode() { + activityId := t.MustGetInt64("activity_id") + uid := t.MustGetUID() + calorieId := t.MustGetInt64("calorie_id") + + qrcode, err := utils.GenH5Qrcode(define.H5Calorie, map[string]interface{}{ + "activity_id": activityId, + "customer_id": uid, + "calorie_id": calorieId, + }) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "qrcode": qrcode, + }) +} + +type CalorieCountResult struct { + Id int64 `json:"id"` + ActivityId int64 `json:"activity_id"` + CalorieId int64 `json:"calorie_id"` + UserId int64 `json:"user_id"` + Avatar string `json:"avatar"` + Nickname string `json:"nickname"` + Score int64 `json:"score"` +} + +// 统计一些数据, 包括参与人数, 包括当前排名 +func (t *CalorieCtl) Count() { + activityId := t.MustGetInt64("activity_id") + calorieId := t.MustGetInt64("calorie_id") + limit := t.DefaultInt("limit", 10) + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + calorie := new(models.Calorie) + exist, err = models.GetById(calorie, calorieId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "卡路里不存在") + + // 统计人数 + count, err := core.GetXormAuto().Where("is_delete=0 and calorie_id=? and rehearsal_id=?", + calorieId, activity.RehearsalId).Count(new(models.CalorieUser)) + t.CheckErr(err) + + // 统计排名 + result := make([]*CalorieCountResult, 0) + err = core.GetXormAuto().Table(new(models.CalorieUser)).Alias("c"). + Select("c.id, c.activity_id, c.calorie_id, c.user_id, u.avatar, u.nickname, c.score, c.join_time"). + Join("LEFT", new(models.User).Alias("u"), "c.user_id=u.id and u.is_delete=0"). + Where("c.is_delete=0 and c.calorie_id=? and c.rehearsal_id=?", calorieId, activity.RehearsalId). + Limit(limit).Desc("c.score").Asc("c.join_time").Find(&result) + t.CheckErr(err) + //duration := calorie.GameDuration - (time.Now().Unix() - calorie.StartTime) + 6 // 增加6s 倒计时 + //if calorie.StartTime == 0 { + // duration = calorie.GameDuration + //} + + // 3s 倒计时 + //var countDown float64 = 0 + //if duration-calorie.GameDuration > 0 { + // countDown = math.Ceil(float64(duration-calorie.GameDuration) / 2.0) + //} + + //if calorie.Status == define.StatusEnding || duration <= 0 { + //duration = 0 + //} + + t.JSON(map[string]interface{}{ + "list": result, // 排名统计 + "count": count, // 人数统计 + //"time": duration - 2*int64(countDown), // 时长 + //"count_down": countDown, //倒计时 + //"status": calorie.Status, // 状态 + }) +} diff --git a/controllers/pc/login.go b/controllers/pc/login.go new file mode 100644 index 0000000..bc9eab8 --- /dev/null +++ b/controllers/pc/login.go @@ -0,0 +1,130 @@ +/* + * @Description: In User Settings Edit + * @Author: your name + * @Date: 2019-08-22 09:26:48 + * @LastEditTime: 2019-08-23 18:04:40 + * @LastEditors: Please set LastEditors + */ +package pc + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/libs/jwt" + "hudongzhuanjia/libs/qq" + "hudongzhuanjia/libs/wx" + "hudongzhuanjia/models" + "hudongzhuanjia/services/activity" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" +) + +//用户 +type UserCtl struct { + controllers.BaseCtl +} + +//登陆 +// 子账号需要接收父级账号的控制,同步数据, +func (t *UserCtl) Login() { + username := t.MustGet("username") + password := t.MustGet("password") + customer := new(models.Customer) + + err := customer.Author(username, password) + t.CheckErr(err) + // 获取用户拥有的activity + activities, err := activity_service.GetActivitiesByCustomerId(customer.Id) + t.CheckErr(err) + + // 主账号无法确定 + token, err := jwt.GenJwtToken("customer", customer.Id, customer.Id, customer.Pid, customer.AreaId, customer.ActivityId, customer.Username) + t.CheckErr(err) + t.SetSession(define.TOKEN, token) + customer.Token = token + customer.Activities = activities + pid := customer.Pid + if pid == 0 { + pid = customer.Id + } + customer.Tag = "activity" + t.RAW(customer) +} + +//检查是否已经登陆 +func (t *UserCtl) Checkin() { + _, exist := t.Get(define.TOKEN) + if exist { + t.SUCCESS("已登录") + } + t.ERROR("未登录", code.MSG_ERR) +} + +// debug +func (t *UserCtl) DebugLogin() { + customerId := t.DefaultInt64("customer_id", 19) + customer := new(models.Customer) + exist, err := models.GetById(customer, customerId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + token, err := jwt.GenJwtToken("customer", customer.Id, customer.Id, customer.Pid, customer.AreaId, customer.ActivityId, customer.Username) + t.CheckErr(err) + t.SetSession(define.TOKEN, token) + t.JSON(map[string]interface{}{ + "customer": customer, + "token": token, + }) +} + +//退出 +func (t *UserCtl) Logout() { + if _, ok := t.Request.SESSION[define.TOKEN]; !ok { + t.DisplayByError("未登录", code.MSG_ERR_Authority) + } + t.DeleteSession(define.TOKEN) + t.DisplayByData("退出成功") +} + +// 微信登陆 callback +func (t *UserCtl) WXLogin() { + //state := t.MustGet("state") + wxcode := t.MustGet("code") + token, err := wx.GetToken(wxcode) + t.CheckErr(err) + + customer := new(models.Customer) + exist, err := customer.GetByOpenid(token.Openid) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + t.SetSession(define.TOKEN, fmt.Sprintf("%d", customer.Id)) + activities, err := activity_service.GetActivitiesByCustomerId(customer.Id) + t.CheckErr(err) + customer.Activities = activities + t.RAW(customer) +} + +// 手机验证码登陆 +func (t *UserCtl) QQLogin() { + //state := t.MustGet("state") + qqcode := t.MustGet("code") + + token, err := qq.GetToken(qqcode) + t.CheckErr(err) + open, err := qq.GetPcOpenid(token.AccessToken) + t.CheckErr(err) + + customer := new(models.Customer) + customer.GetByQQOpenid(open.Openid) + t.CheckErr(err) + t.SetSession(define.TOKEN, fmt.Sprintf("%d", customer.Id)) + activities, err := activity_service.GetActivitiesByCustomerId(customer.Id) + t.CheckErr(err) + customer.Activities = activities + t.RAW(customer) +} + +func (t *UserCtl) QQCodeUrl() { + t.DisplayByData(qq.GetCodeUrl()) +} diff --git a/controllers/pc/lottery_draw.go b/controllers/pc/lottery_draw.go new file mode 100644 index 0000000..7027d93 --- /dev/null +++ b/controllers/pc/lottery_draw.go @@ -0,0 +1,390 @@ +package pc + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + activity_service "hudongzhuanjia/services/activity" + lottery_service "hudongzhuanjia/services/lottery" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +//抽奖 +type LotteryDrawCtl struct { + controllers.AuthorCtl +} + +//开始抽奖 +func (t *LotteryDrawCtl) Start() { + ladderId := t.MustGetInt64("lottery_draw_ladder_id") + + ladder := new(models.LotteryDrawRuleLadder) + exist, err := models.GetById(ladder, ladderId) + t.CheckErr(err) + t.Assert(exist, code.MSG_LOTTERY_RULE_NOT_EXIST, "抽奖规则不存在") + + if ladder.Status != define.StatusNotBegin { + t.ERROR(fmt.Sprintf("该活动%s", ladder.Status), code.MSG_ERR) + } + ladder.Status = define.StatusRunning + ladder.UpdatedAt = time.Now() + t.CheckErr(models.Save(map[string]interface{}{ + "id=": ladderId, + }, ladder, "status", "updated_at")) + + t.SUCCESS("操作成功") +} + +//停止抽奖 +func (t *LotteryDrawCtl) Stop() { + ladderId := t.MustGetInt64("lottery_draw_ladder_id") + + ladder := new(models.LotteryDrawRuleLadder) + exist, err := models.GetById(ladder, ladderId) + t.CheckErr(err) + t.Assert(exist, code.MSG_LOTTERY_RULE_NOT_EXIST, "抽奖规则不存在") + + if ladder.Status != define.StatusRunning { + t.ERROR(fmt.Sprintf("该活动%s", ladder.Status), code.MSG_ERR) + } + + ladder.Status = define.StatusEnding + ladder.UpdatedAt = time.Now() + t.CheckErr(models.Save(map[string]interface{}{ + "id=": ladderId, + }, ladder, "status", "updated_at")) + + t.SUCCESS("操作成功") +} + +type LotteryListResult struct { + LotteryDrawActivityId int64 `json:"lottery_draw_activity_id"` + LotteryDrawRuleId int64 `json:"lottery_draw_rule_id"` + LotteryDrawActivityName string `json:"lottery_draw_name"` + LotteryDrawLadders []*LotteryLadderResult `json:"lottery_draw_ladders"` + PrizeNumber int64 `json:"prize_number"` +} + +type LotteryLadderResult struct { + LotteryDrawRuleId int64 `json:"-"` + LotteryDrawLadderId int64 `json:"lottery_draw_ladder_id"` + Status string `json:"status"` + PrizeName string `json:"prize_name"` + PrizeImg string `json:"prize_img"` + PrizeNumber int64 `json:"prize_number"` +} + +//获取所有抽奖活动列表 +func (t *LotteryDrawCtl) List() { + activityId := t.MustGetInt64("activity_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + result := make([]*LotteryListResult, 0) + err = core.GetXormAuto().Table(new(models.LotteryDrawActivity)).Alias("a"). + Select("a.id as lottery_draw_activity_id, r.id as lottery_draw_rule_id, a.lottery_draw_activity_name"). + Join("LEFT", models.AliasTableName(new(models.LotteryDrawRule), "r"), + "a.id=r.lottery_draw_activity_id and r.is_delete=0"). + Where("a.is_delete=0 and a.activity_id=?", activityId).Find(&result) + t.CheckErr(err) + + // 多地区的一个坑:分配给主会场的area_id不是主账号的area_id + area := new(models.AreaStore) + if t.MustGetCustomerPid() == 0 { + exist, err = area.GetMainAreaById(activityId) + } else { + exist, err = area.GetAreaStoreById(t.MustGetAreaId()) + } + t.CheckErr(err) + t.Assert(exist, code.MSG_AREASTORE_NOT_EXIST, "地区不存在") + + ruleIds := make([]int64, 0) + for _, v := range result { + ruleIds = append(ruleIds, v.LotteryDrawRuleId) + } + ladders := make([]*LotteryLadderResult, 0) + err = core.GetXormAuto().Table(new(models.LotteryDrawRuleLadder)). + Select("id as lottery_draw_ladder_id, prize_name, prize_img, prize_number, lottery_draw_rule_id, status"). + Where("is_delete=0").In("lottery_draw_rule_id", ruleIds).Find(&ladders) + t.CheckErr(err) + + ladderIds := make([]int64, 0) + for _, ladder := range ladders { + ladderIds = append(ladderIds, ladder.LotteryDrawLadderId) + } + + records := make([]map[string]int64, 0) + err = core.GetXormAuto().Table(new(models.LotteryDrawRecord)).Alias("r"). + Select("r.lottery_draw_rule_ladder_id as ladder_id, count(r.id) as num"). + Where("is_delete=0 and rehearsal_id=?", activity.RehearsalId). + In("r.lottery_draw_rule_ladder_id", ladderIds).GroupBy("ladder_id").Find(&records) + t.CheckErr(err) + for i := range ladders { + for j := range records { + if ladders[i].LotteryDrawLadderId == records[j]["ladder_id"] { + ladders[i].PrizeNumber = ladders[i].PrizeNumber - records[j]["num"] + } + } + } + + for i := range result { + for j := range ladders { + if result[i].LotteryDrawRuleId == ladders[j].LotteryDrawRuleId { + result[i].PrizeNumber += ladders[j].PrizeNumber + result[i].LotteryDrawLadders = append(result[i].LotteryDrawLadders, ladders[j]) + } + } + } + + core.GetXormAuto().Table(new(models.LotteryDrawRecord)).Select("count()") + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +//抽奖奖品 +func (t *LotteryDrawCtl) Prize() { + ruleId := t.MustGetInt64("lottery_draw_rule_id") + + list := make([]*models.LotteryDrawRuleLadder, 0) + err := core.GetXormAuto().Where("is_delete=0 and lottery_draw_rule_id=?", ruleId).Find(&list) + t.CheckErr(err) + + for index := range list { + list[index].Des = "在该活动的所有用户中随机抽奖品数量的用户" + } + t.JSON(map[string]interface{}{ + "total": len(list), + "lise": list, + }) +} + +type LotteryUsersResult struct { + UserId int64 `json:"user_id"` + Username string `json:"username"` + Avatar string `json:"avatar"` +} + +// 抽奖用户 +func (t *LotteryDrawCtl) Users() { + activityId := t.MustGetInt64("activity_id") + ruleId := t.MustGetInt64("lottery_draw_rule_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + area := new(models.AreaStore) + if t.MustGetCustomerPid() == 0 { + exist, err = area.GetMainAreaById(activityId) + } else { + exist, err = area.GetAreaStoreById(t.MustGetAreaId()) + } + t.CheckErr(err) + t.Assert(exist, code.MSG_AREASTORE_NOT_EXIST, "地区不存在") + + result := make([]*LotteryUsersResult, 0) + session := core.GetXormAuto().Table(new(models.SignHistory)).Alias("h"). + Select("h.user_id, u.nickname as username, u.avatar").Distinct("h.user_id"). + Join("LEFT", new(models.User).Alias("u"), "h.user_id=u.id and u.is_delete = 0"). + Where("h.is_delete=0 and h.area_id=? and h.activity_id=? and h.rehearsal_id=?", + area.Id, activityId, activity.RehearsalId) + + moduleService, exist, err := activity_service.GetModuleService(define.MODULE_LOTTERY, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "活动模块不存在") + if moduleService.BesideRepeat == define.MODULE_BESIDE_REPEAT { + // 去重标志 + recordIds := make([]int64, 0) + err = core.GetXormAuto().Table(new(models.LotteryDrawRecord)).Select("user_id"). + Where("lottery_draw_rule_id=? and rehearsal_id=? and area_id=? and is_delete=0", + ruleId, activity.RehearsalId, area.Id).Find(&recordIds) + t.CheckErr(err) + session = session.NotIn("h.user_id", recordIds) + } + err = session.Find(&result) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +//抽奖动作 +func (t *LotteryDrawCtl) Lottery() { + activityId := t.MustGetInt64("activity_id") + ruleId := t.MustGetInt64("lottery_draw_rule_id") + ladderId := t.MustGetInt64("lottery_draw_ladder_id") + number := t.MustGetInt("number") // 奖品数量 + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + // 多地区设置 + area := new(models.AreaStore) + if t.MustGetCustomerPid() == 0 { + exist, err = area.GetMainAreaById(activity.Id) + } else { + exist, err = area.GetAreaStoreById(t.MustGetAreaId()) + } + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "地区不存在") + + rule := new(models.LotteryDrawRule) + exist, err = models.GetById(rule, ruleId) + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "抽奖规则不存在") + //t.CheckRunning(rule.LotteryDrawStatus) + + // 查询奖品 + ladder := new(models.LotteryDrawRuleLadder) + exist, err = models.GetById(ladder, ladderId) + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "抽奖等级不存在") + t.CheckRunning(ladder.Status) + + count, err := core.GetXormAuto().Where("lottery_draw_rule_id=? and lottery_draw_rule_ladder_id=? "+ + "and rehearsal_id=? and area_id=? and is_delete=0", ruleId, ladderId, activity.RehearsalId, area.Id). + Count(new(models.LotteryDrawRecord)) + t.CheckErr(err) + + prizeNum := ladder.PrizeNumber - int(count) + if prizeNum <= 0 || prizeNum < number { // 需要抽奖的数量比数据库存在数量多 + t.ERROR("奖品数量不足", code.MSG_LOTTERY_PRIZE_NOT_ENOUGH) + } + + //根据主活动id和地区id获取所有的用户 + signUpIds := make([]int64, 0) + err = core.GetXormAuto().Table(new(models.SignUp)).Select("id").Where("activity_id=? and is_delete=0", + activityId).Find(&signUpIds) + t.CheckErr(err) + if len(signUpIds) <= 0 { + t.ERROR("暂无签到用户", code.MSG_DATA_NOT_EXIST) + } + + moduleService, exist, err := activity_service.GetModuleService(define.MODULE_LOTTERY, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "活动模块不存在") + // 取设置 + lotteryUsers := make([]*lottery_service.LotteryUser, 0) + if moduleService.BesideRepeat == define.MODULE_BESIDE_REPEAT { + // 去除同规则中将用户 + recordIds := make([]int64, 0) + err = core.GetXormAuto().Table(new(models.LotteryDrawRecord)).Select("user_id"). + Where("lottery_draw_rule_id=? and rehearsal_id=? and area_id=? and is_delete=0", + ruleId, activity.RehearsalId, area.Id).Find(&recordIds) + t.CheckErr(err) + + //查询已经中奖的用户,剔除已经中奖的用户 + err = core.GetXormAuto().Table(new(models.SignHistory)).Select("user_id"). + Where("is_delete=0 and rehearsal_id=? and area_id=?", + activity.RehearsalId, area.Id).In("sign_rule_id", signUpIds). + NotIn("user_id", recordIds).Find(&lotteryUsers) + t.CheckErr(err) + } else { + err = core.GetXormAuto().Table(new(models.SignHistory)).Select("user_id"). + Where("is_delete=0 and rehearsal_id=? and area_id=?", + activity.RehearsalId, area.Id).In("sign_rule_id", signUpIds).Find(&lotteryUsers) + t.CheckErr(err) + } + if len(lotteryUsers) < number { + t.ERROR("抽奖人数不足", code.MSG_LOTTERY_PEOPLE_NOT_ENOUGH) + } + lottery_service.RandLotteryUser(lotteryUsers) // 打乱需要中奖人员 + winners := lotteryUsers[:number] + userIds := make([]int64, 0) + for _, winner := range winners { + userIds = append(userIds, winner.UserId) + } + users := make([]*models.User, 0) + err = core.GetXormAuto().Where("is_delete=0").In("id", userIds).Find(&users) + t.CheckErr(err) + for i := range winners { + // 补全信息 + for j := range users { + if winners[i].UserId == users[j].Id { + winners[i].Username = users[j].Nickname + winners[i].Avatar = users[j].Avatar + winners[i].UserPhone = users[j].Phone + winners[i].PrizeName = ladder.PrizeName + winners[i].LadderId = ladder.Id + winners[i].PrizeImg = ladder.PrizeImg + break + } + } + // 普通抽奖 + userPrize := new(models.UserPrize) + userPrize.ActivityId = activityId + userPrize.RehearsalId = activity.RehearsalId + userPrize.ActivityName = activity.Name + userPrize.UserId = winners[i].UserId + userPrize.PrizeImg = ladder.PrizeImg + userPrize.PrizeName = ladder.PrizeName + userPrize.PrizeType = 1 + userPrize.IsDelete = false + userPrize.CreatedAt = time.Now() + userPrize.UpdatedAt = time.Now() + _, err = core.GetXormAuto().Insert(userPrize) + t.CheckErr(err) + + record := new(models.LotteryDrawRecord) + record.UserPrizeId = userPrize.Id + record.ActivityId = activityId + record.RehearsalId = activity.RehearsalId + record.LotteryDrawActivityId = rule.LotteryDrawActivityId + record.LotteryDrawRuleId = rule.Id + record.UserId = winners[i].UserId + record.UserName = winners[i].Username + record.UserPhone = winners[i].UserPhone + record.LotteryDrawRuleLadderId = ladder.Id + record.PrizeName = ladder.PrizeName + record.AreaId = area.Id + record.AreaName = area.Name + record.IsDelete = false + record.CreatedAt = time.Now() + record.UpdatedAt = time.Now() + _, err = core.GetXormAuto().InsertOne(record) + t.CheckErr(err) + } + + t.RAW(winners) +} + +type WinnersResult struct { + UserId int64 `json:"user_id"` + UserName string `json:"user_name"` + UserPhone string `json:"user_phone"` + Avatar string `json:"avatar"` + PrizeName string `json:"prize_name"` +} + +//获取中奖名单 +func (t *LotteryDrawCtl) ListOfWinners() { + ruleId := t.MustGetInt64("lottery_draw_rule_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + result := make([]*WinnersResult, 0) + err := core.GetXormAuto().Table("ox_lottery_draw_record").Alias("record"). + Join("LEFT", new(models.User).Alias("user"), "user.id=record.user_id and user.is_delete=0"). + Where("record.is_delete=0 and record.lottery_draw_rule_id=? and record.rehearsal_id=?", ruleId, rehearsalId). + Find(&result) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} diff --git a/controllers/pc/order_draw.go b/controllers/pc/order_draw.go new file mode 100644 index 0000000..721d602 --- /dev/null +++ b/controllers/pc/order_draw.go @@ -0,0 +1,451 @@ +package pc + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + activity_service "hudongzhuanjia/services/activity" + invitation_service "hudongzhuanjia/services/invitation" + lottery_service "hudongzhuanjia/services/lottery" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +// 订单 +type OrderDrawCtl struct { + controllers.AuthorCtl +} + +// 开启订单活动 +func (t *OrderDrawCtl) Switch() { + activityId := t.MustGetInt64("activity_id") + status := t.MustGetInt("status") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + option := new(models.CustomerOrderOption) + exist, err = option.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "订单活动不存在") + + if option.Status == status { + t.SUCCESS("操作成功") + return + } + + _, err = option.Switch(activityId, status) + t.CheckErr(err) + t.CheckErr(err) + t.SUCCESS("操作成功") +} + +// ===================== 订单抽奖 + +// 开始抽奖 +func (t *OrderDrawCtl) Start() { + ladderId := t.MustGetInt64("order_draw_ladder_id") + + ladder := new(models.OrderDrawRuleLadder) + exist, err := models.GetById(ladder, ladderId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ORDER_RULE_NOT_EXIST, "订单抽奖规则不存在") + + if ladder.Status != define.StatusNotBegin { + t.ERROR(fmt.Sprintf("该活动%s", ladder.Status), code.MSG_ERR) + } + ladder.Status = define.StatusRunning + ladder.UpdatedAt = time.Now() + err = models.Save(map[string]interface{}{ + "id=": ladder.Id, + "is_delete=": 0, + }, ladder, "status", "updated_at") + t.CheckErr(err) + t.SUCCESS("操作成功") +} + +// 开始抽奖 +func (t *OrderDrawCtl) Stop() { + ladderId := t.MustGetInt64("order_draw_ladder_id") + + ladder := new(models.OrderDrawRuleLadder) + exist, err := models.GetById(ladder, ladderId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ORDER_RULE_NOT_EXIST, "订单抽奖规则不存在") + + if ladder.Status != define.StatusRunning { + t.ERROR(fmt.Sprintf("该活动%s", ladder.Status), code.MSG_ERR) + } + + ladder.Status = define.StatusEnding + ladder.UpdatedAt = time.Now() + err = models.Save(map[string]interface{}{ + "id=": ladder.Id, + "is_delete=": 0, + }, ladder, "status", "updated_at") + t.CheckErr(err) + t.SUCCESS("操作成功") +} + +type OrderListResult struct { + OrderDrawActivityId int64 `json:"order_draw_activity_id"` + OrderDrawRuleId int64 `json:"order_draw_rule_id"` + OrderDrawActivityName string `json:"order_draw_activity_name"` + OrderDrawLadders []*OrderLadderResult `json:"order_draw_ladders"` + PrizeNumber int64 `json:"prize_number"` +} +type OrderLadderResult struct { + OrderDrawRuleId int64 `json:"order_draw_rule_id"` + OrderDrawLadderId int64 `json:"order_draw_ladder_id"` + PrizeName string `json:"prize_name"` + Status string `json:"status"` + PrizeImg string `json:"prize_img"` + PrizeNumber int64 `json:"prize_number"` +} + +//获取所有订单奖品 +func (t *OrderDrawCtl) List() { + activityId := t.MustGetInt64("activity_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + // 订单的开启或关闭 + order := new(models.CustomerOrderOption) + exist, err = order.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "订单活动不存在") + + result := make([]*OrderListResult, 0) + core.GetXormAuto().Table(new(models.OrderDrawActivity)).Alias("a"). + Select("a.id as order_draw_activity_id, r.id as order_draw_rule_id, a.order_draw_activity_name"). + Join("LEFT", new(models.OrderDrawRule).Alias("r"), + "a.id=r.order_draw_activity_id and r.is_delete=0"). + Where("a.is_delete=0 and a.activity_id=?", activityId).Find(&result) + + // 多地区的一个坑:分配给主会场的area_id不是主账号的area_id + area := new(models.AreaStore) + if t.MustGetCustomerPid() == 0 { + exist, err = area.GetMainAreaById(activityId) + } else { + exist, err = area.GetAreaStoreById(t.MustGetAreaId()) + } + t.CheckErr(err) + t.Assert(exist, code.MSG_AREASTORE_NOT_EXIST, "地区不存在") + + ruleIds := make([]int64, 0) + for _, v := range result { + ruleIds = append(ruleIds, v.OrderDrawRuleId) + } + + ladders := make([]*OrderLadderResult, 0) + err = core.GetXormAuto().Table(new(models.OrderDrawRuleLadder)).Alias("l"). + Select("id as order_draw_ladder_id, status, prize_name, prize_img, prize_number, order_draw_rule_id"). + Where("is_delete=0").In("order_draw_rule_id", ruleIds).Find(&ladders) + t.CheckErr(err) + + ladderIds := make([]int64, 0) + for _, ladder := range ladders { + ladderIds = append(ladderIds, ladder.OrderDrawLadderId) + } + + records := make([]map[string]int64, 0) + err = core.GetXormAuto().Table(new(models.OrderDrawRecord)).Alias("r"). + Select("r.order_draw_rule_ladder_id as ladder_id, count(id) as num"). + Where("is_delete=0 and rehearsal_id=?", activity.RehearsalId). + In("r.order_draw_rule_ladder_id", ladderIds).GroupBy("ladder_id").Find(&records) + t.CheckErr(err) + + for i := range ladders { + for j := range records { + if ladders[i].OrderDrawLadderId == records[j]["ladder_id"] { + ladders[i].PrizeNumber = ladders[i].PrizeNumber - records[j]["num"] + } + } + } + + for i := range result { + for j := range ladders { + if result[i].OrderDrawRuleId == ladders[j].OrderDrawRuleId { + result[i].PrizeNumber += ladders[j].PrizeNumber + result[i].OrderDrawLadders = append(result[i].OrderDrawLadders, ladders[j]) + } + } + } + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + "status": order.Status, + }) +} + +//抽奖奖品 +func (t *OrderDrawCtl) Prize() { + ruleId := t.MustGetInt64("order_draw_rule_id") + + list := make([]*models.OrderDrawRuleLadder, 0) + err := core.GetXormAuto().Where("is_delete=0 and order_draw_rule_id=?", ruleId).Find(&list) + t.CheckErr(err) + + for index := range list { + list[index].Des = "在该活动的所有订单用户中随机抽奖品数量的用户" + } + t.JSON(map[string]interface{}{ + "total": len(list), + "lise": list, + }) +} + +type OrderUsersResult struct { + UserId int64 `json:"user_id"` + Username string `json:"username"` + Avatar string `json:"avatar"` +} + +//统计人数和订单数量 +func (t *OrderDrawCtl) Users() { + activityId := t.MustGetInt64("activity_id") + ruleId := t.MustGetInt64("order_draw_rule_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + + result := make([]*OrderUsersResult, 0) + session := core.GetXormAuto().Table(new(models.CustomerOrder)).Alias("o"). + Select("o.buyer_id as user_id, u.nickname as username, u.avatar").Distinct("o.buyer_id"). + Join("LEFT", new(models.User).Alias("u"), "o.buyer_id=u.id and u.is_delete=0"). + Where("o.activity_id=? and o.is_delete=0 and o.rehearsal_id=?", + activityId, activity.RehearsalId) + + moduleService, exist, err := activity_service.GetModuleService(define.MODULE_ORDERLY, activity.Id) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "模块服务不存在") + if moduleService.BesideRepeat == define.MODULE_BESIDE_REPEAT { + recordIds := make([]int64, 0) + err = core.GetXormAuto().Table(new(models.OrderDrawRecord)).Select("user_id"). + Where("order_draw_rule_id=? and rehearsal_id=? and is_delete=0", + ruleId, activity.RehearsalId).Find(&recordIds) + t.CheckErr(err) + session = session.NotIn("o.buyer_id", recordIds) + } + err = session.Find(&result) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +// 订单抽奖动作 +func (t *OrderDrawCtl) Draw() { + activityId := t.MustGetInt64("activity_id") + ruleId := t.MustGetInt64("order_draw_rule_id") + ladderId := t.MustGetInt64("order_draw_rule_ladder_id") + number := t.MustGetInt("number") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + area := new(models.AreaStore) + if t.MustGetCustomerPid() == 0 { + exist, err = area.GetMainAreaById(activity.Id) + } else { + exist, err = area.GetAreaStoreById(t.MustGetAreaId()) + } + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "地区不存在") + + rule := new(models.OrderDrawRule) + exist, err = models.GetById(rule, ruleId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ORDER_RULE_NOT_EXIST, "订单抽奖规则不存在") + //t.CheckRunning(rule.OrderDrawStatus) + + // 查询奖品 + ladder := new(models.OrderDrawRuleLadder) + exist, err = models.GetById(ladder, ladderId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ORDER_LADDER_NOT_EXIST, "订单抽奖等级不存在") + t.CheckRunning(ladder.Status) + + count, err := core.GetXormAuto().Where("order_draw_rule_id=? and order_draw_rule_ladder_id=? "+ + "and rehearsal_id=? and is_delete=0", ruleId, ladderId, activity.RehearsalId).Count(new(models.OrderDrawRecord)) + t.CheckErr(err) + prizeNum := ladder.PrizeNumber - int(count) + if prizeNum <= 0 || prizeNum < number { + t.ERROR("奖品数量不足", code.MSG_LOTTERY_PRIZE_NOT_ENOUGH) + } + + moduleService, exist, err := activity_service.GetModuleService(define.MODULE_ORDERLY, activity.Id) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "模块服务不存在") + + orderUsers := make([]*lottery_service.LotteryUser, 0) + if moduleService.BesideRepeat == define.MODULE_BESIDE_REPEAT { + //查询已经中奖的用户,剔除已经中奖的用户 + recordIds := make([]int64, 0) + err = core.GetXormAuto().Table(new(models.OrderDrawRecord)).Select("user_id"). + Where("order_draw_rule_id=? and rehearsal_id=? and is_delete=0", + ruleId, activity.RehearsalId).Find(&recordIds) + + err = core.GetXormAuto().Table(new(models.CustomerOrder)). + Select("buyer_id as user_id").Distinct("buyer_id"). + Where("activity_id=? and rehearsal_id=? and is_delete=0", + activity.Id, activity.RehearsalId).NotIn("buyer_id", recordIds). + Find(&orderUsers) + t.CheckErr(err) + if len(orderUsers) < 0 { + t.ERROR("剔除已经中奖的用户后,已经没有用户可以抽了", code.MSG_ERR) + } + } else { + // 不去除 + err = core.GetXormAuto().Table(new(models.CustomerOrder)).Select("buyer_id as user_id").Distinct("buyer_id"). + Where("activity_id=? and rehearsal_id=? and is_delete=0", + activity.Id, activity.RehearsalId).Find(&orderUsers) + t.CheckErr(err) + } + if len(orderUsers) < number { + t.ERROR("订单抽奖人数不足", code.MSG_LOTTERY_PEOPLE_NOT_ENOUGH) + } + + lottery_service.RandLotteryUser(orderUsers) + winners := orderUsers[:number] + userIds := make([]int64, 0) + for _, winner := range winners { + userIds = append(userIds, winner.UserId) + } + + users := make([]*models.User, 0) + err = core.GetXormAuto().Where("is_delete=0").In("id", userIds).Find(&users) + t.CheckErr(err) + for i := range winners { + for j := range users { + if winners[i].UserId == users[j].Id { + winners[i].Username = users[j].Nickname + winners[i].Avatar = users[j].Avatar + winners[i].UserPhone = users[j].Phone + winners[i].LadderId = ladder.Id + winners[i].PrizeImg = ladder.PrizeImg + winners[i].PrizeName = ladder.PrizeName + break + } + } + // 订单抽奖 ==> 存入我的奖品 + userPrize := new(models.UserPrize) + userPrize.ActivityId = activityId + userPrize.RehearsalId = activity.RehearsalId + userPrize.ActivityName = activity.Name + userPrize.UserId = winners[i].UserId + userPrize.PrizeImg = ladder.PrizeImg + userPrize.PrizeName = ladder.PrizeName + userPrize.PrizeType = 2 + userPrize.IsDelete = false + userPrize.CreatedAt = time.Now() + userPrize.UpdatedAt = time.Now() + _, err = core.GetXormAuto().Insert(userPrize) + t.CheckErr(err) + + record := new(models.OrderDrawRecord) + record.UserPrizeId = userPrize.Id + record.ActivityId = activityId + record.RehearsalId = activity.RehearsalId + record.OrderDrawActivityId = rule.OrderDrawActivityId + record.OrderDrawRuleId = rule.Id + record.UserId = winners[i].UserId + record.OrderDrawRuleLadderId = ladder.Id + record.PrizeName = ladder.PrizeName + record.AreaId = area.Id + record.AreaName = area.Name + record.IsDelete = false + record.CreatedAt = time.Now() + record.UpdatedAt = time.Now() + _, err = core.GetXormAuto().InsertOne(record) + t.CheckErr(err) + } + t.RAW(winners) +} + +type WinnerResult struct { + UserId int64 `json:"user_id"` + Username string `json:"user_name"` + UserPhone string `json:"user_phone"` + Avatar string `json:"avatar"` + PrizeName string `json:"prize_name"` +} + +func (t *OrderDrawCtl) ListOfWinners() { + orderDrawRuleId := t.MustGetInt64("order_draw_rule_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + result := make([]*WinnerResult, 0) + err := core.GetXormAuto().Table(new(models.OrderDrawRecord)).Alias("r"). + Select("r.user_id, u.nickname as username, u.phone as user_phone, u.avatar, r.prize_name"). + Join("LEFT", new(models.User).Alias("u"), "u.id=r.user_id and u.is_delete=0"). + Where("r.is_delete=0 and r.order_draw_rule_id=? and r.rehearsal_id=?", + orderDrawRuleId, rehearsalId).Find(&result) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +// 获取所有订单 + +type OrdersResult struct { + UserId int64 `json:"user_id"` + AreaName string `json:"area_name"` + GoodsName string `json:"goods_name"` + Nickname string `json:"nickname"` + ExtraData string `json:"-"` + Extra []map[string]interface{} `json:"extra"` +} + +func (t *OrderDrawCtl) Orders() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + orders := make([]*OrdersResult, 0) + err := core.GetXormAuto().Table(new(models.CustomerOrder)).Alias("o"). + Select("o.area_name, o.goods_name, o.buyer_id as user_id, u.nickname, l.extra_data as extra_data, o.created_at"). + Distinct("o.id").Join("LEFT", new(models.InvitationLetter).Alias("l"), + "o.buyer_id=l.user_id and o.activity_id=l.activity_id and l.is_delete=0"). + Join("LEFT", new(models.User).Alias("u"), "u.id=o.buyer_id and u.is_delete=0"). + Where("o.is_delete=0 and o.activity_id=? and o.rehearsal_id=?", activityId, rehearsalId). + Asc("o.created_at").Find(&orders) + t.CheckErr(err) + + items, err := invitation_service.GetOptionItem(activityId) + t.CheckErr(err) + for i := range orders { + data, err := invitation_service.GetOptionValue(items, orders[i].ExtraData) + t.CheckErr(err) + orders[i].Extra = data + } + + // 下订单人数 + buyerCount, err := core.GetXormAuto().Where("is_delete=0 and activity_id=? and rehearsal_id=?", + activityId, rehearsalId).Distinct("buyer_id").Count(new(models.CustomerOrder)) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "orders": orders, + "total": len(orders), + "buyer_count": buyerCount, + }) +} diff --git a/controllers/pc/reward.go b/controllers/pc/reward.go new file mode 100644 index 0000000..cceca58 --- /dev/null +++ b/controllers/pc/reward.go @@ -0,0 +1,221 @@ +package pc + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/services/pay" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "strings" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type RewardCtl struct { + controllers.AuthorCtl +} +type RewardResult struct { + models.RewardHistory `xorm:"extends"` + User *models.User `json:"user" xorm:"extends"` +} + +//获取最新的打赏记录 +func (t *RewardCtl) Latest() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + //获取打赏服务得id + server := new(models.RewardServer) + exist, err := server.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_REWARD_NOT_EXIST, "打赏不存在") + + result := new(RewardResult) + exist, err = core.GetXormAuto().Table(new(models.RewardHistory)).Alias("h"). + Join("LEFT", new(models.User).Alias("u"), "h.user_id=u.id and u.is_delete=0"). + Where("h.is_delete=0 and h.status=2 and h.reward_server_id=? and h.rehearsal_id=?", server.Id, rehearsalId). + OrderBy("review_time desc").Get(result) + t.CheckErr(err) + if !exist { + t.RAW(result) + } + + result.User.Openid = "" + result.User.Unionid = "" + result.RewardHistory.RewardAmount = fmt.Sprintf("%.2f", result.RewardHistory.Amount) + t.CheckErr(models.Save(map[string]interface{}{ + "id=": result.RewardHistory.Id, + }, &models.RewardHistory{ + Status: 3, + UpdatedAt: time.Now(), + }, "status", "update_at")) + t.RAW(result) +} + +//获取待审核列表 +func (t *RewardCtl) WaitReview() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + //获取打赏服务得id + server := new(models.RewardServer) + exist, err := server.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_REWARD_NOT_EXIST, "打赏不存在") + + t.CheckErr(pay_service.BatchQueryByActivityId(activityId)) + t.CheckErr(pay_service.BatchQueryRefundByActivityId(activityId)) + + result := make([]*RewardResult, 0) + err = core.GetXormAuto().Table(new(models.RewardHistory)).Alias("h"). + Join("LEFT", new(models.User).Alias("u"), "h.user_id=u.id and u.is_delete=0"). + Where("h.is_delete=0 and h.status=0 and h.reward_server_id=? and h.rehearsal_id=?", + server.Id, rehearsalId).OrderBy("h.created_at desc").Find(&result) + t.CheckErr(err) + //根据打赏服务得id获取待审核得打赏列表 + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +//审核 +func (t *RewardCtl) Review() { + // todo: false 代表通过, true 代表不通过 + idList := t.MustGet("ids") + status := t.MustGetBool("status") + ids := strings.Split(idList, "|") + //rehearsalId := t.MustGetInt64("rehearsal_id") + + result := make([]*models.RewardHistory, 0) + err := core.GetXormAuto().Where("is_delete=0").In("id", ids).Find(&result) + t.CheckErr(err) + + //if rehearsalId != 0 { // 彩排不需要金额 + // t.RAW("审核成功") + // return + //} + + // 审核 + for _, v := range result { + if v.Status != 0 { + t.ERROR("该打赏已处理", code.MSG_USER_DATA_ERROR) + } + if status { // false 通过 , true 不通过 + // 回退金额给用户 + // 应该微信退款 + + _, err := v.UpdateStatus(v.Id, 1) + t.CheckErr(err) + + //if rehearsalId != 0 { // 彩排不需要金额 + // continue + //} + + order := new(models.UserOrder) + exist, err := models.GetById(order, v.UserOrderId) + t.CheckErr(err) + t.Assert(exist, code.MSG_USER_ORDER_NOT_EXIST, "用户支付订单不存在") + + _, err = pay_service.Refund("欧轩互动-打赏拉黑", order.OutTradeNo, order.OpenId, order.GoodType, order.TotalFee, order.TotalFee, order.UserId, order.ActivityId) + t.CheckErr(err) + + } else { + //增加客户的金额 + _, err := v.UpdateStatus(v.Id, 2) + t.CheckErr(err) + + //if rehearsalId != 0 { // 彩排不需要金额 + // continue + //} + + uid := t.MustGetUID() + customer := new(models.Customer) + exist, err := models.GetById(customer, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + wallet := new(models.RewardWallet) + _, err = wallet.IncrBalance(uid, v.Amount) + t.CheckErr(err) + + _, err = core.GetXormAuto().InsertOne(&models.RewardWalletHistory{ + CustomerId: uid, + Money: v.Amount, + Type: "打赏", + UserId: v.UserId, + RewardHistoryId: v.Id, + RewardAccount: v.RewardAmount, + Status: "交易成功", + Mark: "打赏金额", + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + }) + t.CheckErr(err) + } + } + // 发送审核的信息 + t.RAW("审核成功") +} + +//获取打赏得总金额 +func (t *RewardCtl) Amount() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + //获取打赏服务得id + server := new(models.RewardServer) + exist, err := server.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_REWARD_NOT_EXIST, "打赏不存在") + + totalAmount, err := core.GetXormAuto().Where("reward_server_id=? and status=3 and is_delete=0 "+ + " and rehearsal_id=?", server.Id, rehearsalId).Sum(new(models.RewardHistory), "amount") + t.CheckErr(err) + + t.DisplayByData(map[string]interface{}{ + "amount": utils.Float64CusDecimal(totalAmount, 2), + }) +} + +// 黑名单 +func (t *RewardCtl) Blacklist() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + // 获取打赏的服务id + server := new(models.RewardServer) + exist, err := server.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_REWARD_NOT_EXIST, "打赏不存在") + + // 根据打赏服务id获取待审核的名单 + // status=true 代表审核不通过还是通过 + // 目前表示不通过,bully_screen也一样 + result := make([]*RewardResult, 0) + err = core.GetXormAuto().Table(new(models.RewardHistory)).Alias("h"). + Join("LEFT", new(models.User).Alias("u"), "h.user_id=u.id and u.is_delete=0"). + Where("h.is_delete=0 and h.status=1 and h.reward_server_id=? and h.rehearsal_id=?", + server.Id, rehearsalId).OrderBy("review_time desc").Find(&result) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +// 开启打赏 +func (t *RewardCtl) Details() { + activityId := t.MustGetInt64("activity_id") + server := new(models.RewardServer) + exist, err := server.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_REWARD_NOT_EXIST, "打赏不存在") + + t.JSON(map[string]interface{}{ + "server": server, + }) +} diff --git a/controllers/pc/shake_red_envelope.go b/controllers/pc/shake_red_envelope.go new file mode 100644 index 0000000..22d9d0c --- /dev/null +++ b/controllers/pc/shake_red_envelope.go @@ -0,0 +1,213 @@ +package pc + +import ( + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + red_envelope_service "hudongzhuanjia/services/red_envelope" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" +) + +type ShakeRedEnvelopeCtl struct { + controllers.AuthorCtl +} + +func (t *ShakeRedEnvelopeCtl) Ready() { + ruleId := t.MustGetInt64("shake_red_envelope_rule_id") + + rule := new(models.ShakeRedEnvelopeRule) + exist, err := models.GetById(rule, ruleId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "摇红包不存在") + if rule.ShakeRedEnvelopeStatus != define.StatusNotBegin { + t.ERROR(fmt.Sprintf("该活动%s", rule.ShakeRedEnvelopeStatus), code.MSG_ERR) + } + envelope := new(models.ShakeRedEnvelopeActivity) + exist, err = models.GetById(envelope, rule.ShakeRedEnvelopeActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_SHAKERB_NOT_EXIST, "摇红包不存在") + + activity := new(models.Activity) + exist, err = models.GetById(activity, envelope.ActivityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + // done: 把其他的准备中的状态改为未开始 + // 又一个坑, 红包的 轮次根据 activity_id + sids := make([]int64, 0) + err = core.GetXormAuto().Table(new(models.ShakeRedEnvelopeActivity)).Select("id"). + Where("is_delete=0 and activity_id=?", activity.Id).Find(&sids) + t.CheckErr(err) + + _, err = rule.UpdateToStatusBySids(sids, define.StatusReady, define.StatusNotBegin) + t.CheckErr(err) + + // 初始化红包 + err = red_envelope_service.GenRedEnvelope(activity.Id, activity.RehearsalId, rule) + t.CheckErr(err) + + _, err = rule.UpdateStatus(ruleId, define.StatusReady) + t.CheckErr(err) + t.SUCCESS("success") +} + +//开始摇红包 +func (t *ShakeRedEnvelopeCtl) Start() { + ruleId := t.MustGetInt64("shake_red_envelope_rule_id") + + //根据摇红包规则id查找该条记录并且更给状态 + rule := new(models.ShakeRedEnvelopeRule) + exist, err := models.GetById(rule, ruleId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "摇红包不存在") + + if rule.ShakeRedEnvelopeStatus != define.StatusReady { + t.ERROR(fmt.Sprintf("该活动%s", rule.ShakeRedEnvelopeStatus), code.MSG_ERR) + } + + _, err = rule.UpdateStatus(ruleId, define.StatusRunning) + t.CheckErr(err) + t.SUCCESS("success") +} + +//停止摇红包 +func (t *ShakeRedEnvelopeCtl) Stop() { + ruleId := t.MustGetInt64("shake_red_envelope_rule_id") + + rule := new(models.ShakeRedEnvelopeRule) + exist, err := models.GetById(rule, ruleId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "拔河不存在") + + rule.ShakeRedEnvelopeStatus = define.StatusEnding + _, err = rule.UpdateStatus(ruleId, rule.ShakeRedEnvelopeStatus) + t.CheckErr(err) + t.SUCCESS("success") +} + +func (t *ShakeRedEnvelopeCtl) List() { + activityId := t.MustGetInt64("activity_id") + + activity := new(models.Activity) + exist, err := models.GetById(activity, activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_ACTIVITY_NOT_EXIST, "互动不存在") + t.CheckRunning(activity.Status) + + list := make([]*models.ShakeRedEnvelopeActivity, 0) + total, err := core.GetXormAuto().Where("is_delete=0 and is_pay=1 and activity_id=?", activityId).FindAndCount(&list) + t.CheckErr(err) + aIds := make([]int64, 0) + for _, v := range list { + aIds = append(aIds, v.Id) + } + area := new(models.AreaStore) + if t.MustGetCustomerPid() == 0 { + exist, err = area.GetMainAreaById(activityId) + } else { + exist, err = area.GetAreaStoreById(t.MustGetAreaId()) + } + t.CheckErr(err) + t.Assert(exist, code.MSG_DATA_NOT_EXIST, "地区不存在") + + rules := make([]*models.ShakeRedEnvelopeRule, 0) + err = core.GetXormAuto().Where("is_delete=0 and area_id=?", area.Id).In("shake_red_envelope_activity_id", aIds).Find(&rules) + t.CheckErr(err) + rIds := make([]int64, 0) + for _, v := range rules { + rIds = append(rIds, v.Id) + } + ladders := make([]*models.ShakeRedEnvelopeRuleLadder, 0) + core.GetXormAuto().Where("is_delete=0").In("shake_red_envelope_rule_id", rIds).Find(&ladders) + for index := range rules { + for i := range ladders { + if rules[index].Id == ladders[i].ShakeRedEnvelopeRuleId { + rules[index].ShakeRedEnvelopeRuleLadders = append(rules[index].ShakeRedEnvelopeRuleLadders, ladders[i]) + } + } + } + for index := range list { + for i := range rules { + if list[index].Id == rules[i].ShakeRedEnvelopeActivityId { + list[index].ShakeRedEnvelopeRule = rules[i] + break + } + } + } + + for index := range rules { + rules[index].Des = "根据对应得概率获得红包" + } + + t.JSON(map[string]interface{}{ + "total": total, + "list": list, + }) +} + +//二维码 +func (t *ShakeRedEnvelopeCtl) Qrcode() { + activityId := t.MustGetInt64("activity_id") + customerId := t.MustGetUID() + ruleId := t.MustGetInt64("shake_red_envelope_rule_id") + + //将服务器得地址和activity_id,动态生成二维码 + qrcode, err := utils.GenH5Qrcode(define.H5ShakeRb, map[string]interface{}{ + "activity_id": activityId, + "customer_id": customerId, + "rule_id": ruleId, + }) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "qrcode": qrcode, + }) +} + +type ShakeRedEnvelopeRecordAndUser struct { + models.ShakeRedEnvelopeRecord `xorm:"extends"` + User *models.User `json:"user" xorm:"extends"` +} + +// 参数优化 +func (t *ShakeRedEnvelopeCtl) Winners() { + ruleId := t.MustGetInt64("shake_red_envelope_rule_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + records := make([]*ShakeRedEnvelopeRecordAndUser, 0) + err := core.GetXormAuto().Table(new(models.ShakeRedEnvelopeRecord)).Alias("r"). + Join("LEFT", models.AliasTableName(new(models.User), "u"), "r.user_id=u.id and u.is_delete=0"). + Where("r.shake_red_envelope_rule_id=? and is_draw<>-1 and r.is_delete=0 and r.rehearsal_id=?", + ruleId, rehearsalId).OrderBy("r.created_at desc").Find(&records) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "total": len(records), + "winners": records, + }) +} + +// 统计摇红包参与人数和剩余红包数量 +func (t *ShakeRedEnvelopeCtl) Count() { + ruleId := t.MustGetInt64("shake_red_envelope_rule_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + rule := new(models.ShakeRedEnvelopeRule) + exist, err := models.GetById(rule, ruleId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "摇红包轮次不存在") + + numU, err := core.GetXormAuto().Where("is_delete=0 and shake_red_envelope_rule_id=? and rehearsal_id=?", + ruleId, rehearsalId).Count(new(models.ShakeRedEnvelopeUser)) + t.CheckErr(err) + + numR, err := core.GetXormAuto().Where("is_delete=0 and is_draw=-1 and shake_red_envelope_rule_id=? and rehearsal_id=?", + ruleId, rehearsalId).Count(new(models.ShakeRedEnvelopeRecord)) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "red_envelope_num": numR, + "red_envelope_user": numU, + }) +} diff --git a/controllers/pc/sign.go b/controllers/pc/sign.go new file mode 100644 index 0000000..2c31bd8 --- /dev/null +++ b/controllers/pc/sign.go @@ -0,0 +1,87 @@ +package pc + +import ( + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +//签到 +type SignCtl struct { + controllers.AuthorCtl +} + +//获取二维码 +func (t *SignCtl) Qrcode() { + activityId := t.MustGetInt64("activity_id") + uid := t.MustGetUID() + signUpId := t.MustGetInt64("sign_rule_id") + + //将服务器得地址和activity_id,动态生成二维码 + qrcode, err := utils.GenH5Qrcode(define.H5SignIn, map[string]interface{}{ + "activity_id": activityId, + "customer_id": uid, + "sign_rule_id": signUpId, + }) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "qrcode": qrcode, + "logo": "", + }) + +} + +//获取签到模式 +func (t *SignCtl) Mode() { + activityId := t.MustGetInt64("activity_id") + + //通过activity_id查询ox_sign_rule的id + signUp := new(models.SignUp) + exist, err := signUp.GetByActivityId(activityId) + t.CheckErr(err) + t.Assert(exist, code.MSG_SIGN_UP_NOT_EXIST, "签到规则不存在") + + t.RAW(signUp.MaxModel) +} + +func (t *SignCtl) List() { + activityId := t.MustGetInt64("activity_id") + signUps := make([]*models.SignUp, 0) + err := core.GetXormAuto().Where("is_delete=0 and activity_id=?", activityId).Asc("created_at").Find(&signUps) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "total": len(signUps), + "list": signUps, + }) +} + +type SignResult struct { + models.SignHistory `xorm:"extends"` + User *models.User `json:"user" xorm:"extends"` +} + +//处理签到信息 +func (t *SignCtl) SignInfo() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + result := make([]*SignResult, 0) + session := core.GetXormAuto().Table(new(models.SignHistory)).Alias("h"). + Join("LEFT", new(models.User).Alias("u"), "h.user_id=u.id and u.is_delete=0"). + Where("h.is_delete=0 and h.activity_id=? and rehearsal_id=?", activityId, rehearsalId) + if t.PageSize > 0 { // 增加分页 + session.Limit(t.PageSize, t.Page*t.PageSize) + } + count, err := session.FindAndCount(&result) + + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "list": result, + "sign_up_total": count, + }) +} diff --git a/controllers/pc/tug_war.go b/controllers/pc/tug_war.go new file mode 100644 index 0000000..b584c45 --- /dev/null +++ b/controllers/pc/tug_war.go @@ -0,0 +1,221 @@ +package pc + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type TugOfWarCtl struct { + controllers.AuthorCtl +} + +func (t *TugOfWarCtl) Ready() { // 准备中 + baheId := t.MustGetInt64("bahe_activity_id") + + bahe := new(models.TugOfWar) + exist, err := models.GetById(bahe, baheId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "拔河不存在") + if bahe.Status != define.StatusNotBegin { + t.ERROR(fmt.Sprintf("该活动%s", bahe.Status), code.MSG_ERR) + } + // done: 把其他的准备中的状态改为未开始 + _, err = bahe.UpdateToStatusByAid(bahe.ActivityId, define.StatusReady, define.StatusNotBegin) + t.CheckErr(err) + + // 创建队伍 只容许创建一次 + redTeam := &models.BaheTeam{ + BaheTeamName: "red", + ActivityId: bahe.ActivityId, + BaheActivityId: bahe.Id, + IsDelete: false, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + } + err = models.Save(map[string]interface{}{ + "bahe_activity_id=": bahe.Id, + "is_delete=": 0, + "bahe_team_name=": define.TUGWAR_TEAM_RED, + }, redTeam) + t.CheckErr(err) + + blueTeam := &models.BaheTeam{ + BaheTeamName: "blue", + ActivityId: bahe.ActivityId, + BaheActivityId: bahe.Id, + IsDelete: false, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + } + err = models.Save(map[string]interface{}{ + "bahe_activity_id=": bahe.Id, + "is_delete=": 0, + "bahe_team_name=": define.TUGWAR_TEAM_BULE, + }, blueTeam) + t.CheckErr(err) + + _, err = bahe.UpdateStatusById(bahe.Id, define.StatusReady) + t.CheckErr(err) + t.SUCCESS("操作成功") +} + +func (t *TugOfWarCtl) Start() { + baheId := t.MustGetInt64("bahe_activity_id") + + bahe := new(models.TugOfWar) + exist, err := models.GetById(bahe, baheId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "拔河不存在") + if bahe.Status != define.StatusReady { + t.ERROR(fmt.Sprintf("该活动%s", bahe.Status), code.MSG_ERR) + } + + _, err = bahe.UpdateStatusById(baheId, define.StatusRunning) + t.CheckErr(err) + t.SUCCESS("操作成功") +} + +func (t *TugOfWarCtl) Stop() { + baheId := t.MustGetInt64("bahe_activity_id") + + bahe := new(models.TugOfWar) + exist, err := models.GetById(bahe, baheId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "拔河不存在") + if bahe.Status != define.StatusRunning { + t.ERROR(fmt.Sprintf("该活动%s", bahe.Status), code.MSG_ERR) + } + + bahe.Status = define.StatusEnding + bahe.UpdatedAt = time.Now() + _, err = bahe.UpdateStatusById(bahe.Id, bahe.Status) + t.CheckErr(err) + t.SUCCESS("操作成功") +} + +func (t *TugOfWarCtl) Team() { + baheId := t.MustGetInt64("bahe_activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + customerId := t.MustGetUID() + + bahe := new(models.TugOfWar) + exist, err := models.GetById(bahe, baheId) + t.CheckErr(err) + t.Assert(exist, code.MSG_TUGWAR_NOT_EXIST, "拔河不存在") + + //获取队伍信息: 名字、二维码、颜色 + teams := make([]*models.BaheTeam, 0) + total, err := core.GetXormAuto().Where("is_delete=0 and bahe_activity_id=?", bahe.Id).FindAndCount(&teams) + t.CheckErr(err) + + // 队伍颜色 + qrcode := "" + // 二维码 + if bahe.Model != "随机分配模式" { + // 非随机模式,自选队伍 + for index := range teams { + qrcode, err = utils.GenH5Qrcode(define.H5TugOfWar, map[string]interface{}{ + "activity_id": bahe.ActivityId, + "customer_id": customerId, + "bahe_activity_id": bahe.Id, + "bahe_team_id": teams[index].Id, + "rehearsal_id": rehearsalId, + }) + t.CheckErr(err) + teams[index].Qrcode = qrcode + } + } else { + qrcode, err = utils.GenH5Qrcode(define.H5TugOfWar, map[string]interface{}{ + "activity_id": bahe.ActivityId, + "customer_id": customerId, + "bahe_activity_id": bahe.Id, + "bahe_team_id": 0, + "rehearsal_id": rehearsalId, + }) + t.CheckErr(err) + } + + t.JSON(map[string]interface{}{ + "total": total, + "list": teams, + "qrcode": qrcode, + "model": bahe.Model, + }) +} + +func (t *TugOfWarCtl) Member() { + baheId := t.MustGetInt64("bahe_activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + teams := make([]*models.BaheTeam, 0) + err := core.GetXormAuto().Where("is_delete=0 and bahe_activity_id=?", baheId).Find(&teams) + t.CheckErr(err) + + var total int64 = 0 + for index := range teams { + members := make([]*models.BaheTeamMember, 0) + num, err := core.GetXormAuto().Where("is_delete=0 and team_id=? and rehearsal_id=?", + teams[index].Id, rehearsalId).Desc("score").Asc("sort_time").FindAndCount(&members) + t.CheckErr(err) + total += num + teams[index].Members = members + } + + t.JSON(map[string]interface{}{ + "total": total, + "list": teams, + }) +} + +type BaheScoreResult struct { + TotalScore int64 `json:"total_score" description:"总分数"` + Id int64 `json:"id" description:"id"` + ActivityId int64 `json:"activity_id" description:"活动id"` + BaheActivityId int64 `json:"bahe_activity_id" description:"拔河活动id"` + BaheTeamName string `json:"bahe_team_name" description:"拔河队伍得名称"` + Members []*models.BaheTeamMember `json:"members"` +} + +func (t *TugOfWarCtl) Score() { + baheActivityId := t.MustGetInt64("bahe_activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + teams := make([]*BaheScoreResult, 0) + err := core.GetXormAuto().Table(new(models.BaheTeam)).Alias("t"). + Select("sum(m.score) as total_score, t.id, t.activity_id, t.bahe_activity_id, t.bahe_team_name"). + Join("LEFT", new(models.BaheTeamMember).Alias("m"), + "t.id=m.team_id and m.is_delete=0 and m.rehearsal_id=?", rehearsalId). + Where("t.is_delete=0 and t.bahe_activity_id=?", baheActivityId). + GroupBy("t.id").Find(&teams) + t.CheckErr(err) + + for index := range teams { + members := make([]*models.BaheTeamMember, 0) + err = core.GetXormAuto().Where("is_delete=0 and team_id=? and rehearsal_id=?", teams[index].Id, rehearsalId). + Desc("score").Asc("sort_time").Find(&members) + t.CheckErr(err) + teams[index].Members = members + } + t.JSON(map[string]interface{}{ + "total": len(teams), + "list": teams, + }) +} + +func (t *TugOfWarCtl) List() { + activityId := t.MustGetInt64("activity_id") + bahes := make([]*models.TugOfWar, 0) + err := core.GetXormAuto().Where("is_delete=0 and activity_id=?", activityId). + Asc("created_at").Find(&bahes) + t.CheckErr(err) + t.JSON(map[string]interface{}{ + "bahe_activities": bahes, + }) +} diff --git a/controllers/pc/upper_wall.go b/controllers/pc/upper_wall.go new file mode 100644 index 0000000..c7a94e0 --- /dev/null +++ b/controllers/pc/upper_wall.go @@ -0,0 +1,181 @@ +package pc + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + ws_send_service "hudongzhuanjia/services/ws_send" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "strings" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type UpperWallCtl struct { + controllers.AuthorCtl +} +type UpperWallResult struct { + models.UpperWall `xorm:"extends"` + User *models.User `json:"user" xorm:"extends"` +} + +//获取所有已审核的上墙消息 +func (t *UpperWallCtl) List() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + result := make([]*UpperWallResult, 0) + err := core.GetXormAuto().Table("ox_upper_wall").Alias("w"). + Join("LEFT", "ox_user as u", "w.user_id=u.id and u.is_delete=0"). + Where("w.is_delete=0 and w.status=3 and w.activity_id=? and w.rehearsal_id=?", activityId, rehearsalId). + OrderBy("w.review_time desc").Find(&result) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +//获取待审核列表 +func (t *UpperWallCtl) WaitReview() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + //根据霸屏服务得id获取待审核得霸屏列表 + result := make([]*UpperWallResult, 0) + err := core.GetXormAuto().Table("ox_upper_wall").Alias("w"). + Join("LEFT", "ox_user as u", "w.user_id=u.id and u.is_delete=0"). + Where("w.is_delete=0 and w.status=0 and w.activity_id=? and w.rehearsal_id=?", activityId, rehearsalId). + OrderBy("w.review_time desc").Find(&result) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +//审核操作 +func (t *UpperWallCtl) Review() { + idList := t.MustGet("ids") + status := t.MustGetBool("status") + uid := t.MustGetUID() + + ids := strings.Split(idList, "|") + + customer := new(models.Customer) + exist, err := models.GetById(customer, uid) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + reviewStatus := 1 + if !status { + reviewStatus = 3 // 审核通过直接发送ws + } + + t.CheckErr(models.Save(map[string]interface{}{ + "id in": ids, + }, &models.UpperWall{ + Status: reviewStatus, + ReviewTime: time.Now().Unix(), + }, "status", "review_time")) + + // false 通过 + if !status { + result := make([]*UpperWallResult, 0) + err := core.GetXormAuto().Table("ox_upper_wall").Alias("w"). + Join("LEFT", "ox_user as u", "w.user_id=u.id and u.is_delete=0"). + Where("w.is_delete=0").In("w.id", ids). + OrderBy("w.created_at asc").Find(&result) + t.CheckErr(err) + if len(result) == 0 { + t.ERROR("不存在上墙消息", code.MSG_DATA_NOT_EXIST) + return + } + + for index := range result { + bi, err := utils.Gif2Base64(result[index].Img) + t.CheckErr(err) + result[index].Img = bi + } + + go ws_send_service.SendUpperWall(fmt.Sprintf("%d", result[0].ActivityId), + define.TYPE_CUSTOMER, customer.Id, map[string]interface{}{ + "type": "upper_wall", + "customer_id": customer.Id, + "data": map[string]interface{}{ + "list": result, + "total": len(result)}, + }) + } + t.STRING("审核成功") +} + +//获取黑名单列表 +func (t *UpperWallCtl) Blacklist() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + result := make([]*UpperWallResult, 0) + + err := core.GetXormAuto().Table("ox_upper_wall").Alias("w"). + Join("LEFT", "ox_user as u", "w.user_id=u.id and u.is_delete=0"). + Where("w.is_delete=0 and w.status=1 and w.status=1 and w.rehearsal_id=? and w.activity_id=?", + rehearsalId, activityId).OrderBy("review_time desc").Find(&result) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": len(result), + "list": result, + }) +} + +//获取目前上墙得总条数 +func (t *UpperWallCtl) Total() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + + total, err := core.GetXormAuto().Where("is_delete=0 and activity_id=? and rehearsal_id=? and status=3", + activityId, rehearsalId).Count(new(models.UpperWall)) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "total": total, + }) +} + +//二维码 +// 跳到主页 +func (t *UpperWallCtl) Qrcode() { + activityId := t.MustGetInt64("activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + uid := t.MustGetUID() + + qrcode, err := utils.GenH5Qrcode(define.H5Index, map[string]interface{}{ + "activity_id": activityId, + "customer_id": uid, + "rehearsal_id": rehearsalId, + }) + t.CheckErr(err) + + t.JSON(map[string]interface{}{ + "qrcode": qrcode, + }) +} + +func (t *UpperWallCtl) Details() { + activityId := t.MustGetInt64("activity_id") + msgWall := new(models.MsgWallServer) + exist, err := msgWall.GetByActivityId(activityId) + t.CheckErr(err) + if !exist { + t.ERROR("上墙服务模块不存在", code.MSG_ERR) + } + t.JSON(map[string]interface{}{ + "msg_wall": msgWall, + }) +} diff --git a/controllers/pc/vote.go b/controllers/pc/vote.go new file mode 100644 index 0000000..88b55ab --- /dev/null +++ b/controllers/pc/vote.go @@ -0,0 +1,164 @@ +package pc + +import ( + "fmt" + "hudongzhuanjia/controllers" + "hudongzhuanjia/models" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/code" + "hudongzhuanjia/utils/define" + "strconv" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type VoteCtl struct { + controllers.AuthorCtl +} + +//二维码 +func (t *VoteCtl) Qrcode() { + qrcode, err := utils.GenH5Qrcode(define.H5Vote, map[string]interface{}{ + "activity_id": t.MustGetInt64("activity_id"), + "customer_id": t.MustGetUID(), + "vote_activity_id": t.MustGetInt64("vote_activity_id"), + }) + t.CheckErr(err) + + //直接输出二维码 + t.JSON(map[string]interface{}{ + "qrcode": qrcode, + }) +} + +// 装备数据 +func (t *VoteCtl) ReadyVote() { + voteId := t.MustGetInt64("vote_activity_id") + vote := new(models.NewVoteActivity) + exist, err := models.GetById(vote, voteId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "投票活动不存在") + if vote.VoteStatus != define.StatusNotBegin { + t.ERROR(fmt.Sprintf("该活动%s", vote.VoteStatus), code.MSG_ERR) + } + _, err = vote.UpdateToStatusByAid(vote.ActivityId, define.StatusReady, define.StatusNotBegin) + t.CheckErr(err) + + // 初始化某些数据, 例如投票的初始票数 + // 彩排结束恢复某些数据 + ladders := make([]*models.NewVoteActivityLadder, 0) + err = core.GetXormAuto().Where("is_delete=0 and vote_activity_id=?", vote.Id).Find(&ladders) + t.CheckErr(err) + for _, ladder := range ladders { + ladder.TotalNumber = ladder.VoteNumber + _, err = core.GetXormAuto().Where("is_delete=0 and id=?", ladder.Id). + Cols("total_number").Update(ladder) + t.CheckErr(err) + } + + _, err = vote.UpdateStatusById(vote.Id, define.StatusReady) + t.CheckErr(err) + t.SUCCESS("success") +} + +//开始投票 +func (t *VoteCtl) StartVote() { + voteId := t.MustGetInt64("vote_activity_id") + vote := new(models.NewVoteActivity) + exist, err := models.GetById(vote, voteId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "投票活动不存在") + + if vote.VoteStatus != define.StatusReady { + t.ERROR(fmt.Sprintf("该活动%s", vote.VoteStatus), code.MSG_ERR) + } + vote.VoteStatus = define.StatusRunning + vote.UpdatedAt = time.Now() + if vote.VoteLastTime == "" { + vote.VoteLastTime = "0" + } + duration, _ := strconv.ParseInt(vote.VoteLastTime, 10, 64) + vote.VoteEndTime = time.Now().Unix() + duration + _, err = core.GetXormAuto().Where("is_delete=0 and id=?", voteId). + Cols("vote_status", "vote_end_time", "updated_at").Update(vote) + t.CheckErr(err) + t.STRING("操作成功") +} + +//停止投票 +func (t *VoteCtl) StopVote() { + voteId := t.MustGetInt64("vote_activity_id") + + vote := new(models.NewVoteActivity) + exist, err := models.GetById(vote, voteId) + t.CheckErr(err) + t.Assert(exist, code.MSG_MODULE_NOT_EXIST, "投票活动不存在") + + if vote.VoteStatus != define.StatusRunning { + t.ERROR(fmt.Sprintf("该活动%s", vote.VoteStatus), code.MSG_ERR) + } + + vote.VoteStatus = define.StatusEnding + vote.UpdatedAt = time.Now() + vote.VoteEndTime = 0 + _, err = core.GetXormAuto().Where("is_delete=0 and id=?", voteId). + Cols("vote_status", "updated_at", "vote_end_time").Update(vote) + t.CheckErr(err) + + t.STRING("操作成功") +} + +//获取参与人数 +func (t *VoteCtl) JoinTotal() { + voteActivityId := t.MustGetInt64("vote_activity_id") + rehearsalId := t.MustGetInt64("rehearsal_id") + total, err := core.GetXormAuto().Distinct("user_id").Where("vote_activity_id=? and rehearsal_id=? and is_delete=0", + voteActivityId, rehearsalId).Count(new(models.NewVoteActivityHistory)) + t.CheckErr(err) + t.RAW(total) +} + +//获取所有的投票活动 +func (t *VoteCtl) List() { + activityId := t.MustGetInt64("activity_id") + + list := make([]*models.NewVoteActivity, 0) + total, err := core.GetXormAuto().Where("is_delete=0 and activity_id=?", activityId). + Asc("created_at").FindAndCount(&list) + t.CheckErr(err) + + ids := make([]int64, 0) + for _, v := range list { + ids = append(ids, v.Id) + } + ladders := make([]*models.NewVoteActivityLadder, 0) + err = core.GetXormAuto().Where("is_delete=0").In("vote_activity_id", ids).Find(&ladders) + t.CheckErr(err) + + for index := range list { + for i := range ladders { + if list[index].Id == ladders[i].VoteActivityId { + list[index].VoteActivityLadders = append(list[index].VoteActivityLadders, ladders[i]) + } + } + } + + t.JSON(map[string]interface{}{ + "total": total, + "list": list, + }) +} + +//获取投票的前几(头像、姓名、票数) +func (t *VoteCtl) History() { + voteActivityId := t.MustGetInt64("vote_activity_id") + //rehearsalId := t.MustGetInt64("rehearsal_id") + total := t.MustGetInt("total") + + ladders := make([]*models.NewVoteActivityLadder, 0) + err := core.GetXormAuto().Where("is_delete=0 and vote_activity_id=?", voteActivityId). + Desc("total_number").Asc("updated_at").Limit(total).Find(&ladders) + t.CheckErr(err) + t.RAW(ladders) +} diff --git a/controllers/pc/ws.go b/controllers/pc/ws.go new file mode 100644 index 0000000..b2c5947 --- /dev/null +++ b/controllers/pc/ws.go @@ -0,0 +1,83 @@ +package pc + +import ( + "encoding/json" + "hudongzhuanjia/controllers" + "hudongzhuanjia/logger" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/code" + "time" +) + +type WsCtl struct { + controllers.AuthorCtl +} + +// ws doc +// @Summary ws +// @Description get current operation +// @Tags ws +// @Accept json +// @Produce json +// @Param activity_id query int true "Activity ID" +// @Success 0 {array} models.CustomerOperation +// @Failure 503 {string} string "参数不存在" +// @Failure 504 {object} string "用户不存在" +// @Router /Pc/WsCtl/ops [get] +func (t *WsCtl) Ops() { + customerId := t.MustGetUID() + activityId, _ := t.GetInt64("activity_id") + customer := new(models.Customer) + exist, err := models.GetById(customer, customerId) + t.CheckErr(err) + t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在") + + op := new(models.CustomerOperation) + if customer.Pid == 0 { + exist, err = op.GetOpByActivityId(activityId) + } else { + exist, err = op.GetOpByCustomerId(customer.Pid) + } + t.CheckErr(err) + if !exist { + t.JSON(map[string]interface{}{ + "operations": []*models.CustomerOperation{}, + }) + } + + var m = make(map[string]interface{}) + err = json.Unmarshal([]byte(op.ExtraData), &m) + t.CheckErr(err) + + op.OtherData = m + t.JSON(map[string]interface{}{ + "operations": []*models.CustomerOperation{op}, + }) +} + +// ws doc +// @Summary ws +// @Description save operation +// @Tags ws +// @Accept json +// @Produce json +// @Param operation query string true "操作内容" +// @Success 0 {string} string "success" +// @Failure 503 {string} string "参数不存在" +// @Failure 504 {object} string "用户不存在" +// @Router /Pc/WsCtl/saveOp [post] +func (t *WsCtl) SaveOp() { + customerId := t.MustGetInt64("customer_id") + extraData := t.Default("extra_data", "") + op := &models.CustomerOperation{ + CustomerId: customerId, + ExtraData: extraData, + UpdatedAt: time.Now(), + CreatedAt: time.Now(), + } + if row := op.SaveCustomerOperation(); row != 1 { + logger.Sugar.Debugf("save customer_operation出现错误") + t.ERROR("customer operation格式错误", code.MSG_ERR) + } + t.STRING("success") +} diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..7c11b21 --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,596 @@ +// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// This file was generated by swaggo/swag at +// 2019-11-07 14:33:12.2505817 +0800 CST m=+0.073000101 + +package docs + +import ( + "bytes" + "encoding/json" + + "github.com/alecthomas/template" + "github.com/swaggo/swag" +) + +var doc = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "This is a sample server Petstore server.", + "title": "hudongzhuangjia api", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "http://www.swagger.io/support", + "email": "support@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "1.0" + }, + "host": "172.0.0.1:20181", + "basePath": "/PcClient", + "paths": { + "/Client/InviteEnvelopeCtl/invite": { + "post": { + "description": "填写要求信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "invite envelope" + ], + "summary": "InviteEnvelope", + "parameters": [ + { + "type": "integer", + "description": "邀请函内容", + "name": "activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "description": "success", + "schema": { + "type": "string" + } + }, + "404": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "405": { + "description": "用户不存在", + "schema": { + "type": "string" + } + } + } + } + }, + "/Client/InviteEnvelopeCtl/setting": { + "get": { + "description": "get invite envelope setting", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "invite envelope" + ], + "summary": "InviteEnvelope", + "parameters": [ + { + "type": "integer", + "description": "Activity ID", + "name": "activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "schema": { + "type": "object", + "$ref": "#/definitions/models.Invitation" + } + }, + "404": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "405": { + "description": "用户不存在", + "schema": { + "type": "string" + } + } + } + } + }, + "/Client/TugOfWarCtl/shake": { + "get": { + "description": "shake bahe activity", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "tug war" + ], + "summary": "tug war", + "parameters": [ + { + "type": "integer", + "description": "Bahe Activity ID", + "name": "bahe_activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "schema": { + "type": "object", + "$ref": "#/definitions/models.BaheTeam" + } + }, + "404": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "405": { + "description": "用户不存在", + "schema": { + "type": "object", + "$ref": "#/definitions/string" + } + } + } + } + }, + "/Client/TugOfWarCtl/status": { + "get": { + "description": "get current status", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "client tug war" + ], + "summary": "client tug war", + "parameters": [ + { + "type": "integer", + "description": "Bahe Activity ID", + "name": "bahe_activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "schema": { + "type": "object", + "$ref": "#/definitions/models.TugOfWar" + } + }, + "503": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "504": { + "description": "用户不存在", + "schema": { + "type": "object", + "$ref": "#/definitions/string" + } + } + } + } + }, + "/Pc/ActivityCtl/list": { + "get": { + "description": "get all area store", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pc" + ], + "summary": "activity", + "responses": { + "200": { + "description": "success", + "schema": { + "type": "string" + } + } + } + } + }, + "/Pc/AuctionCtl/startAuction": { + "get": { + "description": "开始竞拍", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pc" + ], + "summary": "auction", + "parameters": [ + { + "type": "integer", + "description": "竞拍id", + "name": "auction_activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "success", + "schema": { + "type": "string" + } + } + } + } + }, + "/Pc/AuctionCtl/stopAuction": { + "get": { + "description": "结束竞拍", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pc" + ], + "summary": "auction", + "parameters": [ + { + "type": "integer", + "description": "竞拍id", + "name": "auction_activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "success", + "schema": { + "type": "string" + } + } + } + } + }, + "/Pc/WsCtl/ops": { + "get": { + "description": "get current operation", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ws" + ], + "summary": "ws", + "parameters": [ + { + "type": "integer", + "description": "Activity ID", + "name": "activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.CustomerOperation" + } + } + }, + "503": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "504": { + "description": "用户不存在", + "schema": { + "type": "object", + "$ref": "#/definitions/string" + } + } + } + } + }, + "/Pc/WsCtl/saveOp": { + "post": { + "description": "save operation", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ws" + ], + "summary": "ws", + "parameters": [ + { + "type": "string", + "description": "操作内容", + "name": "operation", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "description": "success", + "schema": { + "type": "string" + } + }, + "503": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "504": { + "description": "用户不存在", + "schema": { + "type": "object", + "$ref": "#/definitions/string" + } + } + } + } + } + }, + "definitions": { + "models.BaheTeam": { + "type": "object", + "properties": { + "activity_id": { + "type": "integer" + }, + "bahe_activity_id": { + "type": "integer" + }, + "bahe_team_name": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "is_delete": { + "type": "boolean" + }, + "members": { + "type": "array", + "items": { + "$ref": "#/definitions/models.BaheTeamMember" + } + }, + "qrcode": { + "type": "string" + }, + "rank": { + "type": "integer" + }, + "total_score": { + "type": "integer" + } + } + }, + "models.BaheTeamMember": { + "type": "object", + "properties": { + "avatar": { + "type": "string" + }, + "bahe_activity_id": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "member_id": { + "type": "integer" + }, + "nick_name": { + "type": "string" + }, + "rehearsal_id": { + "type": "integer" + }, + "score": { + "type": "integer" + }, + "team_id": { + "type": "integer" + }, + "team_name": { + "type": "string" + } + } + }, + "models.CustomerOperation": { + "type": "object", + "properties": { + "activity_id": { + "type": "integer" + }, + "area_id": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "customer_id": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "is_delete": { + "type": "boolean" + }, + "module_activity_id": { + "type": "integer" + }, + "module_activity_type": { + "type": "string" + }, + "operation": { + "type": "string" + }, + "other_data": { + "type": "object" + }, + "updated_at": { + "type": "string" + } + } + }, + "models.Invitation": { + "type": "object", + "properties": { + "activity_id": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "qr_dest_url": { + "type": "string" + }, + "qr_image_url": { + "type": "string" + }, + "self_box": { + "type": "string" + }, + "setting_box": { + "type": "string" + }, + "submit_time_limit": { + "type": "string" + }, + "time_limit_end": { + "type": "string" + } + } + }, + "models.TugOfWar": { + "type": "object", + "properties": { + "activity_id": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "is_delete": { + "type": "boolean" + }, + "model": { + "type": "string" + }, + "number": { + "type": "integer" + }, + "status": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + } + } +}` + +type swaggerInfo struct { + Version string + Host string + BasePath string + Schemes []string + Title string + Description string +} + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = swaggerInfo{ Schemes: []string{}} + +type s struct{} + +func (s *s) ReadDoc() string { + t, err := template.New("swagger_info").Funcs(template.FuncMap{ + "marshal": func(v interface {}) string { + a, _ := json.Marshal(v) + return string(a) + }, + }).Parse(doc) + if err != nil { + return doc + } + + var tpl bytes.Buffer + if err := t.Execute(&tpl, SwaggerInfo); err != nil { + return doc + } + + return tpl.String() +} + +func init() { + swag.Register(swag.Name, &s{}) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..f815b37 --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,544 @@ +{ + "swagger": "2.0", + "info": { + "description": "This is a sample server Petstore server.", + "title": "hudongzhuangjia api", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "http://www.swagger.io/support", + "email": "support@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "1.0" + }, + "host": "172.0.0.1:20181", + "basePath": "/PcClient", + "paths": { + "/Client/InviteEnvelopeCtl/invite": { + "post": { + "description": "填写要求信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "invite envelope" + ], + "summary": "InviteEnvelope", + "parameters": [ + { + "type": "integer", + "description": "邀请函内容", + "name": "activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "description": "success", + "schema": { + "type": "string" + } + }, + "404": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "405": { + "description": "用户不存在", + "schema": { + "type": "string" + } + } + } + } + }, + "/Client/InviteEnvelopeCtl/setting": { + "get": { + "description": "get invite envelope setting", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "invite envelope" + ], + "summary": "InviteEnvelope", + "parameters": [ + { + "type": "integer", + "description": "Activity ID", + "name": "activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "schema": { + "type": "object", + "$ref": "#/definitions/models.Invitation" + } + }, + "404": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "405": { + "description": "用户不存在", + "schema": { + "type": "string" + } + } + } + } + }, + "/Client/TugOfWarCtl/shake": { + "get": { + "description": "shake bahe activity", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "tug war" + ], + "summary": "tug war", + "parameters": [ + { + "type": "integer", + "description": "Bahe Activity ID", + "name": "bahe_activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "schema": { + "type": "object", + "$ref": "#/definitions/models.BaheTeam" + } + }, + "404": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "405": { + "description": "用户不存在", + "schema": { + "type": "object", + "$ref": "#/definitions/string" + } + } + } + } + }, + "/Client/TugOfWarCtl/status": { + "get": { + "description": "get current status", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "client tug war" + ], + "summary": "client tug war", + "parameters": [ + { + "type": "integer", + "description": "Bahe Activity ID", + "name": "bahe_activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "schema": { + "type": "object", + "$ref": "#/definitions/models.TugOfWar" + } + }, + "503": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "504": { + "description": "用户不存在", + "schema": { + "type": "object", + "$ref": "#/definitions/string" + } + } + } + } + }, + "/Pc/ActivityCtl/list": { + "get": { + "description": "get all area store", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pc" + ], + "summary": "activity", + "responses": { + "200": { + "description": "success", + "schema": { + "type": "string" + } + } + } + } + }, + "/Pc/AuctionCtl/startAuction": { + "get": { + "description": "开始竞拍", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pc" + ], + "summary": "auction", + "parameters": [ + { + "type": "integer", + "description": "竞拍id", + "name": "auction_activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "success", + "schema": { + "type": "string" + } + } + } + } + }, + "/Pc/AuctionCtl/stopAuction": { + "get": { + "description": "结束竞拍", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "pc" + ], + "summary": "auction", + "parameters": [ + { + "type": "integer", + "description": "竞拍id", + "name": "auction_activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "success", + "schema": { + "type": "string" + } + } + } + } + }, + "/Pc/WsCtl/ops": { + "get": { + "description": "get current operation", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ws" + ], + "summary": "ws", + "parameters": [ + { + "type": "integer", + "description": "Activity ID", + "name": "activity_id", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.CustomerOperation" + } + } + }, + "503": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "504": { + "description": "用户不存在", + "schema": { + "type": "object", + "$ref": "#/definitions/string" + } + } + } + } + }, + "/Pc/WsCtl/saveOp": { + "post": { + "description": "save operation", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ws" + ], + "summary": "ws", + "parameters": [ + { + "type": "string", + "description": "操作内容", + "name": "operation", + "in": "query", + "required": true + } + ], + "responses": { + "0": { + "description": "success", + "schema": { + "type": "string" + } + }, + "503": { + "description": "参数不存在", + "schema": { + "type": "string" + } + }, + "504": { + "description": "用户不存在", + "schema": { + "type": "object", + "$ref": "#/definitions/string" + } + } + } + } + } + }, + "definitions": { + "models.BaheTeam": { + "type": "object", + "properties": { + "activity_id": { + "type": "integer" + }, + "bahe_activity_id": { + "type": "integer" + }, + "bahe_team_name": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "is_delete": { + "type": "boolean" + }, + "members": { + "type": "array", + "items": { + "$ref": "#/definitions/models.BaheTeamMember" + } + }, + "qrcode": { + "type": "string" + }, + "rank": { + "type": "integer" + }, + "total_score": { + "type": "integer" + } + } + }, + "models.BaheTeamMember": { + "type": "object", + "properties": { + "avatar": { + "type": "string" + }, + "bahe_activity_id": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "member_id": { + "type": "integer" + }, + "nick_name": { + "type": "string" + }, + "rehearsal_id": { + "type": "integer" + }, + "score": { + "type": "integer" + }, + "team_id": { + "type": "integer" + }, + "team_name": { + "type": "string" + } + } + }, + "models.CustomerOperation": { + "type": "object", + "properties": { + "activity_id": { + "type": "integer" + }, + "area_id": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "customer_id": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "is_delete": { + "type": "boolean" + }, + "module_activity_id": { + "type": "integer" + }, + "module_activity_type": { + "type": "string" + }, + "operation": { + "type": "string" + }, + "other_data": { + "type": "object" + }, + "updated_at": { + "type": "string" + } + } + }, + "models.Invitation": { + "type": "object", + "properties": { + "activity_id": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "qr_dest_url": { + "type": "string" + }, + "qr_image_url": { + "type": "string" + }, + "self_box": { + "type": "string" + }, + "setting_box": { + "type": "string" + }, + "submit_time_limit": { + "type": "string" + }, + "time_limit_end": { + "type": "string" + } + } + }, + "models.TugOfWar": { + "type": "object", + "properties": { + "activity_id": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "is_delete": { + "type": "boolean" + }, + "model": { + "type": "string" + }, + "number": { + "type": "integer" + }, + "status": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + } + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..fcb0445 --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,360 @@ +basePath: /PcClient +definitions: + models.BaheTeam: + properties: + activity_id: + type: integer + bahe_activity_id: + type: integer + bahe_team_name: + type: string + id: + type: integer + is_delete: + type: boolean + members: + items: + $ref: '#/definitions/models.BaheTeamMember' + type: array + qrcode: + type: string + rank: + type: integer + total_score: + type: integer + type: object + models.BaheTeamMember: + properties: + avatar: + type: string + bahe_activity_id: + type: integer + id: + type: integer + member_id: + type: integer + nick_name: + type: string + rehearsal_id: + type: integer + score: + type: integer + team_id: + type: integer + team_name: + type: string + type: object + models.CustomerOperation: + properties: + activity_id: + type: integer + area_id: + type: integer + created_at: + type: string + customer_id: + type: integer + id: + type: integer + is_delete: + type: boolean + module_activity_id: + type: integer + module_activity_type: + type: string + operation: + type: string + other_data: + type: object + updated_at: + type: string + type: object + models.Invitation: + properties: + activity_id: + type: integer + id: + type: integer + qr_dest_url: + type: string + qr_image_url: + type: string + self_box: + type: string + setting_box: + type: string + submit_time_limit: + type: string + time_limit_end: + type: string + type: object + models.TugOfWar: + properties: + activity_id: + type: integer + created_at: + type: string + id: + type: integer + is_delete: + type: boolean + model: + type: string + number: + type: integer + status: + type: string + updated_at: + type: string + type: object +host: 172.0.0.1:20181 +info: + contact: + email: support@swagger.io + name: API Support + url: http://www.swagger.io/support + description: This is a sample server Petstore server. + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + termsOfService: http://swagger.io/terms/ + title: hudongzhuangjia api + version: "1.0" +paths: + /Client/InviteEnvelopeCtl/invite: + post: + consumes: + - application/json + description: 填写要求信息 + parameters: + - description: 邀请函内容 + in: query + name: activity_id + required: true + type: integer + produces: + - application/json + responses: + "0": + description: success + schema: + type: string + "404": + description: 参数不存在 + schema: + type: string + "405": + description: 用户不存在 + schema: + type: string + summary: InviteEnvelope + tags: + - invite envelope + /Client/InviteEnvelopeCtl/setting: + get: + consumes: + - application/json + description: get invite envelope setting + parameters: + - description: Activity ID + in: query + name: activity_id + required: true + type: integer + produces: + - application/json + responses: + "0": + schema: + $ref: '#/definitions/models.Invitation' + type: object + "404": + description: 参数不存在 + schema: + type: string + "405": + description: 用户不存在 + schema: + type: string + summary: InviteEnvelope + tags: + - invite envelope + /Client/TugOfWarCtl/shake: + get: + consumes: + - application/json + description: shake bahe activity + parameters: + - description: Bahe Activity ID + in: query + name: bahe_activity_id + required: true + type: integer + produces: + - application/json + responses: + "0": + schema: + $ref: '#/definitions/models.BaheTeam' + type: object + "404": + description: 参数不存在 + schema: + type: string + "405": + description: 用户不存在 + schema: + $ref: '#/definitions/string' + type: object + summary: tug war + tags: + - tug war + /Client/TugOfWarCtl/status: + get: + consumes: + - application/json + description: get current status + parameters: + - description: Bahe Activity ID + in: query + name: bahe_activity_id + required: true + type: integer + produces: + - application/json + responses: + "0": + schema: + $ref: '#/definitions/models.TugOfWar' + type: object + "503": + description: 参数不存在 + schema: + type: string + "504": + description: 用户不存在 + schema: + $ref: '#/definitions/string' + type: object + summary: client tug war + tags: + - client tug war + /Pc/ActivityCtl/list: + get: + consumes: + - application/json + description: get all area store + produces: + - application/json + responses: + "200": + description: success + schema: + type: string + summary: activity + tags: + - pc + /Pc/AuctionCtl/startAuction: + get: + consumes: + - application/json + description: 开始竞拍 + parameters: + - description: 竞拍id + in: query + name: auction_activity_id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: success + schema: + type: string + summary: auction + tags: + - pc + /Pc/AuctionCtl/stopAuction: + get: + consumes: + - application/json + description: 结束竞拍 + parameters: + - description: 竞拍id + in: query + name: auction_activity_id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: success + schema: + type: string + summary: auction + tags: + - pc + /Pc/WsCtl/ops: + get: + consumes: + - application/json + description: get current operation + parameters: + - description: Activity ID + in: query + name: activity_id + required: true + type: integer + produces: + - application/json + responses: + "0": + schema: + items: + $ref: '#/definitions/models.CustomerOperation' + type: array + "503": + description: 参数不存在 + schema: + type: string + "504": + description: 用户不存在 + schema: + $ref: '#/definitions/string' + type: object + summary: ws + tags: + - ws + /Pc/WsCtl/saveOp: + post: + consumes: + - application/json + description: save operation + parameters: + - description: 操作内容 + in: query + name: operation + required: true + type: string + produces: + - application/json + responses: + "0": + description: success + schema: + type: string + "503": + description: 参数不存在 + schema: + type: string + "504": + description: 用户不存在 + schema: + $ref: '#/definitions/string' + type: object + summary: ws + tags: + - ws +swagger: "2.0" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..759f47b --- /dev/null +++ b/go.mod @@ -0,0 +1,34 @@ +module hudongzhuanjia + +go 1.12 + +require ( + github.com/360EntSecGroup-Skylar/excelize/v2 v2.0.1 + github.com/agrison/go-tablib v0.0.0-20160310143025-4930582c22ee + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 + github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect + github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect + github.com/gorilla/websocket v1.4.0 + github.com/iGoogle-ink/gopay v1.5.1 // indirect + github.com/iGoogle-ink/gopay/v2 v2.0.5 + github.com/kirinlabs/HttpRequest v0.1.5 + github.com/ouxuanserver/osmanthuswine v0.0.0-20190916032555-480efadf4941 + github.com/panjf2000/ants v4.0.2+incompatible + github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 + github.com/smartystreets/goconvey v1.6.4 + github.com/swaggo/http-swagger v0.0.0-20190614090009-c2865af9083e + github.com/swaggo/swag v1.6.3 + github.com/tencentyun/cos-go-sdk-v5 v0.0.0-20190926121715-a33db3b0dede + github.com/xormplus/xorm v0.0.0-20190419084314-284871d688a4 + go.uber.org/atomic v1.4.0 // indirect + go.uber.org/multierr v1.2.0 // indirect + go.uber.org/zap v1.10.0 + golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect + golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a // indirect + golang.org/x/net v0.0.0-20191021144547-ec77196f6094 // indirect + golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae // indirect + golang.org/x/tools v0.0.0-20191025023517-2077df36852e // indirect + gopkg.in/natefinch/lumberjack.v2 v2.0.0 + gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..7b1ec86 --- /dev/null +++ b/go.sum @@ -0,0 +1,412 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.2/go.mod h1:H8IAquKe2L30IxoupDgqTaQvKSwF/c8prYHynGIWQbA= +cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= +cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/360EntSecGroup-Skylar/excelize/v2 v2.0.1 h1:gnknz1/4RnpL2fZsJzsqsGHgjWDT7k11tGPsFiDQeDk= +github.com/360EntSecGroup-Skylar/excelize/v2 v2.0.1/go.mod h1:fkN+AZg31J/y9B4AtylxjzzNYetIxi6cElYu/WBUb7g= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Chronokeeper/anyxml v0.0.0-20160530174208-54457d8e98c6 h1:Etfj2lhXyrYemgmWzEtEQQb1kezeEXc8jVjkQUyJnWI= +github.com/Chronokeeper/anyxml v0.0.0-20160530174208-54457d8e98c6/go.mod h1:YzuYAe2hrrwKXkM9kqjbkTLlkbA+/xw2MA46f1+ENxc= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a h1:3SgJcK9l5uPdBC/X17wanyJAMxM33+4ZhEIV96MIH8U= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/jet v2.1.2+incompatible h1:ybZoYzMBdoijK6I+Ke3vg9GZsmlKo/ZhKdNMWz0P26c= +github.com/CloudyKit/jet v2.1.2+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/agrison/go-tablib v0.0.0-20160310143025-4930582c22ee h1:0RklYSvekYaIFI9JUx7TFPQvo++TdILmZiV17QI4nXk= +github.com/agrison/go-tablib v0.0.0-20160310143025-4930582c22ee/go.mod h1:M9nmO4lBRWR/bBv7UCOmDJ1MB2DVoqz19B4JchDA+K0= +github.com/agrison/mxj v0.0.0-20160310142625-1269f8afb3b4 h1:XBNSe5eibe5Fh131ah+xnO6s4A97U1T3tKZKLQQvqu0= +github.com/agrison/mxj v0.0.0-20160310142625-1269f8afb3b4/go.mod h1:n7qJAqL9BKqGqiJyjPbWtxpdswTL5wX0IVP2Uw4vVhQ= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/aws/aws-sdk-go v1.19.14 h1:wUq6zI7Y5RfzFIkworUhK71bd/Vld9Otc6bgM/0ws1A= +github.com/aws/aws-sdk-go v1.19.14/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/bndr/gotabulate v1.1.2 h1:yC9izuZEphojb9r+KYL4W9IJKO/ceIO8HDwxMA24U4c= +github.com/bndr/gotabulate v1.1.2/go.mod h1:0+8yUgaPTtLRTjf49E8oju7ojpU11YmXyvq1LbPAb3U= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I= +github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20190401154936-ce35bd87d4b3/go.mod h1:EcO5fNtMZHCMjAvj8LE6T+5bphSdR6LQ75n+m1TtsFI= +github.com/denisenkom/go-mssqldb v0.0.0-20190418034912-35416408c946 h1:xn+jBHAqNYs6CnHhJwfWZQspPHMEL+LzUk0vpqWj6eo= +github.com/denisenkom/go-mssqldb v0.0.0-20190418034912-35416408c946/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= +github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7YFTXg5IgGVW4gBr5IbvE= +github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= +github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs= +github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk= +github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4= +github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4= +github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-xorm/core v0.6.2 h1:EJLcSxf336POJr670wKB55Mah9f93xzvGYzNRgnT8/Y= +github.com/go-xorm/core v0.6.2/go.mod h1:bwPIfLdm/FzWgVUH8WPVlr+uJhscvNGFcaZKXsI3n2c= +github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= +github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/iGoogle-ink/gopay v1.4.8 h1:c98uztaUODTJuV8vsJQUswN6G+TxVqn6cl/DYv5kHxg= +github.com/iGoogle-ink/gopay v1.5.1 h1:uAKvQows+O7P8tPsdxXMwe/YqqeEIEswrdVDwF8bFOU= +github.com/iGoogle-ink/gopay v1.5.1/go.mod h1:/A7M5Ts6OUEaQD+88stwhPtFV1AxOCL+CAtjreZlGGQ= +github.com/iGoogle-ink/gopay/v2 v2.0.5 h1:jjiHTzkbXEOLC87hs3cAfAGC6+CqWzz/hQ/2x3w1lIU= +github.com/iGoogle-ink/gopay/v2 v2.0.5/go.mod h1:plZK1Q8XAw19RkO4MLMYEWWmIhshVK9FtLOrS1ooNwg= +github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc= +github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= +github.com/jackc/pgx v3.3.0+incompatible h1:Wa90/+qsITBAPkAZjiByeIGHFcj3Ztu+VzrrIpHjL90= +github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/jinzhu/gorm v1.9.4 h1:3KDoUjMEfH58nweXdD5Dng222YiwOVUNFShENhehJyQ= +github.com/jinzhu/gorm v1.9.4/go.mod h1:7ZYqlk/T0SqZip7ZOIL1aC/sjDj+dJo6sN98WljHFXY= +github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k= +github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.0 h1:6WV8LvwPpDhKjo5U9O6b4+xdG/jTXNPwlDme/MTo8Ns= +github.com/jinzhu/now v1.0.0/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/kirinlabs/HttpRequest v0.1.5 h1:BzOb6AmBii232R93birBsf663kt8N9y8N0TCQKoEzhA= +github.com/kirinlabs/HttpRequest v0.1.5/go.mod h1:XV38fA4rXZox83tlEV9KIQ7Cdsut319x6NGzVLuRlB8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0 h1:/5u4a+KGJptBRqGzPvYQL9p0d/tPR4S31+Tnzj9lEO4= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/ouxuanserver/osmanthuswine v0.0.0-20190916032555-480efadf4941 h1:MpkZbGXvxwbsYNTtDphTCsGMi//M2ija6LJr3N6/DpI= +github.com/ouxuanserver/osmanthuswine v0.0.0-20190916032555-480efadf4941/go.mod h1:lIF2zcUhvVpFuLKpEYh3ArHRoZsGNo3PZS7FYqmQBXI= +github.com/panjf2000/ants v4.0.2+incompatible h1:6K9b4YyUmbTvfxGm2YZgmDgIiCEyP1x+gewN+tBr/8U= +github.com/panjf2000/ants v4.0.2+incompatible/go.mod h1:AaACblRPzq35m1g3enqYcxspbbiOJJYaxU2wMpm1cXY= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/satori/go.uuid v0.0.0-20190313024323-b2ce2384e17b h1:PB8A682UQ6pwoFhkszETBsYw3B9Ze9FEA4cf9H9O3f8= +github.com/satori/go.uuid v0.0.0-20190313024323-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM= +github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E= +github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI= +github.com/swaggo/http-swagger v0.0.0-20190614090009-c2865af9083e h1:m5sYJ43teIUlESuKRFQRRm7kqi6ExiYwVKfoXNuRgHU= +github.com/swaggo/http-swagger v0.0.0-20190614090009-c2865af9083e/go.mod h1:eycbshptIv+tqTMlLEaGC2noPNcetbrcYEelLafrIDI= +github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y= +github.com/swaggo/swag v1.6.3 h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI= +github.com/swaggo/swag v1.6.3/go.mod h1:wcc83tB4Mb2aNiL/HP4MFeQdpHUrca+Rp/DRNgWAUio= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tealeg/xlsx v1.0.3 h1:BXsDIQYBPq2HgbwUxrsVXIrnO0BDxmsdUfHSfvwfBuQ= +github.com/tealeg/xlsx v1.0.3/go.mod h1:uxu5UY2ovkuRPWKQ8Q7JG0JbSivrISjdPzZQKeo74mA= +github.com/tencentyun/cos-go-sdk-v5 v0.0.0-20190926121715-a33db3b0dede h1:4FiecrX2TsfWVkXozpV2JOOI09KvC4jD1JotxY2bSnQ= +github.com/tencentyun/cos-go-sdk-v5 v0.0.0-20190926121715-a33db3b0dede/go.mod h1:wk2XFUg6egk4tSDNZtXeKfe2G6690UVyt163PuUxBZk= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0= +github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/wailovet/db2struct v0.0.0-20190220022639-a297dc96489a h1:RndWCoBQ9Ltyj1m46BmGexEv3ZU8hPjV3fGo1xxh07A= +github.com/wailovet/db2struct v0.0.0-20190220022639-a297dc96489a/go.mod h1:Dqil0kg+pAM/6QVGUG6LY9EVUtT/SJqpXsaklNalmz0= +github.com/wailovet/overseer v0.0.0-20190412102736-c280479fa09f h1:N69pQZKxZw3tUsnCWJSw4dG+t4lbb4mCLbiHz1sHfMk= +github.com/wailovet/overseer v0.0.0-20190412102736-c280479fa09f/go.mod h1:IE0ZeKrlRAFsChkP21Tg3CKgybYJ7qiHHJAcH/xB4Sg= +github.com/xormplus/builder v0.0.0-20181220055446-b12ceebee76f h1:1kd2rgJuSRqTCUSqFkKuaUNsNogLzjPhC9Pr8qnhZDs= +github.com/xormplus/builder v0.0.0-20181220055446-b12ceebee76f/go.mod h1:Sz1j9HNsNKOUBDcBcezcwVpydQ/UkFrDo1M2XmuU3mc= +github.com/xormplus/core v0.0.0-20190120064039-da7907271e2f h1:RTzjDWlXKTcurd/cWTOuaxTACdWw+gs7HaNCLaK1PJQ= +github.com/xormplus/core v0.0.0-20190120064039-da7907271e2f/go.mod h1:V3p6iAR/MaICgU6GJqxGQxspfljTyfOTv4Czz0B5atU= +github.com/xormplus/xorm v0.0.0-20190419084314-284871d688a4 h1:7cw+J6ScPpTq9QgHSS4wrGUkrbCE2oVL/dct7YP4d+M= +github.com/xormplus/xorm v0.0.0-20190419084314-284871d688a4/go.mod h1:+v6b10b4x5IcQmp1/Cbo9IqaknxVeuhQng+fhya6bdI= +github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A= +go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M= +go.opencensus.io v0.20.1 h1:pMEjRZ1M4ebWGikflH7nQpV6+Zr88KBMA2XJD3sbijw= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.2.0 h1:6I+W7f5VwC5SV9dNrZ3qXrDB9mD0dyGOi/ZJmYw03T4= +go.uber.org/multierr v1.2.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a h1:gHevYm0pO4QUbwy8Dmdr01R5r1BuKtfYqRqF0h/Cbh0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f h1:hX65Cu3JDlGH3uEdK7I99Ii+9kjD6mvnnpfLdEAH0x4= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190419010253-1f3472d942ba h1:h0zCzEL5UW1mERvwTN6AXcc75PpLkY6OcReia6Dq1BM= +golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a h1:+KkCgOMgnKSgenxTBoiwkMqTiouMIy/3o8RLdmSbGoY= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191021144547-ec77196f6094 h1:5O4U9trLjNpuhpynaDsqwCk+Tw6seqJz1EbqbnzHrc8= +golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be h1:mI+jhqkn68ybP0ORJqunXn+fq+Eeb4hHKqLQcFICjAc= +golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae h1:QoJmnb9uyPCrH8GIg9uRLn4Ta45yhcQtpymCd0AavO8= +golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b h1:/mJ+GKieZA6hFDQGdWZrjj4AXPl5ylY+5HusG80roy0= +golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191025023517-2077df36852e h1:ejUPpxsbZzyShOEURCSvFIT0ltnmBW92Vsc3i8QRcw8= +golang.org/x/tools v0.0.0-20191025023517-2077df36852e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.2.0/go.mod h1:IfRCZScioGtypHNTlz3gFk67J8uePVW7uDTBzXuIkhU= +google.golang.org/api v0.3.0/go.mod h1:IuvZyQh8jgscv8qWfQ4ABd8m7hEudgBFM/EdhA3BnXw= +google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/flosch/pongo2.v3 v3.0.0-20141028000813-5e81b817a0c4 h1:eyQQg/uGuZ3ndaBhqteakHpVW+dSOPalilfC9RpM2TA= +gopkg.in/flosch/pongo2.v3 v3.0.0-20141028000813-5e81b817a0c4/go.mod h1:bJkYqV5pg6+Z7MsSu/hSb1zsPT955hBW2QHLE1jm4wA= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 h1:sY2a+y0j4iDrajJcorb+a0hJIQ6uakU5gybjfLWHlXo= +gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376/go.mod h1:BHKOc1m5wm8WwQkMqYBoo4vNxhmF7xg8+xhG8L+Cy3M= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/goxorm/config b/goxorm/config new file mode 100644 index 0000000..25d2913 --- /dev/null +++ b/goxorm/config @@ -0,0 +1,3 @@ +lang=go +genJson=1 +prefix=ox_ diff --git a/goxorm/struct.go.tpl b/goxorm/struct.go.tpl new file mode 100644 index 0000000..0c07fae --- /dev/null +++ b/goxorm/struct.go.tpl @@ -0,0 +1,20 @@ + +package {{.Models}} + +{{$ilen := len .Imports}} +{{if gt $ilen 0}} +import ( + {{range .Imports}}"{{.}}"{{end}} +) +{{end}} + +{{range .Tables}} +type {{Mapper .Name}} struct { +{{$table := .}} +{{range .ColumnsSeq}}{{$col := $table.GetColumn .}} {{Mapper $col.Name}} {{Type $col}} {{Tag $table $col}} +{{end}} +} + +var {{Mapper .Name}}Entity {{Mapper .Name}} + +{{end}} diff --git a/html/annex/1559027799707464500.ncx b/html/annex/1559027799707464500.ncx new file mode 100644 index 0000000..e69de29 diff --git a/libs/jwt/jwt_go.go b/libs/jwt/jwt_go.go new file mode 100644 index 0000000..53f3ed1 --- /dev/null +++ b/libs/jwt/jwt_go.go @@ -0,0 +1,67 @@ +package jwt + +import ( + "errors" + "fmt" + "time" + + "github.com/dgrijalva/jwt-go" + "github.com/ouxuanserver/osmanthuswine/src/helper" +) + +type JwtClaims struct { + AccountType string + AccountId int64 + CustomerId int64 + CustomerPid int64 + Username string + ActivityId int64 + AreaId int64 + jwt.StandardClaims +} + +func GenJwtToken(accountType string, accountId, customerId, customerPid, areaId, activityId int64, username string) (string, error) { + claims := JwtClaims{ + accountType, + accountId, + customerId, + customerPid, + username, + activityId, + areaId, + jwt.StandardClaims{ + ExpiresAt: time.Now().Add(time.Duration(24000) * time.Hour).Unix(), + Id: helper.CreateUUID(), + Issuer: Issuer, + Subject: Subject, + Audience: Audience, + }, + } + + t := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + return t.SignedString([]byte(Secret)) +} + +const Secret = "osmanthuswine-very-secret" +const Issuer = "osmanthuswine-issuer-ox" +const Subject = "osmanthuswine-subject-ox" +const Audience = "osmanthuswine-audience-ox" + +func ParseAccessToken(accessToken string) (*JwtClaims, error) { + var claims = &JwtClaims{} + token, err := jwt.ParseWithClaims(accessToken, claims, func(token *jwt.Token) (i interface{}, e error) { + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) + } + return []byte(Secret), nil + }) + + if token == nil { + return claims, errors.New("token invalid") + } + + if !claims.VerifyExpiresAt(time.Now().Unix(), true) { + return nil, errors.New("token expired") + } + return claims, err +} diff --git a/libs/jwt/jwt_test.go b/libs/jwt/jwt_test.go new file mode 100644 index 0000000..8c15b8a --- /dev/null +++ b/libs/jwt/jwt_test.go @@ -0,0 +1,8 @@ +package jwt + +import ( + "testing" +) + +func TestJwt(t *testing.T) { +} diff --git a/libs/qq/qq.go b/libs/qq/qq.go new file mode 100644 index 0000000..e35579c --- /dev/null +++ b/libs/qq/qq.go @@ -0,0 +1,139 @@ +package qq + +import ( + "encoding/json" + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/helper" + "io/ioutil" + "net/http" + "net/url" +) + +var ( + Appid = "" + AppKey = "" + RedirectUri = "" + DefaultScope = "get_user_info" + CodeUrl = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&state=%s&scope=%s" + TokenUrl = "https://graph.qq.com/oauth2.0/authorize?grant_type=authorization_code&client_id=%s&client_serect=%s&code=%s&redirect_uri=%s" + RefreshUrl = "https://graph.qq.com/oauth2.0/token?grant_type=refresh_token&client_id=%s&client_serect=%s&refresh_token=%s" + PcOpenidUrl = "https://graph.qq.com/oauth2.0/me?access_token=%s" + WapOpenidUrl = "https://graph.z.qq.com/moc2/me?access_token=%s" + UserInfoUrl = "https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s&format=json" +) + +func GetCodeUrl() string { + uid := helper.CreateUUID() + return fmt.Sprintf(CodeUrl, Appid, url.PathEscape(RedirectUri), uid, DefaultScope) +} + +func GetTokenUrl(code string) string { + return fmt.Sprintf(TokenUrl, Appid, AppKey, code, RedirectUri) +} + +func GetRefreshUrl(refreshToken string) string { + return fmt.Sprintf(RefreshUrl, Appid, AppKey, refreshToken) +} + +func GetPcOpenidUrl(accessToken string) string { + return fmt.Sprintf(PcOpenidUrl, accessToken) +} + +func GetWapOpenidUrl(accessToken string) string { + return fmt.Sprintf(WapOpenidUrl, accessToken) +} + +func GetUserInfoUrl(accessToken, openid string) string { + return fmt.Sprintf(UserInfoUrl, accessToken, Appid, openid) +} + +type Token struct { + AccessToken string `json:"access_token"` + ExpiresIn int64 `json:"expires_in"` + RefreshToken string `json:"refresh_token"` +} + +func GetToken(code string) (*Token, error) { + tokenUrl := GetTokenUrl(code) + resp, err := http.Get(tokenUrl) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + return nil, err + } + token := new(Token) + err = json.Unmarshal(body, token) + return token, err +} + +func RefreshToken(refreshToken string) (*Token, error) { + refreshUrl := GetRefreshUrl(refreshToken) + resp, err := http.Get(refreshUrl) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + return nil, err + } + token := new(Token) + err = json.Unmarshal(body, token) + return token, err +} + +type Open struct { + Openid string `json:"openid"` + ClientId string `json:"client_id"` +} + +func GetPcOpenid(accessToken string) (*Open, error) { + pcOpenidUrl := GetPcOpenidUrl(accessToken) + resp, err := http.Get(pcOpenidUrl) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + return nil, err + } + open := new(Open) + err = json.Unmarshal(body, open) + return open, err +} + +type UserInfo struct { + Ret int `json:"ret"` + Msg string `json:"msg"` + Nickname string `json:"nickname"` + Figureurl string `json:"figureurl"` + Figureurl1 string `json:"figureurl_1"` + Figureurl2 string `json:"figureurl_2"` + FigureurlQq1 string `json:"figureurl_qq_1"` + FigureurlQq2 string `json:"figureurl_qq_2"` + Gender string `json:"gender"` + IsYellowVip string `json:"is_yellow_vip"` + Vip string `json:"vip"` + YellowVipLevel string `json:"yellow_vip_level"` + Level string `json:"level"` + IsYellowYearVip string `json:"is_yellow_year_vip"` +} + +func GetUserInfo(accessToken, openid string) (*UserInfo, error) { + userInfoUrl := GetUserInfoUrl(accessToken, openid) + resp, err := http.Get(userInfoUrl) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + userInfo := new(UserInfo) + err = json.Unmarshal(body, userInfo) + return userInfo, err +} diff --git a/libs/wx/code.go b/libs/wx/code.go new file mode 100644 index 0000000..19a7dfa --- /dev/null +++ b/libs/wx/code.go @@ -0,0 +1,32 @@ +package wx + +const CODE_SUCCESS = "SUCCESS" // 成功 +const CODE_FAIL = "FAIL" // 失败 +const CODE_NOTPAY = "NOTPAY" // 未支付 +const CODE_CHANGE = "CHANGE" // 退款异常 +const CODE_REFUNDCLOSE = "REFUNDCLOSE" // 退款关闭 +const CODE_ERROR = "ERROR" // 业务错误 +const CODE_INVALID_REQUEST = "INVALID_REQUEST" // 无效请求 +const CODE_NOAUTH = "NOAUTH" // 异常IP请求不予受理 +const CODE_NOTENOUGH = "NOTENOUGH" // 余额不足 +const CODE_ORDERPAID = "ORDERPAID" // 订单已支付 +const CODE_ORDERCLOSED = "ORDERCLOSED" // 订单已关闭 +const CODE_SYSTEMERROR = "SYSTEMERROR" // 系统错误 +const CODE_APPID_NOT_EXIST = "APPID_NOT_EXIST" // APPID不存在 +const CODE_MCHID_NOT_EXIST = "MCHID_NOT_EXIST" // MCHID不存在 +const CODE_APPID_MCHID_NOT_MATCH = "APPID_MCHID_NOT_MATCH" // APPID MCHID 不匹配 +const CODE_LACK_PARAMS = "LACK_PARAMS" // 缺少参数 +const CODE_OUT_TRADE_NO_USED = "OUT_TRADE_NO_USED" // 商户订单号重复 +const CODE_SIGNERROR = "SIGNERROR" // 签名错误 +const CODE_XML_FORMAT_ERROR = "XML_FORMAT_ERROR" // xml格式错误 +const CODE_REQUIRE_POST_METHOD = "REQUIRE_POST_METHOD" // 请使用post请求方法 +const CODE_POST_DATA_EMPTY = "POST_DATA_EMPTY" // post数据为空 +const CODE_NOT_UTF8 = "NOT_UTF8" // 编码错误 +const CODE_ORDERNOTEXIST = "ORDERNOTEXIST" // 交易订单号不存在 +const CODE_BIZERR_NEED_RETRY = "BIZERR_NEED_RETRY" // 退款业务流程错误,需要商户触发重试来解决 +const CODE_TRADE_OVERDUE = "TRADE_OVERDUE" // 订单已经超过退款期限 +const CODE_USER_ACCOUNT_ABNORMAL = "USER_ACCOUNT_ABNORMAL" // 退款请求失败用户帐号注销 +const CODE_INVALID_REQ_TOO_MUCH = "INVALID_REQ_TOO_MUCH" // 无效请求过多 +const CODE_INVALID_TRANSACTIONID = "INVALID_TRANSACTIONID" // 无效transaction_id +const CODE_PARAM_ERROR = "PARAM_ERROR" // 参数错误 +const CODE_FREQUENCY_LIMITED = "FREQUENCY_LIMITED" // 请求频率限制 diff --git a/libs/wx/order.go b/libs/wx/order.go new file mode 100644 index 0000000..b1bdd2a --- /dev/null +++ b/libs/wx/order.go @@ -0,0 +1,135 @@ +package wx + +// import ( +// "bytes" +// "crypto/tls" +// "crypto/x509" +// "encoding/xml" +// "io/ioutil" +// "net/http" +// "net/url" +// "strconv" + +// "github.com/ouxuanserver/osmanthuswine/src/helper" +// ) + +// const KEY = "wechat_key" + +// var transfers = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers" + +// type Order struct { +// XMLName xml.Name `xml:"xml"` +// MchAppid string `xml:"mch_appid"` +// Mchid string `xml:"mchid"` +// DeviceInfo string `xml:"device_info"` +// NonceStr string `xml:"nonce_str"` +// Sign string `xml:"sign"` +// PartnerTradeNo string `xml:"partner_trade_no"` +// Openid string `xml:"openid"` +// CheckName string `xml:"check_name"` +// ReUserName string `xml:"re_user_name"` +// Amount int `xml:"amount"` +// Desc string `xml:"desc"` +// SpbillCreateIp string `xml:"spbill_create_ip"` +// } + +// type OrderResult struct { +// ReturnCode string `xml:"return_code"` +// ReturnMsg string `xml:"return_msg"` +// ResultCode string `xml:"result_code"` +// ErrCode string `xml:"err_code"` +// ErrCodeDes string `xml:"err_code_des"` +// MchAppid string `xml:"mch_appid"` +// Mchid string `json:"mchid"` +// DeviceInfo string `json:"device_info"` +// NonceStr string `json:"nonce_str"` +// PartnerTradeNo string `xml:"partner_trade_no"` +// PaymentNo string `xml:"payment_no"` +// PaymentTime string `xml:"payment_time"` +// } + +// //付款,成功返回自定义订单号,微信订单号,true,失败返回错误信息,false +// func Withdraw(appid, mchid, openid, amount, partnerTradeNo, desc, clientIp string) (*OrderResult, error) { +// order := Order{} +// order.MchAppid = appid +// order.Mchid = mchid +// order.Openid = openid +// order.Amount, _ = strconv.Atoi(amount) +// order.Desc = desc +// order.PartnerTradeNo = partnerTradeNo +// order.DeviceInfo = "WEB" +// order.CheckName = "NO_CHECK" //NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名 +// order.SpbillCreateIp = clientIp +// order.NonceStr = helper.CreateUUID() +// order.Sign = md5WithdrawOrder(order) +// xmlBody, _ := xml.MarshalIndent(order, " ", " ") +// resp, err := SecurePost(transfers, xmlBody) +// if err != nil { +// return nil, err +// } +// defer resp.Body.Close() +// bodyByte, _ := ioutil.ReadAll(resp.Body) +// res := new(OrderResult) +// err = xml.Unmarshal(bodyByte, res) +// return res, err +// } +// func md5WithdrawOrder(order Order) string { +// o := url.Values{} +// o.Add("mch_appid", order.MchAppid) +// o.Add("mchid", order.Mchid) +// o.Add("device_info", order.DeviceInfo) +// o.Add("partner_trade_no", order.PartnerTradeNo) +// o.Add("check_name", order.CheckName) +// o.Add("amount", strconv.Itoa(order.Amount)) +// o.Add("spbill_create_ip", order.SpbillCreateIp) +// o.Add("desc", order.Desc) +// o.Add("nonce_str", order.NonceStr) +// o.Add("openid", order.Openid) +// r, _ := url.QueryUnescape(o.Encode()) +// return helper.Md5(r + "&key=" + KEY) +// } + +// var ( +// wechatCertPath = `./cert/cert.pem` +// wechatKeyPath = `./cert/key.pem` +// wechatCAPath = `./cert/rootca.pem` +// ) + + +//采用单例模式初始化ca +// func getTLSConfig() (*tls.Config, error) { +// if _tlsConfig != nil { +// return _tlsConfig, nil +// } +// // load cert +// cert, err := tls.LoadX509KeyPair(wechatCertPath, wechatKeyPath) +// if err != nil { +// return nil, err +// } +// // load root ca +// caData, err := ioutil.ReadFile(wechatCAPath) +// if err != nil { +// return nil, err +// } +// pool := x509.NewCertPool() +// pool.AppendCertsFromPEM(caData) +// _tlsConfig = &tls.Config{ +// Certificates: []tls.Certificate{cert}, +// RootCAs: pool, +// } +// return _tlsConfig, nil +// } + +// //携带ca证书的安全请求 +// func SecurePost(url string, xmlContent []byte) (*http.Response, error) { +// tlsConfig, err := getTLSConfig() +// if err != nil { +// return nil, err +// } +// tr := &http.Transport{TLSClientConfig: tlsConfig} +// client := &http.Client{Transport: tr} +// return client.Post( +// url, +// "application/xml", +// bytes.NewBuffer(xmlContent)) +// } diff --git a/libs/wx/params.go b/libs/wx/params.go new file mode 100644 index 0000000..4d9c324 --- /dev/null +++ b/libs/wx/params.go @@ -0,0 +1,287 @@ +package wx + +import ( + "encoding/xml" + "fmt" + "hudongzhuanjia/utils/define" +) + +var ( + WxCertPath = `./cacert/apiclient_cert.pem` + WxKeyPath = `./cacert/apiclient_key.pem` + WxCaPath = `./cacert/rootca.pem` + Appid = "wx7b0bcf476552c5e9" + Secret = "f6aabdd40ea25272f4442603a7dc8028" + Mchid = `1394404502` + ApiKey = `2c82c64ceec6ba89ffc9f593c671a12f` + mainHost = `https://api.mch.weixin.qq.com` + backHost = `https://api2.mch.weixin.qq.com` +) + +var ( + RedirectUri = "http://api.hudongzhuanjia.com/" + CodeUrl = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect" + AccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code " + RefreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s" + AuthUrl = "https://api.weixin.qq.com/sns/auth?access_token=%s&openid=%s" + UserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s" + TicketTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s" + TicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi" + Expired = 7200 +) + +var ( + NotifyURL = fmt.Sprintf("%s/wechat/callback", define.HOST) // 微信回调通知 + UnifiedOrderURL = fmt.Sprintf("%s/pay/unifiedorder", mainHost) // 统一下单url + QueryOrderURL = fmt.Sprintf("%s/pay/orderquery", mainHost) // 微信查询订单 + CloseOrderURL = fmt.Sprintf("%s/pay/closeorder", mainHost) // 微信关闭订单 + RefundURL = fmt.Sprintf("%s/secapi/pay/refund", mainHost) // 微信退款 + RefundQueryURL = fmt.Sprintf("%s/pay/refundquery", mainHost) // 微信查询退款 + DownloadBillURL = fmt.Sprintf("%s/pay/downloadbill", mainHost) // 微信下载账单 + DownloadFundFlowURL = fmt.Sprintf("%s/pay/downloadfundflow", mainHost) + TransfersURL = fmt.Sprintf("%s/mmpaymkttransfers/promotion/transfers", mainHost) + SendRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/sendredpack", mainHost) + QueryRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/gethbinfo", mainHost) +) + +type CommonReturn struct { + ReturnCode string `xml:"return_code,omitempty" json:"return_code,omitempty"` + ReturnMsg string `xml:"return_msg,omitempty" json:"return_msg,omitempty"` +} + +type CommonResult struct { + ResultCode string `xml:"result_code,omitempty" json:"result_code,omitempty"` + ResultMsg string `xml:"result_msg,omitempty" json:"result_msg,omitempty"` + ErrCode string `xml:"err_code,omitempty" json:"err_code,omitempty"` + ErrCodeDes string `xml:"err_code_des,omitempty" json:"err_code_des,omitempty"` +} + +type CommonParam struct { + Appid string `xml:"appid,omitempty" json:"appid,omitempty"` + MchId string `xml:"mch_id,omitempty" json:"mch_id,omitempty"` + NonceStr string `xml:"nonce_str,omitempty" json:"nonce_str,omitempty"` + Sign string `xml:"sign,omitempty" json:"sign,omitempty"` + SignType string `xml:"sign_type,omitempty" json:"sign_type,omitempty"` +} + +// ========================================== 基础配置 + +type UnifiedOrderParam struct { + CommonParam + XMLName xml.Name `xml:"xml" json:"xml_name,omitempty"` + DeviceInfo string `xml:"device_info,omitempty" json:"device_info,omitempty"` + Body cdata `xml:"body,omitempty" json:"body,omitempty"` + Detail cdata `xml:"detail,omitempty" json:"detail,omitempty"` + Attach string `xml:"attach,omitempty" json:"attach,omitempty"` + OutTradeNo string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"` + FeeType string `xml:"fee_type,omitempty" json:"fee_type,omitempty"` + TotalFee string `xml:"total_fee,omitempty" json:"total_fee,omitempty"` + SpbillCreateIp string `xml:"spbill_create_ip,omitempty" json:"spbill_create_ip,omitempty"` + TimeStart string `xml:"time_start,omitempty" json:"time_start,omitempty"` + TimeExpire string `xml:"time_expire,omitempty" json:"time_expire,omitempty"` + GoodsTag string `xml:"goods_tag,omitempty" json:"goods_tag,omitempty"` + NotifyUrl string `xml:"notify_url,omitempty" json:"notify_url,omitempty"` + TradeType string `xml:"trade_type,omitempty" json:"trade_type,omitempty"` + ProductId string `xml:"product_id,omitempty" json:"product_id,omitempty"` + LimitPay string `xml:"limit_pay,omitempty" json:"limit_pay,omitempty"` + Openid string `xml:"openid,omitempty" json:"openid,omitempty"` + Receipt string `xml:"receipt,omitempty" json:"receipt,omitempty"` + SceneInfo *UnifiedOrderSceneInfo `xml:"scene_info,omitempty" json:"scene_info,omitempty"` +} + +type UnifiedOrderSceneInfo struct { + Id string `xml:"id,omitempty" json:"id,omitempty"` + Name string `xml:"name,omitempty" json:"name,omitempty"` + AreaCode string `xml:"area_code,omitempty" json:"area_code,omitempty"` + Address string `xml:"address,omitempty" json:"address,omitempty"` +} + +type UnifiedOrderResult struct { + CommonReturn + CommonResult + CommonParam + DeviceInfo string `xml:"device_info,omitempty" json:"device_info,omitempty"` + NonceStr string `xml:"nonce_str,omitempty" json:"nonce_str,omitempty"` + TradeType string `xml:"trade_type,omitempty" json:"trade_type,omitempty"` + PrepayId string `xml:"prepay_id,omitempty" json:"prepay_id,omitempty"` + CodeUrl string `xml:"code_url,omitempty" json:"code_url,omitempty"` +} + +// =================================================支付 + +type QueryOrderParam struct { + CommonParam + XMLName xml.Name `xml:"xml" json:"xml_name,omitempty"` + TransactionId string `xml:"transaction_id,omitempty" json:"transaction_id,omitempty"` + OutTradeNo string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"` +} + +type QueryOrderResult struct { + CommonReturn + CommonResult + CommonParam + DeviceInfo string `xml:"device_info" json:"device_info,omitempty"` + Openid string `xml:"openid" json:"openid,omitempty"` + IsSubscribe string `xml:"is_subscribe" json:"is_subscribe,omitempty"` + TradeType string `xml:"trade_type" json:"trade_type,omitempty"` + TradeState string `xml:"trade_state" json:"trade_state,omitempty"` + BankType string `xml:"bank_type" json:"bank_type,omitempty"` + TotalFee string `xml:"total_fee" json:"total_fee,omitempty"` + SettlementTotalFee string `xml:"settlement_total_fee" json:"settlement_total_fee,omitempty"` + FeeType string `xml:"fee_type" json:"fee_type,omitempty"` + CashFee string `xml:"cash_fee" json:"cash_fee,omitempty"` + CashFeeType string `xml:"cash_fee_type" json:"cash_fee_type,omitempty"` + CouponFee string `xml:"coupon_fee" json:"coupon_fee,omitempty"` + CouponCount string `xml:"coupon_count" json:"coupon_count,omitempty"` + CouponTypeN string `xml:"coupon_type_$n" json:"coupon_type_$n,omitempty"` + CouponIdN string `xml:"coupon_id_$n" json:"coupon_id_$n,omitempty"` + CouponFeeN string `xml:"coupon_fee_$n" json:"coupon_fee_$n,omitempty"` + TransactionId string `xml:"transaction_id" json:"transaction_id,omitempty"` + OutTradeNo string `xml:"out_trade_no" json:"out_trade_no,omitempty"` + Attach string `xml:"attach" json:"attach,omitempty"` + TimeEnd string `xml:"time_end" json:"time_end,omitempty"` + TradeStateDesc string `xml:"trade_state_desc" json:"trade_state_desc,omitempty"` +} + +// ============================================================查询订单 + +type CloseOrderParam struct { + CommonParam + XMLName xml.Name `xml:"xml" json:"xml_name,omitempty"` + OutTradeNo string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"` +} + +type CloseOrderResult struct { + CommonReturn + CommonResult + CommonParam +} + +// ======================================== 关闭订单 + +type RefundParam struct { + CommonParam + XMLName xml.Name `xml:"xml" json:"xml_name,omitempty"` + TransactionId string `xml:"transaction_id,omitempty" json:"transaction_id,omitempty"` // 与订单号二选一 + OutTradeNo string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"` + OutRefundNo string `xml:"out_refund_no,omitempty" json:"out_refund_no,omitempty"` + TotalFee string `xml:"total_fee,omitempty" json:"total_fee,omitempty"` + RefundFee string `xml:"refund_fee,omitempty" json:"refund_fee,omitempty"` + RefundFeeType string `xml:"refund_fee_type,omitempty" json:"refund_fee_type,omitempty"` + RefundDesc string `xml:"refund_desc,omitempty" json:"refund_desc,omitempty"` + RefundAccount string `xml:"refund_account,omitempty" json:"refund_account,omitempty"` + NotifyUrl string `xml:"notify_url,omitempty" json:"notify_url,omitempty"` +} + +type RefundResult struct { + CommonReturn + CommonResult + CommonParam + TransactionId string `xml:"transaction_id,omitempty" json:"transaction_id"` + OutTradeNo string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"` + OutRefundNo string `xml:"out_refund_no,omitempty" json:"out_refund_no,omitempty"` + RefundId string `xml:"refund_id,omitempty" json:"refund_id,omitempty"` + RefundFee int `xml:"refund_fee,omitempty" json:"refund_fee,omitempty"` + SettlementRefundFee int `xml:"settlement_refund_fee,omitempty" json:"settlement_refund_fee,omitempty"` + TotalFee int `xml:"total_fee,omitempty" json:"total_fee,omitempty"` + SettlementTotalFee int `xml:"settlement_total_fee,omitempty" json:"settlement_total_fee,omitempty"` + FeeType string `xml:"fee_type,omitempty" json:"fee_type,omitempty"` + CashFee int `xml:"cash_fee,omitempty" json:"cash_fee,omitempty"` + CashFeeType string `xml:"cash_fee_type,omitempty" json:"cash_fee_type,omitempty"` + CashRefundFee string `xml:"cash_refund_fee,omitempty" json:"cash_refund_fee,omitempty"` + CouponTypeN string `xml:"coupon_type_$n,omitempty" json:"coupon_type_$n,omitempty"` + CouponRefundFee string `xml:"coupon_refund_fee,omitempty" json:"coupon_refund_fee,omitempty"` + CouponRefundFeeN string `xml:"coupon_refund_fee_$n,omitempty" json:"coupon_refund_fee_$n,omitempty"` + CouponRefundCount string `xml:"coupon_refund_count,omitempty" json:"coupon_refund_count,omitempty"` + CouponRefundIdN string `xml:"coupon_refund_id_$n,omitempty" json:"coupon_refund_id_$n,omitempty"` +} + +// ===================================================== 退款申请 + +type RefundQueryParam struct { + CommonParam + XMLName xml.Name `xml:"xml" json:"xml_name,omitempty"` + TransactionId string `xml:"transaction_id,omitempty" json:"transaction_id,omitempty"` + OutTradeNo string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"` + OutRefundNo string `xml:"out_refund_no,omitempty" json:"out_refund_no,omitempty"` + RefundId string `xml:"refund_id,omitempty" json:"refund_id,omitempty"` + Offset int `xml:"offset,omitempty" json:"offset,omitempty"` +} + +type RefundQueryResult struct { + CommonReturn + CommonResult + CommonParam + TransactionId string `xml:"transaction_id,omitempty" json:"transaction_id,omitempty"` + OutTradeNo string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"` + TotalRefundCount int `xml:"total_refund_count,omitempty" json:"total_refund_count,omitempty"` + TotalFee int `xml:"total_fee,omitempty" json:"total_fee,omitempty"` + FeeType string `xml:"fee_type,omitempty" json:"fee_type,omitempty"` + CashFee int `xml:"cash_fee,omitempty" json:"cash_fee,omitempty"` + CashFeeType string `xml:"cash_fee_type,omitempty" json:"cash_fee_type,omitempty"` + SettlementTotalFee int `xml:"settlement_total_fee,omitempty" json:"settlement_total_fee,omitempty"` + RefundCount int `xml:"refund_count,omitempty" json:"refund_count,omitempty"` + OutRefundNoN string `xml:"out_refund_no_$n,omitempty" json:"out_refund_no_$n,omitempty"` + RefundIdN string `xml:"refund_id_$n,omitempty" json:"refund_id_$n,omitempty"` + RefundChannelN string `xml:"refund_channel_$n,omitempty" json:"refund_channel_$n,omitempty"` + RefundFeeN int `xml:"refund_fee_$n,omitempty" json:"refund_fee_$n,omitempty"` + CouponRefundFeeN int `xml:"coupon_refund_fee_$n,omitempty" json:"coupon_refund_fee_$n,omitempty"` + CouponRefundCountN int `xml:"coupon_refund_count_$n,omitempty" json:"coupon_refund_count_$n,omitempty"` + CouponRefundIdNM string `xml:"coupon_refund_id_$n_$m,omitempty" json:"coupon_refund_id_$n_$m,omitempty"` + CouponTypeNM string `xml:"coupon_type_$n_$m,omitempty" json:"coupon_type_$n_$m,omitempty"` + CouponRefundFeeNM int `xml:"coupon_refund_fee_$n_$m,omitempty" json:"coupon_refund_fee_$n_$m,omitempty"` + RefundStatusN string `xml:"refund_status_$n,omitempty" json:"refund_status_$n,omitempty"` + RefundAccountN string `xml:"refund_account_$n" json:"refund_account_$n,omitempty"` + RefundRecvAccoutN string `xml:"refund_recv_accout_$n,omitempty" json:"refund_recv_accout_$n,omitempty"` // 少了n + RefundSuccessTimeN string `xml:"refund_success_time_$n,omitempty" json:"refund_success_time_$n,omitempty"` +} + +// =================================================== 退款查询 + +type RedPackParam struct { + CommonParam + XMLName xml.Name `xml:"xml" json:"xml_name,omitempty"` + Appid string `xml:"wxappid,omitempty" json:"wxappid,omitempty"` // wxappid + MchBillno string `xml:"mch_billno,omitempty" json:"mch_billno,omitempty"` + SendName string `xml:"send_name,omitempty" json:"send_name,omitempty"` + ReOpenid string `xml:"re_openid,omitempty" json:"re_openid,omitempty"` + TotalAmount int `xml:"total_amount,omitempty" json:"total_amount,omitempty"` + TotalNum int `xml:"total_num,omitempty" json:"total_num,omitempty"` + Wishing string `xml:"wishing,omitempty" json:"wishing,omitempty"` + ClientIp string `xml:"client_ip,omitempty" json:"client_ip,omitempty"` + ActName string `xml:"act_name,omitempty" json:"act_name,omitempty"` + Remark string `xml:"remark,omitempty" json:"remark,omitempty"` + SendId string `xml:"send_id,omitempty" json:"send_id,omitempty"` + RiskInfo string `xml:"risk_info,omitempty" json:"risk_info,omitempty"` +} + +type RedPackResult struct { + CommonReturn + CommonResult + MchBillno string `xml:"mch_billno,omitempty" json:"mch_billno,omitempty"` + MchId string `xml:"mch_id,omitempty" json:"mch_id,omitempty"` + Wxappid string `xml:"wxappid,omitempty" json:"wxappid,omitempty"` // wxappid + ReOpenid string `xml:"re_openid,omitempty" json:"re_openid,omitempty"` + TotalAmount int `xml:"total_amount,omitempty" json:"total_amount,omitempty"` + SendListid string `xml:"send_listid,omitempty" json:"send_listid,omitempty"` +} + +type QueryRedPackResult struct { + CommonReturn + CommonResult + MchBillno string `xml:"mch_billno,omitempty" json:"mch_billno,omitempty"` + Mchid string `xml:"mchid,omitempty" json:"mchid,omitempty"` + DetailId string `xml:"detail_id,omitempty" json:"detail_id,omitempty"` + Status string `xml:"status,omitempty" json:"status,omitempty"` + SendType string `xml:"send_type,omitempty" json:"send_type,omitempty"` + HbType string `xml:"hb_type,omitempty" json:"hb_type,omitempty"` + TotalNum int `xml:"total_num,omitempty" json:"total_num,omitempty"` + TotalAmount int `xml:"total_amount,omitempty" json:"total_amount,omitempty"` + Reason string `xml:"reason,omitempty" json:"reason,omitempty"` + SendTime string `xml:"send_time,omitempty" json:"send_time,omitempty"` + RefundTime string `xml:"refund_time,omitempty" json:"refund_time,omitempty"` + RefundAmount int `xml:"refund_amount,omitempty" json:"refund_amount,omitempty"` + Wishing string `xml:"wishing,omitempty" json:"wishing,omitempty"` + Remark string `xml:"remark,omitempty" json:"remark,omitempty"` + ActName string `xml:"act_name,omitempty" json:"act_name,omitempty"` +} diff --git a/libs/wx/pay.go b/libs/wx/pay.go new file mode 100644 index 0000000..4d628d8 --- /dev/null +++ b/libs/wx/pay.go @@ -0,0 +1,272 @@ +package wx + +import ( + "bytes" + "crypto/tls" + "crypto/x509" + "encoding/xml" + "fmt" + "io/ioutil" + "net/http" +) + +func SwitchHost(host string) { + UnifiedOrderURL = fmt.Sprintf("%s/pay/unifiedorder", host) + QueryOrderURL = fmt.Sprintf("%s/pay/orderquery", host) + CloseOrderURL = fmt.Sprintf("%s/pay/closeorder", host) + RefundURL = fmt.Sprintf("%s/pay/refund", host) + RefundQueryURL = fmt.Sprintf("%s/pay/refundquery", host) + TransfersURL = fmt.Sprintf("%s/mmpaymkttransfers/promotion/transfers", host) +} + +type cdata string + +func (c cdata) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + return e.EncodeElement(struct { + string `xml:",cdata"` + }{string(c)}, start) +} + +var _tlsConfig *tls.Config + +//var WxClient = NewClient() + +func getTLSConfig() (*tls.Config, error) { + if _tlsConfig != nil { + return _tlsConfig, nil + } + // load cert + cert, err := tls.LoadX509KeyPair(WxCertPath, WxKeyPath) + if err != nil { + return nil, err + } + // load root ca + caData, err := ioutil.ReadFile(WxCaPath) + if err != nil { + return nil, err + } + pool := x509.NewCertPool() + pool.AppendCertsFromPEM(caData) + _tlsConfig = &tls.Config{ + Certificates: []tls.Certificate{cert}, + RootCAs: pool, + } + return _tlsConfig, nil +} + +type Client struct { + AppId string + MchId string + secureClient *http.Client +} + +//func NewClient() *Client { +// tlsConfig, err := getTLSConfig() +// if err != nil { +// panic(err) // 出现错误 +// } +// tr := &http.Transport{TLSClientConfig: tlsConfig} +// client := &http.Client{Transport: tr} +// return &Client{ +// AppId: Appid, +// MchId: Mchid, +// secureClient: client, +// } +//} + +func (w *Client) Post(url string, xmlRes []byte) (*http.Response, error) { + return w.secureClient.Post(url, "application/xml", bytes.NewBuffer(xmlRes)) +} + +// ======= 支付回调 +func (w *Client) Callback() { + +} + +// ======= 统一下单 +func (w *Client) UnifiedOrder(param *UnifiedOrderParam) (*UnifiedOrderResult, error) { + param.Appid = w.AppId + param.MchId = w.MchId + xmlParam, err := xml.MarshalIndent(param, "", "") + if err != nil { + return nil, err + } + resp, err := w.Post(UnifiedOrderURL, xmlParam) + if err != nil { + return nil, err + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + res := new(UnifiedOrderResult) + err = xml.Unmarshal(body, res) + if err != nil { + return nil, err + } + if res.ReturnCode != CODE_SUCCESS { + return res, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + if res.ResultCode != CODE_SUCCESS { + return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + + return res, nil +} + +// ======= 查询订单 +func (w *Client) QueryOrder(param *QueryOrderParam) (*QueryOrderResult, error) { + param.Appid = w.AppId + param.MchId = w.MchId + xmlParam, err := xml.MarshalIndent(param, "", "") + if err != nil { + return nil, err + } + resp, err := w.Post(QueryOrderURL, xmlParam) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + res := new(QueryOrderResult) + err = xml.Unmarshal(body, res) + if err != nil { + return nil, err + } + if res.ReturnCode != CODE_SUCCESS { + return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + if res.ResultCode != CODE_SUCCESS { + return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + return res, nil +} + +// ======= 关闭订单 +func (w *Client) CloseOrder(param *CloseOrderParam) (*CloseOrderResult, error) { + param.Appid = w.AppId + param.MchId = w.MchId + xmlParam, err := xml.MarshalIndent(param, "", "") + if err != nil { + return nil, err + } + resp, err := w.Post(CloseOrderURL, xmlParam) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + res := new(CloseOrderResult) + err = xml.Unmarshal(body, res) + if err != nil { + return nil, err + } + if res.ReturnCode != CODE_SUCCESS { + return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + if res.ResultCode != CODE_SUCCESS { + return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + + return res, nil +} + +// ======= 申请退款 +func (w *Client) Refund(param *RefundParam) (*RefundResult, error) { + param.Appid = w.AppId + param.MchId = w.MchId + xmlParam, err := xml.MarshalIndent(param, "", "") + if err != nil { + return nil, err + } + resp, err := w.Post(RefundURL, xmlParam) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + res := new(RefundResult) + err = xml.Unmarshal(body, res) + if err != nil { + return nil, err + } + if res.ReturnCode != CODE_SUCCESS { + return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + if res.ResultCode != CODE_SUCCESS { + return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + + return nil, nil +} + +// ======= 查询退款 +func (w *Client) RefundQuery(param *RefundQueryParam) (*RefundQueryResult, error) { + param.Appid = w.AppId + param.MchId = w.MchId + xmlParam, err := xml.MarshalIndent(param, "", "") + if err != nil { + return nil, err + } + resp, err := w.Post(RefundQueryURL, xmlParam) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + res := new(RefundQueryResult) + err = xml.Unmarshal(body, res) + if err != nil { + return nil, err + } + if res.ReturnCode != CODE_SUCCESS { + return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + if res.ResultCode != CODE_SUCCESS { + return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + return res, nil + +} + +// 支付结果通知 +// 支付给用户零钱 + +// 公众号发送红包 +func (w *Client) SendRedPack(param *RedPackParam) (*RedPackResult, error) { + param.Appid = w.AppId + param.MchId = w.MchId + xmlParam, err := xml.MarshalIndent(param, "", "") + if err != nil { + return nil, err + } + resp, err := w.Post(SendRedPackURL, xmlParam) + if err != nil { + return nil, err + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + res := new(RedPackResult) + err = xml.Unmarshal(body, res) + if err != nil { + return nil, err + } + if res.ReturnCode != CODE_SUCCESS { + return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + if res.ResultCode != CODE_SUCCESS { + return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + return res, nil +} diff --git a/libs/wx/wx.go b/libs/wx/wx.go new file mode 100644 index 0000000..b1ae601 --- /dev/null +++ b/libs/wx/wx.go @@ -0,0 +1,151 @@ +package wx + +import ( + "fmt" + "github.com/kirinlabs/HttpRequest" + "github.com/ouxuanserver/osmanthuswine/src/helper" + "net/url" +) + +func GetCodeUrl() string { + uid := helper.CreateUUID() + return fmt.Sprintf(CodeUrl, Appid, url.PathEscape(RedirectUri), uid) +} + +func GetAccessTokenUrl(code string) string { + return fmt.Sprintf(AccessTokenUrl, Appid, Secret, code) +} + +func GetRefreshTokenUrl(refreshToken string) string { + return fmt.Sprintf(RefreshTokenUrl, Appid, refreshToken) +} + +func GetAuthUrl(accessToken string, openid string) string { + return fmt.Sprintf(AuthUrl, accessToken, openid) +} + +func GetUserInfoUrl(accessToken string, openid string) string { + return fmt.Sprintf(UserInfoUrl, accessToken, openid) +} + +func GetTicketUrl(ticketToken string) string { + return fmt.Sprintf(TicketUrl, ticketToken) +} + +func GetTicketTokenUrl() string { + return fmt.Sprintf(TicketTokenUrl, Appid, Secret) +} + +/// + +type Token struct { + AccessToken string `json:"access_token"` + ExpiresIn int64 `json:"expires_in"` + RefreshToken string `json:"refresh_token"` + Openid string `json:"openid"` + Scope string `json:"scope"` + Unionid string `json:"unionid"` +} + +func GetToken(code string) (*Token, error) { + tokenUrl := GetAccessTokenUrl(code) + resp, err := HttpRequest.Get(tokenUrl) + if err != nil { + return nil, err + } + token := new(Token) + err = resp.Json(token) + return token, err +} + +func RefreshToken(refreshToken string) (*Token, error) { + refreshUrl := GetRefreshTokenUrl(refreshToken) + resp, err := HttpRequest.Get(refreshUrl) + if err != nil { + return nil, err + } + token := new(Token) + err = resp.Json(token) + return token, err +} + +type ValidMessage struct { + ErrCode int `json:"err_code"` + ErrMsg string `json:"err_msg"` +} + +func ValidToken(accessToken, openid string) bool { + authUrl := GetAuthUrl(accessToken, openid) + resp, err := HttpRequest.Get(authUrl) + if err != nil { + return false + } + msg := new(ValidMessage) + err = resp.Json(msg) + if err != nil { + return false + } + if msg.ErrCode != 0 { + return false + } + return true +} + +type UserInfo struct { + Openid string `json:"openid"` + Nickname string `json:"nickname"` + Sex int `json:"sex"` + Province string `json:"province"` + City string `json:"city"` + Country string `json:"country"` + Headimgurl string `json:"headimgurl"` + Privilege []string `json:"privilege"` + Unionid string `json:"unionid"` +} + +func GetUserInfo(accessToken, openid string) (*UserInfo, error) { + userInfoUrl := GetUserInfoUrl(accessToken, openid) + resp, err := HttpRequest.Get(userInfoUrl) + if err != nil { + return nil, err + } + userInfo := new(UserInfo) + err = resp.Json(userInfo) + return userInfo, err +} + +type TicketToken struct { + AccessToken string `json:"access_token"` + ExpiresIn int64 `json:"expires_in"` + ErrCode int `json:"err_code"` + ErrMsg string `json:"err_msg"` +} + +func GetTicketToken() (*TicketToken, error) { + tokenUrl := GetTicketTokenUrl() + resp, err := HttpRequest.Debug(true).Get(tokenUrl) + if err != nil { + return nil, err + } + token := new(TicketToken) + err = resp.Json(token) + return token, err +} + +type ApiTicket struct { + ErrCode int `json:"err_code"` + ErrMsg string `json:"err_msg"` + Ticket string `json:"ticket"` + ExpiresIn int64 `json:"expires_in"` +} + +func GetTicket(ticketToken string) (*ApiTicket, error) { + ticketUrl := GetTicketUrl(ticketToken) + resp, err := HttpRequest.Debug(true).Get(ticketUrl) + if err != nil { + return nil, err + } + ticket := new(ApiTicket) + err = resp.Json(ticket) + return ticket, err +} diff --git a/logger/logger.go b/logger/logger.go new file mode 100644 index 0000000..c7cd621 --- /dev/null +++ b/logger/logger.go @@ -0,0 +1,48 @@ +package logger + +import ( + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "gopkg.in/natefinch/lumberjack.v2" + "os" + "time" +) + +var Sugar *zap.SugaredLogger + +func init() { + InitZap() +} +func InitZap() { + w := zapcore.AddSync(&lumberjack.Logger{ + Filename: "log/hdzj.log", + MaxSize: 500, // megabytes + MaxBackups: 3, + MaxAge: 28, // days + }) + core := zapcore.NewCore( + zapcore.NewConsoleEncoder(NewEncoderConfig()), + zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), w), + zap.DebugLevel) + Sugar = zap.New(core, zap.AddCaller()).Sugar() +} +func NewEncoderConfig() zapcore.EncoderConfig { + return zapcore.EncoderConfig{ + // Keys can be anything except the empty string. + TimeKey: "T", + LevelKey: "L", + NameKey: "N", + CallerKey: "C", + MessageKey: "M", + StacktraceKey: "S", + LineEnding: zapcore.DefaultLineEnding, + EncodeLevel: zapcore.CapitalLevelEncoder, + EncodeTime: TimeEncoder, + EncodeDuration: zapcore.StringDurationEncoder, + EncodeCaller: zapcore.ShortCallerEncoder, + } +} + +func TimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString(t.Format("2006-01-02 15:04:05.000")) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..9b39b01 --- /dev/null +++ b/main.go @@ -0,0 +1,78 @@ +package main + +import ( + "hudongzhuanjia/controllers/client" + "hudongzhuanjia/controllers/common" + "hudongzhuanjia/controllers/pc" + _ "hudongzhuanjia/docs" + "runtime" + + "github.com/ouxuanserver/osmanthuswine" + "github.com/ouxuanserver/osmanthuswine/src/core" + "github.com/swaggo/http-swagger" +) + +// @title hudongzhuangjia api +// @version 1.0 +// @description This is a sample server Petstore server. +// @termsOfService http://swagger.io/terms/ + +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io + +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host 172.0.0.1:20181 +// @BasePath /PcClient + +func main() { + // pc + core.GetInstanceRouterManage().Registered(new(pc.WsCtl)) // 用户 + core.GetInstanceRouterManage().Registered(new(pc.UserCtl)) // 用户 + core.GetInstanceRouterManage().Registered(new(pc.ActivityCtl)) // 活动 + core.GetInstanceRouterManage().Registered(new(pc.VoteCtl)) // 投票 + core.GetInstanceRouterManage().Registered(new(pc.AuctionCtl)) // 竞拍 + core.GetInstanceRouterManage().Registered(new(pc.ShakeRedEnvelopeCtl)) // 摇红包 + core.GetInstanceRouterManage().Registered(new(pc.AreaStoreCtl)) // 地区 + core.GetInstanceRouterManage().Registered(new(pc.LotteryDrawCtl)) // 抽奖 + core.GetInstanceRouterManage().Registered(new(pc.SignCtl)) // 签到 + core.GetInstanceRouterManage().Registered(new(pc.BullyScreenCtl)) // 霸屏 + core.GetInstanceRouterManage().Registered(new(pc.RewardCtl)) // 打赏 + core.GetInstanceRouterManage().Registered(new(pc.BarrageCtl)) // 弹幕 + core.GetInstanceRouterManage().Registered(new(pc.UpperWallCtl)) // 上墙 + core.GetInstanceRouterManage().Registered(new(pc.TugOfWarCtl)) // 拔河 + core.GetInstanceRouterManage().Registered(new(pc.OrderDrawCtl)) // 订单抽奖 + core.GetInstanceRouterManage().Registered(new(pc.CalorieCtl)) // 卡路里 + + // client + core.GetInstanceRouterManage().Registered(new(client.ActivityCtl)) // 互动 + core.GetInstanceRouterManage().Registered(new(client.InvitationLetterCtl)) // 邀请函 + core.GetInstanceRouterManage().Registered(new(client.VoteCtl)) // 投票 + core.GetInstanceRouterManage().Registered(new(client.UserCtl)) // 用户 + core.GetInstanceRouterManage().Registered(new(client.UserAuthCtl)) // 登录信息校验 + core.GetInstanceRouterManage().Registered(new(client.SignCtl)) // 签到 + core.GetInstanceRouterManage().Registered(new(client.BullyScreenCtl)) // 霸屏 + core.GetInstanceRouterManage().Registered(new(client.RewardCtl)) // 打赏 + core.GetInstanceRouterManage().Registered(new(client.BarrageCtl)) // 弹幕 + core.GetInstanceRouterManage().Registered(new(client.UpperWallCtl)) // 上墙 + core.GetInstanceRouterManage().Registered(new(client.ShakeRedEnvelopeCtl)) // 摇红包 + core.GetInstanceRouterManage().Registered(new(client.TugOfWarCtl)) // 拔河 + core.GetInstanceRouterManage().Registered(new(client.AuctionCtl)) // 竞拍 + core.GetInstanceRouterManage().Registered(new(client.WxCtl)) // 微信设置 + core.GetInstanceRouterManage().Registered(new(client.OrderEntryCtl)) // 订单 + core.GetInstanceRouterManage().Registered(new(client.LotteryCtl)) // 奖品 + core.GetInstanceRouterManage().Registered(new(client.CalorieCtl)) // 卡路里 + + // common + core.GetInstanceRouterManage().Registered(new(common.AnnexCtl)) + core.GetInstanceRouterManage().Registered(new(common.WeChatOauthCtl)) + + if runtime.GOOS == "windows" { + // swagger + osmanthuswine.GetChiRouter().Get("/swagger/*", httpSwagger.WrapHandler) + } + + osmanthuswine.Run() +} diff --git a/models/CalorieUser.go b/models/CalorieUser.go new file mode 100644 index 0000000..d5fc068 --- /dev/null +++ b/models/CalorieUser.go @@ -0,0 +1,36 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const CalorieUserTableName = TableNamePrefix + "calorie_user" + +type CalorieUser struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('互动id') INT(11)"` + Avatar string `json:"avatar" xorm:"-"` + Nickname string `json:"nickname" xorm:"-"` + UserId int64 `json:"user_id" xorm:"not null comment('用户表id') INT(11)"` + CalorieId int64 `json:"calorie_id" xorm:"not null comment('calorie表id') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id') INT(11)"` + Score int64 `json:"score" xorm:"not null default(0) comment('分数') INT(11)"` + JoinTime int64 `json:"join_time" xorm:"not null default('0') comment('加入时间纳秒') VARCHAR(128)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null default(CURRENT_TIMESTAMP) updated comment('创建时间') TIMESTAMP"` +} + +func (t *CalorieUser) TableName() string { + return CalorieUserTableName +} + +func (t *CalorieUser) GetByCalorieIdAndUserId(cid, uid, rid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and calorie_id=? and user_id=? and rehearsal_id=?", cid, uid, rid).Get(t) +} + +func (t *CalorieUser) IncrScore(score int) (int64, error) { + t.JoinTime = time.Now().UnixNano() + return core.GetXormAuto().Where("is_delete=0 and id=?", t.Id).Cols("score", "join_time").Incr("score", score).Update(t) +} diff --git a/models/activity.go b/models/activity.go new file mode 100644 index 0000000..c71c829 --- /dev/null +++ b/models/activity.go @@ -0,0 +1,47 @@ +package models + +import ( + "time" +) + +const ActivityTableName = TableNamePrefix + "activity" + +//互动活动 +type Activity struct { + Id int64 `json:"id" xorm:"pk autoincr INT(11)"` + CustomerId int64 `json:"customer_id" xorm:"not null default(0) comment('customer_id, 创建客户id') INT(11)"` + Services []*ActivityModuleService `json:"services,omitempty" xorm:"-" description:"主活动下的服务"` + AreaStores []*AreaStore `json:"area_stores,omitempty" xorm:"-" description:"地区"` + BarrageStatus string `json:"barrage_status,omitempty" xorm:"-" description:"弹幕服务状态"` + BullyScreenStatus string `json:"bully_screen_status,omitempty" xorm:"-" description:"霸屏状态"` + RewardStatus string `json:"reward_status,omitempty" xorm:"-" description:"打赏状态"` + UpperWallStatus string `json:"upper_wall_status,omitempty" xorm:"-" description:"上墙状态"` + Name string `json:"name" xorm:"not null comment('主活动名字') VARCHAR(255)"` + Classification string `json:"classification" xorm:"not null comment('互动分类') VARCHAR(255)"` + Status string `json:"status" xorm:"not null default('未开始') comment('状态[未开始,进行中,已结束]') VARCHAR(128)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('0正式、1彩排中的id') INT(11)"` + Province string `json:"province" xorm:"not null default('') comment('省') VARCHAR(128)" description:"省"` + City string `json:"city" xorm:"not null default('') comment('省') VARCHAR(128)" description:"市"` + StartTime time.Time `json:"start_time" xorm:"not null default('1970-01-01 08:00:00') comment('互动开始时间') DATETIME"` + EndTime time.Time `json:"end_time" xorm:"not null default('1970-01-01 08:00:00') comment('互动开始时间') DATETIME"` + PublicAccount string `json:"public_account" xorm:"not null default('') comment('公众号') VARCHAR(255)" description:"公众账号"` + ContactNumber string `json:"contact_number" xorm:"not null default('') comment('联系方式') VARCHAR(255)" description:"联系电话"` + EstimatedNum int `json:"estimated_num" xorm:"not null default(0) comment('预计与会人数') INT(11)" description:"预计人数"` + HdMode string `json:"hd_mode" xorm:"not null default('') comment('互动模式') VARCHAR(128)"` + MoreAreaMode string `json:"more_area_mode" xorm:"not null default('关闭') comment('多地区模式[开启,关闭]') VARCHAR(255)" description:"多地区模式[开启,关闭]"` + PhoneBgUrl string `json:"phone_bg_url" xorm:"not null default('') comment('手机通用背景') VARCHAR(255)"` + PhoneBgSwitch string `json:"phone_bg_switch" xorm:"not null default('关闭') comment('手机通用背景开关') VARCHAR(255)"` + MaxBgUrl string `json:"max_bg_url" xorm:"not null default('') comment('大屏通用背景') VARCHAR(255)" description:"大屏通用背景"` + MaxBgSwitch string `json:"max_bg_switch" xorm:"not null default('关闭') comment('大屏通用背景开关')" description:"大屏通用背景开关"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('删除') TINYINT(1)" description:"删除"` + CreatedAt time.Time `json:"-" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"` +} + +func (t *Activity) TableName() string { + return ActivityTableName +} + +func (t *Activity) Alias(name string) string { + return AliasTableName(t, name) +} diff --git a/models/activity_module_service.go b/models/activity_module_service.go new file mode 100644 index 0000000..5473e8f --- /dev/null +++ b/models/activity_module_service.go @@ -0,0 +1,50 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +const ActivityModuleServiceTableName = TableNamePrefix + "activity_module_service" + +//活动模块服务 +type ActivityModuleService struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动id') INT(11)"` + ServiceModuleHistoryId int64 `json:"service_module_history_id" xorm:"not null comment('service_module_history表id') INT(11)"` + ServiceModuleName string `json:"service_module_name" xorm:"-" description:"模块服务名字"` + ServiceModuleStatus string `json:"service_module_status" xorm:"not null default('关闭') comment('服务模块 免费开启。付费默认关闭。') VARCHAR(128)"` + PhoneBgUrl string `json:"phone_bg_url" xorm:"not null default('') comment('服务模块的自定义手机屏的图片') VARCHAR(255)"` + PhoneBgSwitch string `json:"phone_bg_switch" xorm:"not null default('关闭') comment('模块手机的开关 开启|关闭') VARCHAR(11)"` + MaxBgUrl string `json:"max_bg_url" xorm:"not null default('') comment('服务模块的自定义大屏的图片') VARCHAR(255)"` + MaxBgSwitch string `json:"max_bg_switch" xorm:"not null default('关闭') comment('模块大屏的开关 开启|关闭') VARCHAR(11)"` + ModuleStyleId int64 `json:"module_style_id" xorm:"not null default(0) comment('每个模块对应的一个样式id 如果有的话') INT(11)"` + BesideRepeat string `json:"beside_repeat" xorm:"not null default('不去除') comment('是否去除重复') VARCHAR(11)"` + ServiceModuleStartTime time.Time `json:"service_module_start_time" xorm:"not null default('1970-01-01 08:00:00') comment('服务开始时间') DATETIME"` + ServiceModuleEndTime time.Time `json:"service_module_end_time" xorm:"not null default('1970-01-01 08:00:00') comment('服务结束时间') DATETIME"` + MoreAreaMode string `json:"more_area_mode" xorm:"not null default('关闭') comment('多地区模式录入人员用到') VARCHAR(11)"` + OrderDrawStatus string `json:"order_draw_status" xorm:"not null default('关闭') comment('订单抽奖开关[开启|关闭]') VARCHAR(11)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"` +} + +/** + * 获取手机和大屏的背景图: + * 通过主活动的id定位activity_module_service的所有service_module_history_id, + * 所有service_module_history_id in module_service_history,并且 模块名=module_service_history.name + * 通过定位出来的activity_module_service检查是否手机和大屏的背景图状态,开启则从ui_base获取,否则直接从activity_module_service + */ + +func (t *ActivityModuleService) TableName() string { + return ActivityModuleServiceTableName +} + +func (t *ActivityModuleService) Alias(name string) string { + return AliasTableName(t, name) +} + +func (t *ActivityModuleService) GetByActivityIdAndHistoryId(aid, hid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and service_module_history_id=?", aid, hid).Get(t) +} diff --git a/models/annex.go b/models/annex.go new file mode 100644 index 0000000..ba2b368 --- /dev/null +++ b/models/annex.go @@ -0,0 +1,23 @@ +package models + +import ( + "time" +) + +const AnnexTableName = TableNamePrefix + "annex" + +//附件 +type Annex struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + Path string `json:"path" xorm:"not null comment('路径') VARCHAR(255)"` + Size int64 `json:"size" xorm:"not null comment('文件得大小') INT(11)"` + Suffix string `json:"suffix" xorm:"not null comment('文件得后缀') VARCHAR(255)"` + Md5 string `json:"md5" xorm:"not null comment('文件得md5值') VARCHAR(255)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建得时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新得时间') DATETIME"` +} + +func (t *Annex) TableName() string { + return AnnexTableName +} diff --git a/models/area_store.go b/models/area_store.go new file mode 100644 index 0000000..4f0d658 --- /dev/null +++ b/models/area_store.go @@ -0,0 +1,40 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +const AreaStoreTableName = TableNamePrefix + "area_store" + +//店铺地区 +type AreaStore struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + Name string `json:"name" xorm:"not null default('') comment('名字') VARCHAR(255)"` + Type string `json:"type" xorm:"not null default('') comment('地区类型') VARCHAR(255)"` + Address string `json:"address" xorm:"not null default('') comment('地址') VARCHAR(255)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动id') BIGINT(20)"` + IsMainArea bool `json:"is_main_area" xorm:"not null default(0) comment('是否主地区1是') TINYINT(1)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *AreaStore) TableName() string { + return AreaStoreTableName +} + +func (t *AreaStore) GetAreaStoreById(id int64) (bool, error) { + return core.GetXormAuto().Where("id=? and is_delete=0", id).Get(t) +} + +func (t *AreaStore) GetMainAreaById(aid int64) (bool, error) { + return core.GetXormAuto().Where("activity_id=? and is_main_area=1 and is_delete=0", aid).Get(t) +} + +func GetAreaStoresByActivityId(aid int64) ([]*AreaStore, error) { + list := make([]*AreaStore, 0) + err := core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid).Find(&list) + return list, err +} diff --git a/models/auction_activity.go b/models/auction_activity.go new file mode 100644 index 0000000..5b06817 --- /dev/null +++ b/models/auction_activity.go @@ -0,0 +1,15 @@ +package models + +//竞拍活动 +//type AuctionActivity struct { +// Id int64 `json:"id"` +// ActivityId int64 `json:"activity_id" description:"活动的id"` +// AuctionActivityName string `json:"auction_activity_name" description:"竞拍名称"` +// LatestMoney float64 `json:"latest_price" xorm:"-" description:"最新的竞拍叫价,通过查询AuctionHistory获得"` +// MaxMoney float64 `json:"max_price" xorm:"-" description:"目前最高叫价,通过查询AuctionHistory获得"` +// MinMoney float64 `json:"min_price" xorm:"-" description:"目前最低叫价,通过查询AuctionHistory获得"` +// AuctionRule *AuctionRule `json:"auction_rule" xorm:"-" description:"竞拍规则,通过查询AuctionRule获得"` +// IsDelete bool `json:"is_delete" xorm:"default(0)"` +// CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +//} diff --git a/models/auction_deal.go b/models/auction_deal.go new file mode 100644 index 0000000..8a4db8e --- /dev/null +++ b/models/auction_deal.go @@ -0,0 +1,13 @@ +package models + +//竞拍成交 +//type AuctionDeal struct { +// Id int64 `json:"id"` +// RuleId int64 `json:"rule_id" description:"规则id"` +// PlayerCode int `json:"player_code" description:"竞拍参与者号码"` +// DealMoney float64 `json:"deal_money" description:"成交的金额"` +// IsPay bool `json:"is_pay" description:"是否支付"` +// IsDelete bool `json:"is_delete" xorm:"default(0)"` +// CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +//} diff --git a/models/auction_history.go b/models/auction_history.go new file mode 100644 index 0000000..67d0937 --- /dev/null +++ b/models/auction_history.go @@ -0,0 +1,63 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +const AuctionHistoryTableName = TableNamePrefix + "auction_history" + +//竞拍历史 +type AuctionHistory struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + UserId int64 `json:"user_id" xorm:"not null comment('用户表id') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null comment('彩排id, 0是正式') INT(11)"` + PlayerId int64 `json:"player_id" xorm:"not null comment('竞拍者id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('互动id') INT(11)"` + AreaId int64 `json:"area_id" xorm:"not null comment('地区id') INT(11)"` + AreaName string `json:"area_name" xorm:"not null comment('地区名字') VARCHAR(128)"` + UserName string `json:"user_name" xorm:"not null comment('用户名') VARCHAR(128)"` + UserPhone string `json:"user_phone" xorm:"not null comment('用户手机') VARCHAR(128)"` + AuctionGoodsName string `json:"auction_goods_name" xorm:"not null comment('竞拍商品名字') VARCHAR(255)"` + AuctionActivityId int64 `json:"auction_activity_id" xorm:"not null comment('竞拍活动id') INT(11)"` + PlayerCode int64 `json:"player_code" xorm:"not null comment('竞拍参与者号码') INT(11)"` + Unit int `json:"unit" xorm:"not null default(1) comment('单位') TINYINT(1)"` + Money float64 `json:"money" xorm:"not null comment('计算总价格') DECIMAL(20)"` + Version int `json:"version" xorm:"not null default(0) version comment('乐观锁') INT(11)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *AuctionHistory) TableName() string { + return AuctionHistoryTableName +} + +func (t *AuctionHistory) GetHighestMoney(rid, aid int64) (bool, error) { + return core.GetXormAuto().Where("auction_activity_id = ? and rehearsal_id=? and is_delete=0", aid, rid). + Desc("money").Asc("updated_at").Get(t) +} + +func (t *AuctionHistory) CountHistory(rid, aid int64) (int64, error) { + return core.GetXormAuto().Where("auction_activity_id = ? and rehearsal_id=? and is_delete=0", aid, rid).Count(t) +} + +func GetAuctionHistoriesByAuctionId(aid, rid int64, orderBy string) ([]*AuctionHistory, error) { + histories := make([]*AuctionHistory, 0) + err := core.GetXormAuto().Where("is_delete=0 and auction_activity_id=? and rehearsal_id=?", aid, rid). + OrderBy(orderBy).Find(&histories) + return histories, err +} + +func GetAuctionHistoriesByAuctionIds(ids []int64, rid int64, orderBy string) ([]*AuctionHistory, error) { + histories := make([]*AuctionHistory, 0) + err := core.GetXormAuto().Where("is_delete=0 and rehearsal_id=?", rid). + In("auction_activity_id", ids).OrderBy(orderBy).Find(&histories) + return histories, err +} + +func (t *AuctionHistory) SoftDelete() (int64, error) { + t.IsDelete = true + return core.GetXormAuto().Id(t.Id).Cols("is_delete").Update(t) +} diff --git a/models/auction_player.go b/models/auction_player.go new file mode 100644 index 0000000..d7e70db --- /dev/null +++ b/models/auction_player.go @@ -0,0 +1,29 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const AuctionPlayerTableName = TableNamePrefix + "auction_player" + +//竞拍者 +type AuctionPlayer struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + AuctionActivityId int64 `json:"auction_activity_id" xorm:"not null comment('竞拍活动id') INT(11)"` + UserId int64 `json:"user_id" xorm:"not null comment('客户的id') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id, 0正式数据') INT(11)"` + Code int64 `json:"code" xorm:"not null comment('竞拍参与人的代号') INT(11)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(0)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *AuctionPlayer) TableName() string { + return AuctionPlayerTableName +} + +func (t *AuctionPlayer) GetByAuctionIdAndUid(aid, uid, rid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and auction_activity_id=? and user_id=? and rehearsal_id=?", + aid, uid, rid).Get(t) +} diff --git a/models/auction_result_record.go b/models/auction_result_record.go new file mode 100644 index 0000000..69dec79 --- /dev/null +++ b/models/auction_result_record.go @@ -0,0 +1,42 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const AuctionResultRecordTableName = TableNamePrefix + "auction_result_record" + +type AuctionResultRecord struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default(0) comment('主活动id') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('0正式/!0彩排id') INT(11)"` // 增加彩排功能 + AuctionActivityId int64 `json:"auction_activity_id" xorm:"not null comment('竞拍活动id') INT(11)"` + AreaId int64 `json:"area_id" xorm:"not null default('0') comment('地区id') INT(11)"` + AreaName string `json:"area_name" xorm:"not null default('') comment('地区名字') VARCHAR(255)"` + UserId int64 `json:"user_id" xorm:"not null comment('用户id') INT(11)"` + UserName string `json:"user_name" xorm:"not null comment('用户名字') VARCHAR(255)"` + UserPhone string `json:"user_phone" xorm:"not null comment('用户手机号码') VARCHAR(128)"` + PlayerCode int64 `json:"player_code" xorm:"not null default(0) comment('竞拍编号') INT(11)"` + AuctionGoodsName string `json:"auction_goods_name" xorm:"not null comment('商品名字') VARCHAR(255)"` + DealPrice float64 `json:"deal_price" xorm:"not null comment('成交价格') DECIMAL(20)"` + Unit int `json:"unit" xorm:"not null default(1) comment('单位') TINYINT(1)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *AuctionResultRecord) TableName() string { + return AuctionResultRecordTableName +} + +func (t *AuctionResultRecord) CountHistory(rid, aid int64) (int64, error) { + return core.GetXormAuto().Where("auction_activity_id=? and rehearsal_id=? and is_delete=0", aid, rid).Count(t) +} + +func GetAuctionRecordsByAuctionId(id, rid int64, orderBy string) ([]*AuctionResultRecord, error) { + records := make([]*AuctionResultRecord, 0) + err := core.GetXormAuto().Where("is_delete=0 and rehearsal_id=? and auction_activity_id=?", rid, id). + OrderBy(orderBy).Find(&records) + return records, err +} diff --git a/models/auction_rule.go b/models/auction_rule.go new file mode 100644 index 0000000..245896d --- /dev/null +++ b/models/auction_rule.go @@ -0,0 +1,28 @@ +package models + +//const AuctionRuleTableName = TableNamePrefix + "auction_rule" +// +////竞拍规则 +//type AuctionRule struct { +// Id int64 `json:"id"` +// AuctionActivityId int64 `json:"auction_activity_id" description:"竞拍轮次的id, 对应auction_activity表的主键id"` +// AuctionTime int64 `json:"auction_time" description:"竞拍持续时间 秒为单位"` +// AuctionStatus string `json:"auction_status" description:"竞拍活动状态 [可竞拍,不可竞拍]"` +// AreaId int64 `json:"area_id" description:"地区id"` +// AreaStatus string `json:"area_status" description:"多地区模式[开启,关闭]"` +// AuctionGoodsName string `json:"auction_goods_name" description:"竞拍物品名称"` +// AuctionGoodsDesc string `json:"auction_goods_desc" description:"竞拍物品描述"` +// StartPrice float64 `json:"start_price" description:"起始价格"` +// Model string `json:"model" description:"[加价竞拍,减价竞拍]"` +// Pic string `json:"pic" description:"竞拍图片"` +// BaseInterval float64 `json:"base_interval" description:"基础区间"` +// Threshold float64 `json:"threshold" description:"活动结束阀值"` +// UseTimes int64 `json:"use_times" description:"使用次数"` +// IsDelete bool `json:"is_delete" xorm:"is_delete" description:"是否删除"` +// CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +//} +// +//func (t *AuctionRule) TableName() string { +// return AuctionRuleTableName +//} diff --git a/models/bahe_activity.go b/models/bahe_activity.go new file mode 100644 index 0000000..f30adc1 --- /dev/null +++ b/models/bahe_activity.go @@ -0,0 +1,19 @@ +package models + +//拔河比赛活动 +//type BaheActivity struct { +// Id int64 `json:"id"` +// ActivityId int64 `json:"activity_id" description:"活动的id"` +// BaheActivityName string `json:"bahe_activity_name" description:"拔河名称"` +// RandomTeam string `json:"random_team" description:"[开启,关闭]随机组队模式"` +// MaxMoreCode string `json:"max_more_code" description:"[开启,关闭]大屏多二维码模式"` +// H5Choose string `json:"h_5_choose" description:"[开启,关闭]h5挑选队伍"` +// BaheActivityStatus string `json:"bahe_activity_status" description:"拔河活动状态[未开始,进行中,结束]"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +//} + +//func (b *BaheActivity) GetBaheActivityById(id int64) (bool, error) { +// return core.GetXormAuto().Where("id=? and is_delete=?", id, false).Get(b) +//} diff --git a/models/bahe_history.go b/models/bahe_history.go new file mode 100644 index 0000000..cf7e1b4 --- /dev/null +++ b/models/bahe_history.go @@ -0,0 +1,18 @@ +package models + +//const BaheHistoryTableName = TableNamePrefix + "bahe_history" +// +////拔河的比赛结果的记录 +//type BaheHistory struct { +// Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` +// ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动的id') INT(11)"` +// WinnerId int64 `json:"winner_id" xorm:"not null comment('胜利队伍id') INT(11)"` +// MatchRes string `json:"match_res" xorm:"not null comment('比赛结果信息,[team_id=>人数,...]') INT(11)"` +// IsDelete bool `json:"is_delete" xorm:"default(0)"` +// CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +//} +// +//func (t *BaheHistory) TableName() string { +// return BaheHistoryTableName +//} diff --git a/models/bahe_rule.go b/models/bahe_rule.go new file mode 100644 index 0000000..b0dd53c --- /dev/null +++ b/models/bahe_rule.go @@ -0,0 +1,16 @@ +package models + +//拔河规则 +//type BaheRule struct { +// Id int64 `json:"id"` +// BaheActivityId int64 `json:"bahe_activity_id" description:"拔河轮次的id, 对应bahe_activity的主键id"` +// AreaId int64 `json:"area_id" description:"地区id"` +// RandomTeam string `json:"random_team" description:"[开启,关闭]随机组队模式"` +// MaxMoreCode string `json:"max_more_code" description:"[开启,关闭]大屏多二维码模式"` +// H5Choose string `json:"h_5_choose" description:"[开启,关闭]h5挑选队伍"` +// BaheStatus string `json:"bahe_status" description:"拔河活动状态[未开始,进行中,结束]"` +// UseTimes int64 `json:"use_times" description:"使用次数"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +//} diff --git a/models/bahe_team.go b/models/bahe_team.go new file mode 100644 index 0000000..a4cb27c --- /dev/null +++ b/models/bahe_team.go @@ -0,0 +1,31 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const BaheTeamTable = TableNamePrefix + "bahe_team" + +//拔河队伍 +type BaheTeam struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('活动id') INT(11)"` + BaheActivityId int64 `json:"bahe_activity_id" xorm:"not null comment('拔河活动id') INT(11) "` + BaheTeamName string `json:"bahe_team_name" xorm:"not null comment('拔河队伍得名称') VARCHAR(255)"` + TotalScore int64 `json:"total_score" xorm:"-" description:"总分数"` + Rank int `json:"rank" xorm:"-" description:"排名"` + Members []*BaheTeamMember `json:"members" xorm:"-" description:"队伍人数"` + Qrcode string `json:"qrcode" xorm:"-" description:"二维码"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否已删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *BaheTeam) TableName() string { + return BaheTeamTable +} + +func (t *BaheTeam) GetOtherTeam(id, bid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and id=? and bahe_activity_id=?", id, bid).Get(t) +} diff --git a/models/bahe_team_member.go b/models/bahe_team_member.go new file mode 100644 index 0000000..bb56dba --- /dev/null +++ b/models/bahe_team_member.go @@ -0,0 +1,43 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +const BaheTeamMemberTableName = TableNamePrefix + "bahe_team_member" + +//拔河队伍人员 +type BaheTeamMember struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + BaheActivityId int64 `json:"bahe_activity_id" xorm:"not null default(0) comment('拔河活動id') BIGINT(20)"` + TeamId int64 `json:"team_id" xorm:"not null default(0) comment('队伍id') BIGINT(20)"` + TeamName string `json:"team_name" xorm:"not null default('') comment('队伍名字') VARCHAR(255)"` + MemberId int64 `json:"member_id" xorm:"not null comment('用户id') BIGINT(20)"` + Score int64 `json:"score" xorm:"not null default(0) comment('分数') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id/0正式') BIGINT(20)"` + Avatar string `json:"avatar" xorm:"not null comment('头像') VARCHAR(255)"` + NickName string `json:"nick_name" xorm:"not null comment('昵称') VARCHAR(255)"` + SortTime int64 `json:"sort_time" xorm:"not null default '0' comment('排序时间') VARCHAR(20)"` + IsDelete bool `json:"-" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"-" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"-" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *BaheTeamMember) TableName() string { + return BaheTeamMemberTableName +} + +func (t *BaheTeamMember) Alias(name string) string { + return AliasTableName(t, name) +} + +func (t *BaheTeamMember) GetMemberByBaheIdAndUserId(uid, bid, rid int64) (bool, error) { + return core.GetXormAuto().Where("member_id=? and bahe_activity_id=? and rehearsal_id=? and is_delete=0", uid, bid, rid).Get(t) +} + +func (t *BaheTeamMember) IncrScoreById(id, score int64) (int64, error) { + t.SortTime = time.Now().UnixNano() + return core.GetXormAuto().Id(id).Incr("score", score).Cols("score, sort_time").Update(t) +} diff --git a/models/barrage_history.go b/models/barrage_history.go new file mode 100644 index 0000000..1b8f3cf --- /dev/null +++ b/models/barrage_history.go @@ -0,0 +1,22 @@ +package models + +import ( + "time" +) + +const BarrageHistoryTableName = TableNamePrefix + "barrage_history" + +//弹幕历史记录 +type BarrageHistory struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动得id') INT(11)"` + UserId int64 `json:"user_id" xorm:"not null comment('用户得id') INT(11)"` + Content string `json:"content" xorm:"not null comment('内容') TEXT"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreateAt time.Time `json:"create_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdateAt time.Time `json:"update_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *BarrageHistory) TableName() string { + return BarrageHistoryTableName +} diff --git a/models/base.go b/models/base.go new file mode 100644 index 0000000..cdf2d3e --- /dev/null +++ b/models/base.go @@ -0,0 +1,67 @@ +package models + +import ( + "fmt" + "reflect" + "strings" + + "github.com/ouxuanserver/osmanthuswine/src/core" + "github.com/xormplus/xorm" +) + +func Condition(condition map[string]interface{}) *xorm.Session { + session := core.GetXormAuto().NewSession() + for k, v := range condition { + if strings.Contains(k, " not in") { + session = session.NotIn(strings.TrimRight(k, " not in"), v) + } else if strings.Contains(k, " in") { + session = session.In(strings.TrimRight(k, " in"), v) + } else if strings.HasPrefix(strings.ToLower(k), "order by") { + session = session.OrderBy(v.(string)) + } else if strings.HasSuffix(k, "<") || strings.HasSuffix(k, ">") || + strings.HasSuffix(k, "<=") || strings.HasSuffix(k, ">=") || + strings.HasSuffix(k, "<>") || strings.HasSuffix(k, "=") || + strings.HasSuffix(k, "!=") { + session = session.Where(fmt.Sprintf("%s?", k), v) + } else { + session = session.Where(fmt.Sprintf("%s=?", k), v) + } + } + return session +} + +func Save(condition map[string]interface{}, obj interface{}, filed ...string) error { + session := Condition(condition) + defer session.Close() + if condition != nil && Exit(session.Clone(), reflect.New(reflect.TypeOf(obj).Elem()).Interface()) { + //存在则更新 + _, err := session.Cols(filed...).Update(obj) + return err + } else { + //不存在则插入 + _, err := session.InsertOne(obj) + return err + } +} + +func Exit(session *xorm.Session, obj interface{}) (result bool) { + defer session.Close() + result, _ = session.Exist(obj) + return result +} + +func GetTableName(bean interface{}) string { + if table, ok := bean.(string); ok { + return table + } + return core.GetXormAuto().TableInfo(bean).Name +} + +func AliasTableName(bean interface{}, alias string) string { + tn := GetTableName(bean) + return fmt.Sprintf("%s as %s", tn, alias) +} + +func GetById(bean interface{}, id int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and id=?", id).Get(bean) +} diff --git a/models/bully_screen_history.go b/models/bully_screen_history.go new file mode 100644 index 0000000..702eaec --- /dev/null +++ b/models/bully_screen_history.go @@ -0,0 +1,43 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const BullyScreenHistoryTableName = TableNamePrefix + "bully_screen_history" + +//霸屏历史表 +type BullyScreenHistory struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + BullyScreenServerId int64 `json:"bully_screen_server_id" xorm:"not null comment('霸屏服务得id') INT(11)"` + UserOrderId int64 `json:"user_order_id" xorm:"not null default 0 comment('微信统一下订单id') INT(11)"` + CustomerId int64 `json:"customer_id" xorm:"not null comment('客户id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('互动id') INT(11)"` + UserId int64 `json:"user_id" xorm:"not null comment('用户得id') INT(11)"` + Nickname string `json:"nickname" xorm:"not null default('') comment('发送者昵称') VARCHAR(128)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id/ 0是正式') INT(11)"` + Style int `json:"style" xorm:"not null comment('服务样式') INT(11)"` + Second int `json:"second" xorm:"not null comment('霸屏时间(秒)') INT(11)"` + Content string `json:"content" xorm:"not null comment('内容') TEXT"` + Status int `json:"status" xorm:"not null default(0) comment('[-1未支付,0未审核,1未通过,2已通过, 3已推送]') INT(11)"` + Amount float64 `json:"amount" xorm:"not null default 0.00 comment('霸屏金额') DECIMAL(10)"` + ReviewTime int64 `json:"review_time" xorm:"not null comment('审核的时间') INT(11)"` + Version int64 `json:"version" xorm:"not null version comment('乐观锁') INT(11)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *BullyScreenHistory) TableName() string { + return BullyScreenHistoryTableName +} + +func (t *BullyScreenHistory) GetByUserOrderId(userOrderId int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrderId).Get(t) +} + +func (t *BullyScreenHistory) UpdateStatus(id int64, status int) (int64, error) { + t.Status = status + return core.GetXormAuto().Id(id).Cols("status").Update(t) +} diff --git a/models/bully_screen_server.go b/models/bully_screen_server.go new file mode 100644 index 0000000..dce808a --- /dev/null +++ b/models/bully_screen_server.go @@ -0,0 +1,34 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const BullyScreenServerTableName = TableNamePrefix + "bully_screen_server" + +//霸屏服务 +type BullyScreenServer struct { + Id int64 `json:"id"` + ActivityId int64 `json:"activity_id" description:"主活动的id"` + ServerStartTime time.Time `json:"server_start_time" description:"服务开始时间"` + ServerEndTime time.Time `json:"server_end_time" description:"服务结束时间"` + Start string `json:"start" description:"霸屏是否开启 [开启|关闭]"` + ServerDisplay string `json:"server_display" description:"霸屏展示的方式 [消息界面|互动界面]"` + Price float64 `json:"price" description:"每秒的价格 霸屏"` + IsDelete bool `json:"is_delete" xorm:"is_delete"` + CreatedAt time.Time `json:"created_at" xorm:"created"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated"` +} + +func (t *BullyScreenServer) TableName() string { + return BullyScreenServerTableName +} + +func (t *BullyScreenServer) Alias(name string) string { + return AliasTableName(t, name) +} + +func (t *BullyScreenServer) GetByActivityId(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid).Get(t) +} diff --git a/models/bully_screen_wallet.go b/models/bully_screen_wallet.go new file mode 100644 index 0000000..519ae44 --- /dev/null +++ b/models/bully_screen_wallet.go @@ -0,0 +1,24 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const BSWalletTableName = TableNamePrefix + "bully_screen_wallet" + +type BullyScreenWallet struct { + Id int64 `json:"id"` + CustomerId int64 `json:"customer_id"` + Balance float64 `json:"balance"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +func (t *BullyScreenWallet) TableName() string { + return BSWalletTableName +} + +func (t *BullyScreenWallet) IncrBalance(cid int64, money float64) (int64, error) { + return core.GetXormAuto().Where("customer_id=?", cid).Incr("balance", money).Update(t) +} diff --git a/models/bully_screen_wallet_hisotry.go b/models/bully_screen_wallet_hisotry.go new file mode 100644 index 0000000..0a8a6c3 --- /dev/null +++ b/models/bully_screen_wallet_hisotry.go @@ -0,0 +1,25 @@ +package models + +import "time" + +const BSWalletHistoryTableName = TableNamePrefix + "bully_screen_wallet_history" + +type BullyScreenWalletHistory struct { + Id int64 `json:"id" xorm:"not null autoincr pk INT(11)"` + CustomerId int64 `json:"customer_id" xorm:"not null default 0 comment('客户表id') INT(11)"` + UserId int64 `json:"customer_id" xorm:"not null default 0 comment('客户表id') INT(11)"` + Money float64 `json:"money" xorm:"not null default 0.00 comment('金额[分正负]') DECIMAL(10)"` + HisBalance string `json:"his_balance" xorm:"not null default '0' comment('历史霸屏余额') VARCHAR(128)"` + Type string `json:"type" xorm:"not null default '' comment('记录类型 霸屏/提现') VARCHAR(128)"` + BullyScreenUsername string `json:"bully_screen_username" xorm:"not null default '' comment('发起霸屏的那个用户的用户名') VARCHAR(128)"` + BullyScreenAccount string `json:"bully_screen_account" xorm:"not null default '' comment('支付霸屏的账户 只支持支付宝或微信') VARCHAR(128)"` + CashDrawId int64 `json:"cash_draw_id" xorm:"not null default 0 comment('cash_draw提现表id') INT(11)"` + Status string `json:"status" xorm:"not null default '交易成功' comment('交易状态') VARCHAR(128)"` + Mark string `json:"mark" xorm:"not null comment('备注') TEXT"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated default 'CURRENT_TIMESTAMP' comment('更新时间') TIMESTAMP"` +} + +func (t *BullyScreenWalletHistory) TableName() string { + return BSWalletHistoryTableName +} diff --git a/models/calorie.go b/models/calorie.go new file mode 100644 index 0000000..a8fe911 --- /dev/null +++ b/models/calorie.go @@ -0,0 +1,47 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/utils/define" + "time" +) + +const CalorieTableName = TableNamePrefix + "calorie" + +type Calorie struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('互动id') INT(11)"` + GameDuration int64 `json:"game_duration" xorm:"not null default(60) comment('游戏时长秒') INT(11)"` + StartTime int64 `json:"start_time" xorm:"not null default(0) comment('游戏开始时间') INT(11)"` + Status string `json:"status" xorm:"not null default('未开始') comment('状态[未开始,准备中,进行中,已结束]') VARCHAR(11)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null default(CURRENT_TIMESTAMP) updated TIMESTAMP"` +} + +func (t *Calorie) TableName() string { + return CalorieTableName +} + +func (t *Calorie) UpdateToStatusByActivityId(aid int64, before, after string) (int64, error) { + t.Status = after + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and status=? and activity_id=?", before, aid). + Cols("status", "updated_at").Update(t) +} + +func (t *Calorie) UpdateStatusById(id int64, status string) (int64, error) { + t.Status = status + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and id=?", id).Cols("status", "start_time", "updated_at").Update(t) +} + +func (t *Calorie) GetCurrent(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and (status=? or status=?)", + aid, define.StatusReady, define.StatusRunning).Desc("created_at").Get(t) +} + +func UpdateCalorieStatusByActivityId(aid int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid). + Update(&Calorie{Status: define.StatusNotBegin}) +} diff --git a/models/customer.go b/models/customer.go new file mode 100644 index 0000000..e06ca7b --- /dev/null +++ b/models/customer.go @@ -0,0 +1,71 @@ +package models + +import ( + "errors" + "fmt" + "hudongzhuanjia/logger" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" + "github.com/ouxuanserver/osmanthuswine/src/helper" +) + +const CustomerTableName = TableNamePrefix + "customer" + +//客户表 +type Customer struct { + Id int64 `json:"id" xorm:"not null pk autoincr comment('主键') INT(11)"` + Activities []*Activity `json:"activities" xorm:"-" description:"用户创建的主活动"` + Nickname string `json:"nickname" xorm:"not null default('') comment('昵称') VARCHAR(255)"` + Username string `json:"username" xorm:"not null default('') comment('用户名') VARCHAR(255)"` + Password string `json:"-" xorm:"not null default('') comment('密码') VARCHAR(255)"` + Openid string `json:"open_id" xorm:"not null default('') comment('openid') VARCHAR(128)"` + Token string `json:"token" xorm:"not null default('') comment('登陆凭证token') VARCHAR(255)"` + Balance float64 `json:"balance" xorm:"not null default(0.00) comment('余额') DECIMAL(18)"` + SmsCode string `json:"sms_code" xorm:"not null default('') comment('短信验证码') VARCHAR(128)"` + AreaId int64 `json:"area_id" xorm:"not null default(0) comment('地区id') INT(11)"` // 子账号的地区 + ActivityId int64 `json:"activity_id" xrom:"not null default(0) comment('主活动id') INT(11)"` + HeadImg string `json:"head_img" xorm:"not null default('') comment('头像') VARCHAR(255)"` + Email string `json:"email" xorm:"not null default('') comment('邮箱') VARCHAR(128)"` + Phone string `json:"phone" xorm:"not null default('') comment('电话号码') VARCHAR(128)"` + QqOpenid string `json:"qq_openid" xorm:"not null default('') comment('qq openid') VARCHAR(255)"` + Tag string `json:"tag" xorm:"-" description:"tag ws过滤信息"` + Pid int64 `json:"pid" xorm:"not null default(0) comment('上级账号,该值为空时不允许登陆web客户端') INT(11)"` // 可能判断是否为子账号h + RoleId int64 `json:"role_id" xorm:"not null default(4) comment('1超级管理员2代理商3渠道会员4普通会员5地区子账号') INT(11)"` + TopId int64 `json:"top_id" xorm:"not null default(0) comment('角色的上级id') INT(11)"` + IsDelete bool `json:"-" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"-" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"-" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *Customer) TableName() string { + return CustomerTableName +} + +//根据账号和密码验证用户 +func (t *Customer) Author(userName, pwd string) error { + exist, err := core.GetXormAuto().Where("(phone=? or email=?) and is_delete=0", userName, userName).Get(t) + if err != nil { + logger.Sugar.Debugf("验证用户失败,失败原因:%+v,账号:%s,密码:%s,MD5后得密码:%s", err, userName, pwd, helper.Md5(fmt.Sprintf("hdzj==%s", pwd))) + return err + } + if !exist { + return errors.New("用户名错误,请重新输入") + } + + if t.Pid == 0 { + pwd = helper.Md5(fmt.Sprintf("hdzj==%s", pwd)) + } + if t.Password != pwd { + return errors.New("密码错误,请重新输入") + } + return nil +} + +func (t *Customer) GetByOpenid(openid string) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and openid=?", openid).Get(t) +} + +func (t *Customer) GetByQQOpenid(openid string) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and qq_openid=?", openid).Get(t) +} diff --git a/models/customer_goods.go b/models/customer_goods.go new file mode 100644 index 0000000..55c49f5 --- /dev/null +++ b/models/customer_goods.go @@ -0,0 +1,32 @@ +package models + +import ( + "time" +) + +const CustomerGoodsTableName = TableNamePrefix + "customer_goods" + +type CustomerGoods struct { + Id int64 `json:"id"` + ActivityId int64 `json:"activity_id"` + GoodsPicUrl string `json:"goods_pic_url"` + Name string `json:"name" description:"商品名字"` + Qrcode string `json:"qrcode" xorm:"-"` + Price float64 `json:"price" description:"价格"` + Desc string `json:"desc" description:"介绍"` + IsDelete bool `json:"is_delete" xorm:"default(0)"` + CreatedAt time.Time `json:"created_at" xorm:"created"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated"` +} + +func (t *CustomerGoods) TableName() string { + return CustomerGoodsTableName +} + +func (t *CustomerGoods) Alias(name string) string { + return AliasTableName(t, name) +} + +//func (t *CustomerGoods) GetById(gid int64) (bool, error) { +// return core.GetXormAuto().Where("is_delete=0 and id=?", gid).Get(t) +//} diff --git a/models/customer_operation.go b/models/customer_operation.go new file mode 100644 index 0000000..bee9e37 --- /dev/null +++ b/models/customer_operation.go @@ -0,0 +1,60 @@ +package models + +import ( + "hudongzhuanjia/logger" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +// 用户操作, 主从账号同步信息 +// 拔河/摇红包/摇奖券/订单/上墙/霸屏/抽奖/投票/竞拍/打赏/会务 +type CustomerOperation struct { + Id int64 `json:"id"` + CustomerId int64 `json:"customer_id" description:"客户id"` + ActivityId int64 `json:"activity_id" description:"主活动id"` + AreaId int64 `json:"area_id" description:"地区id"` + ModuleActivityId int64 `json:"module_activity_id" description:"具体活动id"` + ModuleActivityType string `json:"module_activity_type" description:"具体活动类型"` + Operation string `json:"operation" description:"操作内容"` + OtherData interface{} `json:"other_data" xorm:"-" description:"额外的字段"` + ExtraData string `json:"-" xorm:"text" description:"额外信息"` + IsDelete bool `json:"is_delete" xorm:"default(0)"` + CreatedAt time.Time `json:"created_at" xorm:"created"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated"` +} + +func (op *CustomerOperation) SaveCustomerOperation() int64 { + row, err := core.GetXormAuto().InsertOne(op) + if err != nil { + logger.Sugar.Debugf("customer operation insert failed. error: %v; content: %s", err, op.ExtraData) + return 0 + } + return row +} + +func (op *CustomerOperation) GetOpsByCustomerId(customerId int64, areaId int64) []*CustomerOperation { + ops := make([]*CustomerOperation, 0) + var err error + if areaId == 0 { + err = core.GetXormAuto().Where("customer_id=?", customerId).OrderBy("created_at desc").Find(&ops) + } else { + err = core.GetXormAuto().Where("customer_id=? and area_id=?", customerId, areaId).OrderBy("created_at asc").Find(&ops) + } + if err != nil { + logger.Sugar.Debugf("customer_operation find failed. error: %v", err) + return nil + } + return ops +} + +func (op *CustomerOperation) GetOpByCustomerId(customerId int64) (bool, error) { + return core.GetXormAuto().Where("customer_id=? and is_delete=0", customerId).OrderBy("created_at desc").Get(op) +} +func (op *CustomerOperation) GetOpByActivityId(activityId int64) (bool, error) { + return core.GetXormAuto().Where("activity_id=? and is_delete=0", activityId).OrderBy("created_at desc").Get(op) +} + +func (op *CustomerOperation) GetOpByCustomerIdAndActivityId(pid, activityId int64) (bool, error) { + return core.GetXormAuto().Where("customer_id=? and activity_id=?", pid, activityId).OrderBy("created_at desc").Get(op) +} diff --git a/models/customer_order.go b/models/customer_order.go new file mode 100644 index 0000000..abc8148 --- /dev/null +++ b/models/customer_order.go @@ -0,0 +1,39 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const CustomerOrderTableName = TableNamePrefix + "customer_order" + +type CustomerOrder struct { + Id int64 `json:"id" xorm:"pk autoincr BIGINT(20)"` + UserPrizeId int64 `json:"user_prize_id" xorm:"not null default 0 comment('用户奖品id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default 0 comment('主活动id') INT(11)"` + AreaId int64 `json:"area_id" xorm:"not null default 0 comment('地区id') BIGINT(20)"` + AreaName string `json:"area_name" xorm:"not null default('') comment('地区名字') VARCHAR(255)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id/0正式') BIGINT(20)"` + OutTradeNo string `json:"out_trade_no" xorm:"not null default('') comment('订单流水号') VARCHAR(255)"` + OrderEntryPersonId int64 `json:"order_enter_person_id" xorm:"not null default 0 comment('订单录入人员id') BIGINT(20)"` + OrderEntryPersonName string `json:"order_entry_person_name" xorm:"-"` + BuyerId int64 `json:"buyer_id" xorm:"not null default 0 comment('user表id') BIGINT(20)"` + User *User `json:"user" xorm:"-"` + GoodsId int64 `json:"goods_id" xorm:"not null default 0 comment('customer_goods表id') BIGINT(20)"` + Good *CustomerGoods `json:"good" xorm:"-"` + GoodsName string `json:"goods_name" xorm:"not null default('') comment('商品名字') VARCHAR(255)"` + TotalAmount float64 `json:"total_amount" xorm:"not null default 0.00 comment('订单总额') DECIMAL"` + OrderTime string `json:"order_time" xorm:"-"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *CustomerOrder) TableName() string { + return CustomerOrderTableName +} + +func (t *CustomerOrder) SoftDeleteById(id int64) (int64, error) { + t.IsDelete = true + return core.GetXormAuto().Id(id).Cols("is_delete").Update(t) +} diff --git a/models/customer_order_option.go b/models/customer_order_option.go new file mode 100644 index 0000000..d7f02ef --- /dev/null +++ b/models/customer_order_option.go @@ -0,0 +1,37 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const CustomerOrderOptionTableName = TableNamePrefix + "customer_order_option" + +type CustomerOrderOption struct { + Id int64 `json:"id" xorm:"not null pk INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default 0 comment('互动id') INT(11)"` + SettingBox string `json:"setting_box" xorm:"not null comment('json格式 选中的表单项') TEXT"` + SelfBox string `json:"self_box" xorm:"not null comment('json格式 邀请函选中的表单项') TEXT"` + Status int `json:"status" xorm:"not null default 0 comment('订单活动的开启1|关闭0') TINYINT(1)"` + IsDelete int `json:"-" xorm:"not null default 0 comment('删除') TINYINT(1)"` + CreatedAt time.Time `json:"-" xorm:"created"` + UpdatedAt time.Time `json:"-" xorm:"updated"` +} + +func (t *CustomerOrderOption) TableName() string { + return CustomerOrderOptionTableName +} + +func (t *CustomerOrderOption) GetByActivityId(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid).Get(t) +} + +func (t *CustomerOrderOption) GetOpen(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and status=?", aid, 1). + Desc("created_at").Get(t) +} + +func (t *CustomerOrderOption) Switch(aid int64, status int) (int64, error) { + t.Status = status + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid).Cols("status").Update(t) +} diff --git a/models/dan_mu_server.go b/models/dan_mu_server.go new file mode 100644 index 0000000..45437c2 --- /dev/null +++ b/models/dan_mu_server.go @@ -0,0 +1,32 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const DanMuServerTableName = TableNamePrefix + "dan_mu_server" + +type DanMuServer struct { + Id int64 `json:"id" xorm:"not null pk autoincr"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('互动id') INT(11)" description:"主活动id"` + DanmuSwitch string `json:"danmu_switch" xorm:"not null default('关闭') comment('弹幕服务开启、关闭') VARCHAR(255)"` + DanmuOpacity int `json:"danmu_opacity" xorm:"not null default(100) comment('弹幕透明度') INT(11)"` + DanmuSpeed int `json:"danmu_speed" xorm:"not null default(50) comment('弹幕速度') INT(11)"` + DanmuPosition string `json:"danmu_position" xorm:"not null default('顶部') comment('弹幕位置[顶部 底部 满屏]')"` + DanmuFontSize string `json:"danmu_font_size" xorm:"not null default('中') comment('字号大小[大 中 小]')"` + ServerDisplay string `json:"server_display" xorm:"not null default('消息界面') comment('霸屏展示方式 [消息界面|互动界面]') VARCHAR(255)"` + ServerStartTime time.Time `json:"server_start_time" xorm:"not null default('1970-01-01 08:00:00') comment('开启时间') DATETIME"` + ServerEndTime time.Time `json:"server_end_time" xorm:"not null default('1970-01-01 08:00:00') comment('结束时间') DATETIME" description:"关闭时间"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null default(CURRENT_TIMESTAMP) updated comment('更新时间') TIMESTAMP" description:"更新时间"` +} + +func (t *DanMuServer) TableName() string { + return DanMuServerTableName +} + +func (t *DanMuServer) GetByActivityId(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid).Get(t) +} diff --git a/models/init_models.go b/models/init_models.go new file mode 100644 index 0000000..e58c090 --- /dev/null +++ b/models/init_models.go @@ -0,0 +1,87 @@ +package models + +import ( + "fmt" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +const TableNamePrefix = "ox_" + +func init() { + err := core.GetXormAuto().Sync2( + new(Activity), + new(ActivityModuleService), + new(Annex), + new(AreaStore), + new(AuctionHistory), + new(AuctionResultRecord), + new(BaheTeam), + new(BaheTeamMember), + new(BarrageHistory), + new(BullyScreenHistory), + new(BullyScreenServer), + new(BullyScreenWalletHistory), + new(Customer), + new(CustomerGoods), + new(CustomerOperation), + new(CustomerOrder), + new(DanMuServer), + new(Invitation), + new(InvitationLetter), + new(LotteryDrawActivity), + new(LotteryDrawEnvelopeWallet), + new(LotteryDrawRecord), + new(LotteryDrawRule), + new(LotteryDrawRuleLadder), + new(LotteryDrawWalletHistory), + new(ModuleService), + new(ModuleServiceHistory), + new(ModuleStyle), + new(NewAuctionActivity), + new(NewVoteActivity), + new(NewVoteActivityHistory), + new(NewVoteActivityLadder), + new(Order), + new(OrderDrawActivity), + new(OrderDrawRecord), + new(OrderDrawRule), + new(OrderDrawRuleLadder), + new(OrderDrawStyle), + new(RewardHistory), + new(RewardServer), + new(RewardWallet), + new(RewardWalletHistory), + new(SeminarActivity), + new(SeminarInviteCode), + new(SeminarInvitePage), + new(SeminarRule), + new(SeminarStyle), + new(Sensitive), + new(ShakeRedEnvelopeActivity), + new(ShakeRedEnvelopeRecord), + new(ShakeRedEnvelopeRule), + new(ShakeRedEnvelopeRuleLadder), + new(SignHistory), + new(SignUp), + new(TugOfWar), + new(UpperWall), + new(User), + new(UserWalletHistory), + new(NewVoteActivity), + new(NewVoteActivityHistory), + new(OrderEntryPerson), + new(Rehearsal), + new(WeChatTicket), + new(MsgWallServer), + new(ShakeRedEnvelopeUser), + new(OrderGift), + new(UserPrize), + new(Calorie), + new(CalorieUser), + new(UserOrder), + new(UserRefund), + new(UserRedPack), + ) + fmt.Printf("error=======>%v\n\n", err) +} diff --git a/models/invitation.go b/models/invitation.go new file mode 100644 index 0000000..9299351 --- /dev/null +++ b/models/invitation.go @@ -0,0 +1,25 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type Invitation struct { + Id int64 `json:"id" description:"主键"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动id')" description:"主活动id"` + SettingBox string `json:"setting_box" xorm:"not null comment('表单选项json化')" description:"表单选项Json化"` + SelfBox string `json:"self_box" xorm:"not null comment('表单选项json化')" description:"自定义表单选项json"` + SubmitTimeLimit time.Time `json:"submit_time_limit" xorm:"not null comment('0为不限制 1为限制 限制必填时间段')" description:"0为不限制 1为限制 限制必填时间段"` + TimeLimitEnd time.Time `json:"time_limit_end" xorm:"not null default('1970-01-01 08:00:00') comment('限制时间段结束')" description:"限制时间段结束"` + QrImageUrl string `json:"qr_image_url" xorm:"not null comment('二维码图片地址')" description:"二维码图片地址"` + QrDestUrl string `json:"qr_dest_url" xorm:"not null comment('二维码图片指向地址')" description:"二维码图片指向地址"` + IsDelete bool `json:"-" xorm:"default(0)" description:"删除"` + CreatedAt time.Time `json:"-" xorm:"created"` + UpdatedAt time.Time `json:"-" xorm:"updated"` +} + +func (i *Invitation) GetInvitationByActivityId(aid int64) (bool, error) { + return core.GetXormAuto().Where("activity_id = ? and is_delete = ?", aid, false).Get(i) +} diff --git a/models/invitation_letter.go b/models/invitation_letter.go new file mode 100644 index 0000000..c93ed06 --- /dev/null +++ b/models/invitation_letter.go @@ -0,0 +1,37 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +const InvitationLetterTableName = TableNamePrefix + "invitation_letter" + +type InvitationLetter struct { + Id int64 `json:"id" xorm:"pk autoincr" description:"主键"` + UserId int64 `json:"user_id" xorm:"not null default(0) comment('用户id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default(0) comment('主活动id') INT(11)"` + InvitationId int64 `json:"invitation_id" xorm:"not null default(0) comment('邀请函id') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default 0 comment('彩排id') INT(11)"` + ExtraData string `json:"extra_data" xorm:"not null default(0) comment('邀请函信息') LONGTEXT"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"删除"` + CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新"` +} + +func (t *InvitationLetter) TableName() string { + return InvitationLetterTableName +} + +func (t *InvitationLetter) Alias(name string) string { + return AliasTableName(t, name) +} + +func (t *InvitationLetter) Insert() (int64, error) { + return core.GetXormAuto().InsertOne(t) +} + +func (t *InvitationLetter) GetByUserIdAndActivityId(uid, aid, rid int64) (bool, error) { + return core.GetXormAuto().Where("user_id=? and activity_id=? and rehearsal_id=? and is_delete=0", uid, aid, rid).Get(t) +} diff --git a/models/lottery_draw_activity.go b/models/lottery_draw_activity.go new file mode 100644 index 0000000..fe888e7 --- /dev/null +++ b/models/lottery_draw_activity.go @@ -0,0 +1,31 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const LotteryDrawActivityTableName = TableNamePrefix + "lottery_draw_activity" + +//抽奖活动 +type LotteryDrawActivity struct { + Id int64 `json:"id"` + ActivityId int64 `json:"activity_id" description:"主活动的id"` + CreatorId int64 `json:"creator_id" description:"创建者id"` + LotteryDrawActivityName string `json:"lottery_draw_activity_name" description:"抽奖轮次名称"` + LotteryDrawRule *LotteryDrawRule `json:"lottery_draw_rule" xorm:"-" description:"抽奖活动规则"` + IsDelete bool `json:"-" xorm:"default(0)"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} + +func (t *LotteryDrawActivity) TableName() string { + return LotteryDrawActivityTableName +} + +func GetLDActivityIdsByActivityId(aid int64) ([]int64, error) { + lotteryIds := make([]int64, 0) + err := core.GetXormAuto().Table(new(LotteryDrawActivity)).Select("id"). + Where("is_delete=0 and activity_id=?", aid).Find(&lotteryIds) + return lotteryIds, err +} diff --git a/models/lottery_draw_envelope_wallet.go b/models/lottery_draw_envelope_wallet.go new file mode 100644 index 0000000..1005560 --- /dev/null +++ b/models/lottery_draw_envelope_wallet.go @@ -0,0 +1,15 @@ +package models + +import ( + "time" +) + +//抽奖红包钱包 +type LotteryDrawEnvelopeWallet struct { + Id int64 `json:"id"` + CustomerId int64 `json:"customer_id" description:"客户id"` + Balance float64 `json:"balance" description:"余额"` + IsDelete bool `json:"is_delete" xorm:"default(0)"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/lottery_draw_record.go b/models/lottery_draw_record.go new file mode 100644 index 0000000..1b62123 --- /dev/null +++ b/models/lottery_draw_record.go @@ -0,0 +1,32 @@ +package models + +import ( + "time" +) + +const LotteryDrawRecordTableName = TableNamePrefix + "lottery_draw_record" + +type LotteryDrawRecord struct { + Id int64 `json:"id" xorm:"pk autoincr"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动id')"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null comment('彩排id/0正式')"` + UserPrizeId int64 `json:"user_prize_id" xorm:"not null comment('用户奖品id') INT(11)"` + LotteryDrawActivityId int64 `json:"lottery_draw_activity_id" xorm:"not null comment('抽奖活动id')"` + LotteryDrawRuleId int64 `json:"lottery_draw_rule_id" xorm:"not null comment('抽奖规则id') BIGINT(20)"` + LotteryDrawRuleLadder *LotteryDrawRuleLadder `json:"lottery_draw_rule_ladder" xorm:"-"` + UserId int64 `json:"user_id" xorm:"not null comment('用户id')"` + User *User `json:"user" xorm:"-"` + UserName string `json:"user_name" description:"用户名" xorm:"not null comment('用户名')"` + UserPhone string `json:"user_phone" description:"电话" xorm:"not null comment('电话号码')"` + LotteryDrawRuleLadderId int64 `json:"lottery_draw_rule_ladder_id" xorm:"not null comment('规则阶梯id')"` + PrizeName string `json:"prize_name" description:"奖品名字" xorm:"not null comment('奖品名字')"` + AreaName string `json:"area_name" description:"名字" xorm:"not null comment('地区名字')"` + AreaId int64 `json:"area_id" xorm:"not null default(0) comment('地区id')"` + IsDelete bool `json:"-" xorm:"default(0)"` + CreatedAt time.Time `json:"-" xorm:"created"` + UpdatedAt time.Time `json:"-" xorm:"updated"` +} + +func (t *LotteryDrawRecord) TableName() string { + return LotteryDrawRecordTableName +} diff --git a/models/lottery_draw_rule.go b/models/lottery_draw_rule.go new file mode 100644 index 0000000..87ffec0 --- /dev/null +++ b/models/lottery_draw_rule.go @@ -0,0 +1,40 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/utils/define" + "time" +) + +const LotteryDrawRuleTableName = TableNamePrefix + "lottery_draw_rule" + +//抽奖活动规则 +type LotteryDrawRule struct { + Id int64 `json:"id"` + LotteryDrawActivityId int64 `json:"lottery_draw_activity_id" description:"红包轮次的id"` + LotteryDrawRuleLadders []*LotteryDrawRuleLadder `json:"lottery_draw_rule_ladder" xorm:"-" description:"阶梯"` + AreaId int64 `json:"area_id" description:"地区id"` + AreaStatus string `json:"area_status" description:"多地区[开启,关闭]"` + UseTimes int64 `json:"use_times" description:"使用次数"` + LotteryDrawStatus string `json:"lottery_draw_status" description:"抽奖活动状态 [未开始/进行中/已结束]"` // 废弃字段 + PrizeNum int `json:"prize_num" xorm:"-" description:"奖品总数"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} + +func (t *LotteryDrawRule) TableName() string { + return LotteryDrawRuleTableName +} + +func GetLDRuleIdsByLDActivityId(ids []int64) ([]int64, error) { + ruleIds := make([]int64, 0) + err := core.GetXormAuto().Table(new(LotteryDrawRule)).Select("id"). + Where("is_delete=0").In("lottery_draw_activity_id", ids).Find(&ruleIds) + return ruleIds, err +} + +func UpdateLDRuleStatusByLDActiviytIds(ids []int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0").In("lottery_draw_activity_id", ids). + Update(&LotteryDrawRule{LotteryDrawStatus: define.StatusNotBegin}) +} diff --git a/models/lottery_draw_rule_ladder.go b/models/lottery_draw_rule_ladder.go new file mode 100644 index 0000000..293aacd --- /dev/null +++ b/models/lottery_draw_rule_ladder.go @@ -0,0 +1,37 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/utils/define" + "time" +) + +const LotteryDrawRuleLadderTableName = TableNamePrefix + "lottery_draw_rule_ladder" + +//抽奖活动规则阶梯 +type LotteryDrawRuleLadder struct { + Id int64 `json:"id"` + LotteryDrawRuleId int64 `json:"lottery_draw_rule_id" description:"红包轮次的id"` + PrizeName string `json:"prize_name" description:"奖品名字"` + PrizeNumber int `json:"prize_number" description:"奖品数量"` + Probability float64 `json:"probability" description:"概率"` + PrizeImg string `json:"prize_img" description:"奖品图片"` + Status string `json:"status" xorm:"not null default('未开始') comment('状态未开始进行中已结束') VARCHAR(3)"` + Des string `json:"des" xorm:"-" description:"规则描述"` + IsDelete bool `json:"-" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} + +func (t *LotteryDrawRuleLadder) TableName() string { + return LotteryDrawRuleLadderTableName +} + +func (t *LotteryDrawRuleLadder) Alias(name string) string { + return AliasTableName(t, name) +} + +func UpdateLDLadderStatusByLDRuleIds(ids []int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0").In("lottery_draw_rule_id", ids). + Update(&LotteryDrawRuleLadder{Status: define.StatusNotBegin}) +} diff --git a/models/lottery_draw_wallet_history.go b/models/lottery_draw_wallet_history.go new file mode 100644 index 0000000..f5bed05 --- /dev/null +++ b/models/lottery_draw_wallet_history.go @@ -0,0 +1,16 @@ +package models + +import ( + "time" +) + +//抽奖活动钱包历史 +type LotteryDrawWalletHistory struct { + Id int64 `json:"id"` + CustomerId int64 `json:"customer_id" description:"客户id"` + Money float64 `json:"money" description:"金额[分正负]"` + Mark string `json:"mark" description:"备注"` + IsDelete bool `json:"is_delete" xorm:"default(0)"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/lottery_draw_winner.go b/models/lottery_draw_winner.go new file mode 100644 index 0000000..affc58b --- /dev/null +++ b/models/lottery_draw_winner.go @@ -0,0 +1,14 @@ +package models + +//抽奖的中奖名单 +//type LotteryDrawWinner struct { +// Id int64 `json:"id"` +// LotteryDrawRuleId int64 `json:"lottery_draw_rule_id" description:"红包轮次的id"` +// LotteryDrawRuleLadderId int64 `json:"lottery_draw_rule_ladder_id" description:"抽奖奖品的id"` +// LotteryDrawRuleLadder *LotteryDrawRuleLadder `json:"lottery_draw_rule_ladder" xorm:"-" description:"奖品得信息"` +// UserId int64 `json:"user_id" description:"用户表得id"` +// User *User `json:"user" xorm:"-" description:"用户信息"` +// IsDelete bool `json:"is_delete" xorm:"default(0)"` +// CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +//} diff --git a/models/module_service.go b/models/module_service.go new file mode 100644 index 0000000..565e26a --- /dev/null +++ b/models/module_service.go @@ -0,0 +1,22 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +//模块服务表 +type ModuleService struct { + Id int64 `json:"id"` + Name string `json:"name" description:"模块的名称"` + Price float64 `json:"price" description:"模块价格"` + Free string `json:"free" description:"模块是否收费[收费|免费]"` + IsDelete bool `json:"is_delete" xorm:"default(0)"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} + +func (t *ModuleService) GetByName(name string) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and name=?", name).Get(t) +} diff --git a/models/module_service_history.go b/models/module_service_history.go new file mode 100644 index 0000000..f896962 --- /dev/null +++ b/models/module_service_history.go @@ -0,0 +1,34 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +const ModuleServiceHistoryTableName = TableNamePrefix + "module_service_history" + +type ModuleServiceHistory struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + ServiceModuleId int64 `json:"service_module_id" xorm:"not null comment('服务模块的id') INT(11)" description:"服务模块的id"` + Name string `json:"name" xorm:"not null comment('模块名字') VARCHAR(255)" description:"模块的名称"` + Price float64 `json:"price" xorm:"not null default(0.0) comment('模块价格') DECIMAL(10) " description:"模块价格"` + Free string `json:"free" xorm:"not null comment('模块是否收费[收费|免费]') VARCHAR(255)" description:"模块是否收费[收费|免费]"` + Description string `json:"description" xorm:"not null comment('描述或者简介') VARCHAR(128)"` + UseTimes int `json:"use_times" xorm:"not null default(0) comment('模块服务使用次数') INT(11)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"-" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"` +} + +func (t *ModuleServiceHistory) TableName() string { + return ModuleServiceHistoryTableName +} + +func (t *ModuleServiceHistory) Alias(name string) string { + return AliasTableName(t, name) +} + +func (t *ModuleServiceHistory) GetByModuleIdAndName(id int64, name string) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and service_module_id=? and name=?", id, name).Get(t) +} diff --git a/models/module_style.go b/models/module_style.go new file mode 100644 index 0000000..2b9e952 --- /dev/null +++ b/models/module_style.go @@ -0,0 +1,16 @@ +package models + +import ( + "time" +) + +//模块样式表 +type ModuleStyle struct { + Id int64 `json:"id"` + ModuleServiceId int64 `json:"module_service_id" description:"服务模块的id"` + StyleName string `json:"style_name" description:"样式名字"` + StyleImage string `json:"style_image" description:"样式图片"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否已删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/msg_wall_server.go b/models/msg_wall_server.go new file mode 100644 index 0000000..3568641 --- /dev/null +++ b/models/msg_wall_server.go @@ -0,0 +1,23 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type MsgWallServer struct { + Id int64 `json:"id" xorm:"pk autoincr"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动id')"` + MsgWallBgUrl string `json:"msg_wall_bg_url" xorm:"not null comment('消息墙背景url')"` + MsgWallBgStatus string `json:"msg_wall_bg_status" xorm:"not null default('关闭') comment('自定义消息墙背景开关[开启|关闭]')"` + UpWallStatus string `json:"up_wall_status" xorm:"not null default('关闭') comment('消息上墙开关[开启|关闭]')"` + MsgTrailStatus string `json:"msg_trail_status" xorm:"not null default('关闭') comment('消息审核开关[开启|关闭]')"` + IsDelete bool `json:"is_delete" xorm:"default('0') comment('删除')"` + CreatedAt time.Time `json:"created_at" xorm:"created comment('创建')"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated comment('更新')"` +} + +func (t *MsgWallServer) GetByActivityId(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid).Get(t) +} diff --git a/models/new_auction_activity.go b/models/new_auction_activity.go new file mode 100644 index 0000000..a998db2 --- /dev/null +++ b/models/new_auction_activity.go @@ -0,0 +1,84 @@ +package models + +import ( + "hudongzhuanjia/utils/define" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +const NewAuctionActivityTableName = TableNamePrefix + "new_auction_activity" + +type NewAuctionActivity struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + Pid int64 `json:"pid" xorm:"not null default(0) comment('排序id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default(0) comment('主活动id') INT(11)"` + Histories []*AuctionHistory `json:"histories" xorm:"-"` + AuctionModel string `json:"auction_model" xorm:"not null default('加价竞拍') comment('竞拍模式:加价竞拍|减价竞拍') VARCHAR(128)"` + AuctionGoodsName string `json:"auction_goods_name" xorm:"not null default('') comment('竞拍商品名字') VARCHAR(255)"` + AuctionDuration string `json:"auction_duration" xorm:"not null default(0) comment('竞拍时长单位秒') INT(11)"` + AuctionEndTime int64 `json:"auction_end_time" xorm:"not null default(0) comment('竞拍结束时间') INT(11)"` + GoodsNum int `json:"goods_num" xorm:"not null default(0) comment('减价竞拍的商品数量') INT(11)"` + StartPrice float64 `json:"start_price" xorm:"not null default(0.00) comment('起拍价格') DECIMAL(18)"` + Step float64 `json:"step" xorm:"not null default(0.00) comment('加价或减价幅度') DECIMAL(18)"` + ReduceRate string `json:"reduce_rate" xorm:"not null default(0) comment('减价频率单位秒') VARCHAR(255)"` + Desc string `json:"desc" xorm:"not null comment('商品描述') TEXT"` + GoodsPicUrl string `json:"goods_pic_url" xorm:"not null default('') comment('商品图片url') VARCHAR(255)"` + Status string `json:"status" xorm:"not null default('未开始') comment('状态[未开始,装备中, 进行中,已结束]') VARCHAR(128)"` + CurrentMoney float64 `json:"current_money,omitempty" xorm:"-" description:"当前价格"` + Unit int `json:"unit" xorm:"not null default(1) comment('单位') TINYINT(1)"` + IsSort int `json:"is_sort" xorm:"not null default(0) comment('1表示排过序') INT(11)"` + IsDelete bool `json:"-" xorm:"not null default(0) comment('软删除') TINYINT(1)" description:"删除 "` + CreatedAt time.Time `json:"-" xorm:"not null created comment('创建时间') DATETIME" description:"创建"` + UpdatedAt time.Time `json:"-" xorm:"not null updated comment('更新时间') DATETIME" description:"更新"` +} + +func (t *NewAuctionActivity) TableName() string { + return NewAuctionActivityTableName +} + +func (t *NewAuctionActivity) Alias(name string) string { + return AliasTableName(t, name) +} + +func (t *NewAuctionActivity) IncrMoneyById(id int64, money float64) (int64, error) { + return core.GetXormAuto().Id(id).Incr("money", money).Update(t) +} + +func (t *NewAuctionActivity) DecrMoneyById(id int64, money float64) (int64, error) { + return core.GetXormAuto().Id(id).Decr("money", money).Decr("goods_num", 1).Update(t) +} + +func (t *NewAuctionActivity) UpdateToStatusByAid(aid int64, before, after string) (int64, error) { + t.Status = after + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and status=?", aid, before). + Cols("status", "updated_at").Update(t) +} +func (t *NewAuctionActivity) UpdateStatusById(id int64, status string) (int64, error) { + t.Status = status + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and id=?", id). + Cols("status", "updated_at").Update(t) +} + +func (t *NewAuctionActivity) GetByActivityId(aid int64, status string) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and status=?", aid, status). + Desc("created_at").Get(t) +} +func (t *NewAuctionActivity) GetCurrent(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and (status=? or status=?)", + aid, define.StatusReady, define.StatusRunning).Get(t) +} + +func UpdateAuctionStatusByActivityId(aid int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid). + Update(&NewAuctionActivity{Status: define.StatusNotBegin}) +} + +func GetAuctionsByActivityId(aid int64, orderBy string) ([]*NewAuctionActivity, error) { + auctions := make([]*NewAuctionActivity, 0) + err := core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid). + OrderBy(orderBy).Find(&auctions) + return auctions, err +} diff --git a/models/new_vote_activity.go b/models/new_vote_activity.go new file mode 100644 index 0000000..6ad36e5 --- /dev/null +++ b/models/new_vote_activity.go @@ -0,0 +1,64 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/utils/define" + "time" +) + +const NewVoteActivityTableName = TableNamePrefix + "new_vote_activity" + +type NewVoteActivity struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('互动id') INT(11)"` + VoteActivityLadders []*NewVoteActivityLadder `json:"vote_activity_ladders" xorm:"-"` + Theme string `json:"theme" xorm:"not null default('') comment('投票主题') VARCHAR(255)"` + JoinWay string `json:"join_way" xorm:"not null comment('参与方式说明') TEXT"` + Description string `json:"description" xorm:"not null comment('投票介绍') TEXT"` + Model string `json:"model" xorm:"not null default('单选') comment('投票类型[单选|多选]') VARCHAR(128)"` + ModelNum int64 `json:"model_num" xorm:"not null default(1) comment('投票类型选多少个') INT(11)"` + VoteLastTime string `json:"vote_last_time" description:"投票时长秒 0表示无时间限制"` + VoteEndTime int64 `json:"vote_end_time" xorm:"default(0)" description:"投票开始时间"` + ResultDisplay string `json:"result_display" description:"结果展示[百分比|票数]"` + ResultLimit int `json:"result_limit" description:"默认显示多少名"` + DisplayVoteNumber string `json:"display_vote_number" description:"[显示|不显示] 投票人数"` + PhoneVoteDisplayResult string `json:"phone_vote_display_result" description:"[显示|不显示] 手机端投票是否显示结果"` + VoteBySignUser string `json:"vote_by_sign_user" description:"[指定|不指定] 是否指定签到用户投票"` + VoteStatus string `json:"vote_status" description:"投票活动的状态 [可投票|不可投票]"` + IsDelete bool `json:"-" xorm:"default(0)"` + CreatedAt time.Time `json:"-" xorm:"created"` + UpdatedAt time.Time `json:"-" xorm:"updated"` +} + +func (t *NewVoteActivity) TableName() string { + return NewVoteActivityTableName +} + +func (t *NewVoteActivity) GetByActivityId(aid int64, status string) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and vote_status=?", aid, status). + Desc("created_at").Get(t) +} + +func (t *NewVoteActivity) UpdateToStatusByAid(aid int64, before string, after string) (int64, error) { + t.VoteStatus = after + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and vote_status=? and activity_id=?", before, aid). + Cols("vote_status", "updated_at").Update(t) +} + +func (t *NewVoteActivity) UpdateStatusById(id int64, status string) (int64, error) { + t.VoteStatus = status + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and id=?", id). + Cols("vote_status", "updated_at").Update(t) +} + +func (t *NewVoteActivity) GetCurrent(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and (vote_status=? or vote_status=?)", + aid, define.StatusReady, define.StatusRunning).Desc("created_at").Get(t) +} + +func UpdateVoteStatusByActiviytId(aid int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid). + Update(&NewVoteActivity{VoteStatus: define.StatusNotBegin}) +} diff --git a/models/new_vote_activity_history.go b/models/new_vote_activity_history.go new file mode 100644 index 0000000..20683b1 --- /dev/null +++ b/models/new_vote_activity_history.go @@ -0,0 +1,42 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const VoteActivityHistoryTableName = TableNamePrefix + "new_vote_activity_history" + +type NewVoteActivityHistory struct { + Id int64 `json:"id" xorm:"pk autoincr"` + VoteActivityId int64 `json:"vote_activity_id" xorm:"not null default(0) comment('投票活动id')"` + VoteActivityLadderId int64 `json:"vote_activity_ladder_id" xorm:"not null default('') comment('投票活动对象')"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id/0正式')"` + UserId int64 `json:"user_id" xorm:"not null default(0) comment('投票人')"` + IsDelete bool `json:"-" xorm:"default(0) comment('删除')"` + CreatedAt time.Time `json:"-" xorm:"created comment('创建时间')"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated comment('更新时间')"` +} + +func (t *NewVoteActivityHistory) TableName() string { + return VoteActivityHistoryTableName +} + +func (t *NewVoteActivityHistory) Alias(name string) string { + return AliasTableName(t, name) +} + +func (t *NewVoteActivityHistory) ExistByLadderId(uid, lid, rid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and user_id=? and vote_activity_ladder_id=? and "+ + " rehearsal_id=?", uid, lid, rid).Exist(t) +} + +func (t *NewVoteActivityHistory) ExistByVoteId(uid, vid, rid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and user_id=? and vote_activity_id=? and rehearsal_id=?", + uid, vid, rid).Exist(t) +} + +func (t *NewVoteActivityHistory) CountUser(uid, rid, vid int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0 and user_id=? and rehearsal_id=? and vote_activity_id=?", + uid, rid, vid).Count(t) +} diff --git a/models/new_vote_activity_ladder.go b/models/new_vote_activity_ladder.go new file mode 100644 index 0000000..7d6936f --- /dev/null +++ b/models/new_vote_activity_ladder.go @@ -0,0 +1,29 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const VoteActivityLadderTableName = TableNamePrefix + "new_vote_activity_ladder" + +type NewVoteActivityLadder struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + VoteActivityId int64 `json:"vote_activity_id" xorm:"not null comment('投票轮次的id') INT(11)"` + VoteNumber int64 `json:"vote_number" xorm:"not null comment('投票的初始的票数') INT(11)"` + VoteMember string `json:"vote_member" xorm:"not null comment('投票的人员名字') VARCHAR(255)"` + MemberImg string `json:"member_img" xorm:"not null comment('被投票人员的图片')"` + TotalNumber int64 `json:"total_number" xorm:"not null default 0 comment('投票总数') INT(11)"` + IsVote bool `json:"is_vote" xorm:"-" description:"是否被投票"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *NewVoteActivityLadder) TableName() string { + return VoteActivityLadderTableName +} + +func (t *NewVoteActivityLadder) Incr(id, number int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0 and id=?", id).Incr("total_number", number).Update(t) +} diff --git a/models/order.go b/models/order.go new file mode 100644 index 0000000..410b8e4 --- /dev/null +++ b/models/order.go @@ -0,0 +1,25 @@ +package models + +import ( + "time" +) + +type Order struct { + Id int64 `json:"id"` + CustomerId int64 `json:"customer_id"` + OutTradeNo string `json:"out_trade_no"` + TradeNo string `json:"trade_no"` + Money float64 `json:"money"` + ServiceFee float64 `json:"service_fee"` + TotalAmount float64 `json:"total_amount"` + PayType string `json:"pay_type"` + PayTime time.Time `json:"pay_time"` + Goods string `json:"goods"` + ServiceIds string `json:"service_ids"` + ActivityId string `json:"activity_id"` + IsPay int `json:"is_pay"` + Mark string `json:"mark"` + IsDelete bool `json:"is_delete" xorm:"default(0)"` + CreatedAt time.Time `json:"created_at" xorm:"created"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated"` +} diff --git a/models/order_draw_activity.go b/models/order_draw_activity.go new file mode 100644 index 0000000..f1f9bec --- /dev/null +++ b/models/order_draw_activity.go @@ -0,0 +1,33 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const OrderDrawActivityTableName = TableNamePrefix + "order_draw_activity" + +//订单抽奖活动 +type OrderDrawActivity struct { + Id int64 `json:"id"` + ActivityId int64 `json:"activity_id" description:"活动的id"` + CreatorId int64 `json:"creator_id"` + OrderDrawActivityName string `json:"order_draw_activity_name"` + OrderDrawRule *OrderDrawRule `json:"order_draw_rule" xorm:"-"` + MoreAreaMode string `json:"more_area_mode"` + IsSuccess bool `json:"is_success"` + IsDelete bool `json:"is_delete" xorm:"default(0)"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} + +func (t *OrderDrawActivity) TableName() string { + return OrderDrawActivityTableName +} + +func GetODActivityIdsByActivityId(aid int64) ([]int64, error) { + orderIds := make([]int64, 0) + err := core.GetXormAuto().Table(new(OrderDrawActivity)).Select("id"). + Where("is_delete=0 and activity_id=?", aid).Find(&orderIds) + return orderIds, err +} diff --git a/models/order_draw_record.go b/models/order_draw_record.go new file mode 100644 index 0000000..e69ad6c --- /dev/null +++ b/models/order_draw_record.go @@ -0,0 +1,34 @@ +package models + +import ( + "time" +) + +const OrderDrawRecordTableName = TableNamePrefix + "order_draw_record" + +type OrderDrawRecord struct { + Id int64 `json:"id" xorm:"not null pk autoincr"` + UserPrizeId int64 `json:"user_prize_id" xorm:"not null comment('用户奖品表id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动id')"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id/0正式')"` + OrderDrawActivityId int64 `json:"order_draw_activity_id" xorm:"not null comment('订单抽奖活动id')"` + OrderDrawRuleId int64 `json:"order_draw_rule_id" xorm:"not null comment('订单抽奖规则id')"` + OrderDrawRuleLadderId int64 `json:"order_draw_rule_ladder_id" xorm:"not null comment('订单规则阶梯id')"` + OrderDrawRuleLadder *OrderDrawRuleLadder `json:"order_draw_rule_ladder" xorm:"-"` + UserId int64 `json:"user_id" xorm:"not null comment('用户id')"` + User *User `json:"user" xorm:"-"` + PrizeName string `json:"prize_name" xorm:"not null comment('奖品名字')"` + AreaId int64 `json:"area_id" xorm:"not null default(0) comment('地区id') BIGINT(20)"` + AreaName string `json:"area_name" xorm:"not null default('') comment('地区id')"` + IsDelete bool `json:"-" xorm:"default(0)"` + CreatedAt time.Time `json:"-" xorm:"created"` + UpdatedAt time.Time `json:"-" xorm:"updated"` +} + +func (t *OrderDrawRecord) TableName() string { + return OrderDrawRecordTableName +} + +func (t *OrderDrawRecord) Count() { + +} diff --git a/models/order_draw_rule.go b/models/order_draw_rule.go new file mode 100644 index 0000000..41982ed --- /dev/null +++ b/models/order_draw_rule.go @@ -0,0 +1,45 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/utils/define" + "time" +) + +const OrderDrawRuleTableName = TableNamePrefix + "order_draw_rule" + +//订单抽奖抽奖规则 +type OrderDrawRule struct { + Id int64 `json:"id"` + OrderDrawActivityId int64 `json:"order_lottery_draw_activity_id" description:"订单抽奖活动的的id"` + OrderDrawRuleLadders []*OrderDrawRuleLadder `json:"order_draw_rule_ladders" xorm:"-"` + AreaId int64 `json:"area_id" description:"地区id"` + UseTimes int `json:"use_times" description:"使用次数"` + Name string `json:"name"` + OrderDrawStatus string `json:"order_draw_status"` + PrizeNum int `json:"prize_num" xorm:"-"` + HaveEditRule bool `json:"have_edit_rule"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} + +func (t *OrderDrawRule) TableName() string { + return OrderDrawRuleTableName +} + +func (t *OrderDrawRule) Alias(name string) string { + return AliasTableName(t, name) +} + +func GetODRuleIdsByODActivityIds(ids []int64) ([]int64, error) { + ruleIds := make([]int64, 0) + err := core.GetXormAuto().Table(new(OrderDrawRule)).Select("id"). + Where("is_delete=0").In("order_draw_activity_id", ids).Find(&ruleIds) + return ruleIds, err +} + +func UpdateODRuleStatusByODActivityIds(ids []int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0").In("order_draw_activity_id", ids). + Update(&OrderDrawRule{OrderDrawStatus: define.StatusNotBegin}) +} diff --git a/models/order_draw_rule_ladder.go b/models/order_draw_rule_ladder.go new file mode 100644 index 0000000..0d8cf6f --- /dev/null +++ b/models/order_draw_rule_ladder.go @@ -0,0 +1,38 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/utils/define" + "time" +) + +const OrderDrawRuleLadderTableName = TableNamePrefix + "order_draw_rule_ladder" + +//订单抽奖抽奖规则梯子 +type OrderDrawRuleLadder struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + OrderDrawRuleId int64 `json:"order_draw_rule_id" xorm:"not null comment('订单轮次的id') INT(11)"` + PrizeLevel string `json:"prize_level" xorm:"not null default('1') comment('奖品等级') VARCHAR(128)"` + PrizeName string `json:"prize_name" xorm:"not null comment('奖品名字') VARCHAR(255)"` + PrizeNumber int `json:"prize_number" xorm:"not null default(0) comment('奖品数量') INT(11)"` + Probability float64 `json:"probability" xorm:"not null default(10.00) comment('概率') DECIMAL(10)"` + PrizeImg string `json:"prize_img" xorm:"not null comment('奖品图片') VARCHAR(255)"` + Status string `json:"status" xorm:"not null default('未开始') comment('订单状态未开始,进行中,已结束') VARCHAR(3)"` + Des string `json:"desc" xorm:"-" description:"描述"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *OrderDrawRuleLadder) TableName() string { + return OrderDrawRuleLadderTableName +} + +func (t *OrderDrawRuleLadder) Alias(name string) string { + return AliasTableName(t, name) +} + +func UpdateODLadderStatusByODRuleIds(ids []int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0").In("order_draw_rule_id", ids). + Update(&OrderDrawRuleLadder{Status: define.StatusNotBegin}) +} diff --git a/models/order_draw_style.go b/models/order_draw_style.go new file mode 100644 index 0000000..72a9724 --- /dev/null +++ b/models/order_draw_style.go @@ -0,0 +1,15 @@ +package models + +import ( + "time" +) + +//订单抽奖样式 +type OrderDrawStyle struct { + Id int64 `json:"id"` + StyleName string `json:"style_name" description:"样式的名字"` + StyleImageUrl string `json:"style_image_url" description:"样式的图片地址"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/order_draw_winner.go b/models/order_draw_winner.go new file mode 100644 index 0000000..dc466a6 --- /dev/null +++ b/models/order_draw_winner.go @@ -0,0 +1,14 @@ +package models + +//type OrderDrawWinner struct { +// Id int64 `json:"id"` +// OrderDrawActivityId int64 `json:"order_draw_activity_id"` +// OrderDrawRuleId int64 `json:"order_draw_rule_id"` +// OrderDrawRuleLadderId int64 `json:"order_draw_rule_ladder_id"` +// OrderDrawRuleLadder *OrderDrawRuleLadder `json:"order_draw_rule_ladder" xorm:"-"` +// UserId int64 `json:"user_id"` +// User *User `json:"user" xorm:"-"` +// IsDelete bool `json:"-" xorm:"default(0)"` +// CreatedAt time.Time `json:"-" xorm:"created"` +// UpdatedAt time.Time `json:"-" xorm:"updated"` +//} diff --git a/models/order_entry_person.go b/models/order_entry_person.go new file mode 100644 index 0000000..5cf65f3 --- /dev/null +++ b/models/order_entry_person.go @@ -0,0 +1,31 @@ +package models + +import ( + "time" +) + +const OrderEntryPersonTableName = TableNamePrefix + "order_entry_person" + +type OrderEntryPerson struct { + Id int64 `json:"id" xorm:"pk autoincr BIGINT(20)"` + Name string `json:"name" xorm:"not null default('') comment('名字') VARCHAR(255)"` + Account string `json:"account" xorm:"not null default('') comment('账号') VARCHAR(255)"` + Password string `json:"password" xorm:"not null default('') comment('密码') VARCHAR(255)"` + Pid int64 `json:"pid" xorm:"not null default 0 comment('主账号') VARCHAR(255)"` + AreaId int64 `json:"area_id" xorm:"not null default 0 comment('地区id') BIGINT(20)"` + AreaName string `json:"area_name" xorm:"-"` + ActivityId int64 `json:"activity_id" xorm:"not null default 0 comment('主活动id') BIGINT(20)"` + ActivityName string `json:"activity_name" xorm:"-"` + Token string `json:"token" xorm:"-"` + IsDelete bool `json:"-" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"-" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"-" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *OrderEntryPerson) TableName() string { + return OrderEntryPersonTableName +} + +//func (t *OrderEntryPerson) GetById(eid int64) (bool, error) { +// return core.GetXormAuto().Where("is_delete=0 and id=?", eid).Get(t) +//} diff --git a/models/order_gift.go b/models/order_gift.go new file mode 100644 index 0000000..1f159e4 --- /dev/null +++ b/models/order_gift.go @@ -0,0 +1,29 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/utils/define" + "time" +) + +const OrderGiftTableName = TableNamePrefix + "order_gift" + +type OrderGift struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default(0) comment('互动id') INT(11)"` + OrderGiftSwitch string `json:"order_gift_switch" xorm:"not null default('关闭') comment('订单送礼开关[开启|关闭]') VARCHAR(2)"` + Num int `json:"num" xorm:"not null default(0) comment('前多少人下单有礼0不限制') INT(11)"` + GiftName string `json:"gift_name" xorm:"not null default('') comment('礼品名字') VARCHAR(255)"` + GiftPicUrl string `json:"gift_pic_url" xorm:"not null default('') comment('礼品图片url') VARCHAR(255)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(0)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *OrderGift) TableName() string { + return OrderGiftTableName +} + +func (t *OrderGift) GetByActivityId(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and order_gift_switch=? and activity_id=?", define.StatusOpen, aid).Get(t) +} diff --git a/models/rehearsal.go b/models/rehearsal.go new file mode 100644 index 0000000..6db5ec5 --- /dev/null +++ b/models/rehearsal.go @@ -0,0 +1,21 @@ +package models + +import "time" + +const RehearsalTableName = TableNamePrefix + "rehearsal" + +// 彩排信息 +type Rehearsal struct { + Id int64 `json:"id" xorm:"pk autoincr"` + CustomerId int64 `json:"customer_id" xorm:"not null default(0) comment('客户id')"` + ActivityId int64 `json:"activity_id" xorm:"not null default(0) comment('主活动id')"` + LimitNumber int64 `json:"limit_number" xorm:"not null default(10) comment('限定人数')"` + Status int64 `json:"status" xorm:"not null default(0) comment('0未开始/1进行中/2已结束')"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('删除')"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间')"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间')"` +} + +func (t *Rehearsal) TableName() string { + return RehearsalTableName +} diff --git a/models/reward_history.go b/models/reward_history.go new file mode 100644 index 0000000..10c54b9 --- /dev/null +++ b/models/reward_history.go @@ -0,0 +1,41 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const ReWardHistoryTableName = TableNamePrefix + "reward_history" + +//打赏历史 +type RewardHistory struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + UserOrderId int64 `json:"user_order_id" xorm:"not null default(0) comment('用户订单id') INT(11)"` + CustomerId int64 `json:"customer_id" xorm:"not null comment('客户id') INT(11)"` + RewardServerId int64 `json:"reward_server_id" xorm:"not null comment('打赏服务id') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id/0正式') INT(11)"` + UserId int64 `json:"user_id" xorm:"not null comment('用户得id') INT(11)"` + User *User `json:"user" xorm:"-" description:"用户信息"` + Content string `json:"content" xorm:"not null comment('内容') text"` + Amount float64 `json:"amount" xorm:"not null default(0.0) comment('金额') DECIMAL"` + RewardAmount string `json:"reward_amount" xorm:"-" description:"同上, 字符串"` + Status int `json:"status" xorm:"not null default(0) comment('-1未支付 0未审核,1未通过,2已通过,3已推送') INT(11)"` + ReviewTime int64 `json:"review_time" xorm:"not null default(0) comment('审核时间') INT(11)"` + Version int64 `json:"version" xorm:"not null version comment('乐观锁') INT(11)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0)"` + CreatedAt time.Time `json:"create_at" xorm:"not null default(CURRENT_TIMESTAMP) created comment('创建时间') TIMESTAMP"` + UpdatedAt time.Time `json:"update_at" xorm:"not null default(CURRENT_TIMESTAMP) updated comment('更新时间') TIMESTAMP"` +} + +func (t *RewardHistory) TableName() string { + return ReWardHistoryTableName +} + +func (t *RewardHistory) GetByUserOrderId(userOrderId int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrderId).Get(t) +} + +func (t *RewardHistory) UpdateStatus(id int64, status int) (int64, error) { + t.Status = status + return core.GetXormAuto().Id(id).Cols("status").Update(t) +} diff --git a/models/reward_server.go b/models/reward_server.go new file mode 100644 index 0000000..6dcb982 --- /dev/null +++ b/models/reward_server.go @@ -0,0 +1,30 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const RewardServerTableName = TableNamePrefix + "reward_server" + +//打赏服务 +type RewardServer struct { + Id int64 `json:"id" xorm:"pk autoincr"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动id')" description:"主活动id"` + ServerStartTime time.Time `json:"server_start_time" xorm:"not null comment('服务开始时间')" description:"服务开始时间"` + ServerEndTime time.Time `json:"server_end_time" xorm:"not null comment('服务结束时间')" description:"服务结束时间"` + ServerDisplay string `json:"server_display" xorm:"not null comment('霸屏展示的方式 [消息界面|互动界面]')" description:"霸屏展示的方式 [消息界面|互动界面]"` + ServerStart string `json:"server_start" xorm:"not null comment('打赏服务是否开启 [开启|关闭]')" description:"打赏服务是否开启 [开启|关闭]"` + IsExpire string `json:"is_expire" xorm:"not null comment('是否过期了 此字段应该由脚本去执行 当时间大于服务结束时间时 server_start为关闭 本字段未已过期')"` + IsDelete bool `json:"-" xorm:"default(0)"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} + +func (t *RewardServer) TableName() string { + return RewardServerTableName +} + +func (t *RewardServer) GetByActivityId(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid).Get(t) +} diff --git a/models/reward_wallet.go b/models/reward_wallet.go new file mode 100644 index 0000000..8240377 --- /dev/null +++ b/models/reward_wallet.go @@ -0,0 +1,26 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const RewardWalletTableName = TableNamePrefix + "reward_wallet" + +//打赏钱包 +type RewardWallet struct { + Id int64 `json:"id"` + CustomerId int64 `json:"customer_id" description:"客户id"` + Balance float64 `json:"balance" description:"余额"` + IsDelete bool `json:"is_delete" xorm:"default(0)"` + CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +} + +func (t *RewardWallet) TableName() string { + return RewardWalletTableName +} + +func (t *RewardWallet) IncrBalance(cid int64, money float64) (int64, error) { + return core.GetXormAuto().Where("customer_id=?", cid).Incr("balance", money).Update(t) +} diff --git a/models/reward_wallet_history.go b/models/reward_wallet_history.go new file mode 100644 index 0000000..4e008d3 --- /dev/null +++ b/models/reward_wallet_history.go @@ -0,0 +1,31 @@ +package models + +import ( + "time" +) + +const RewardWalletHistoryTableName = TableNamePrefix + "reward_wallet_history" + +//客户打赏得钱包流水 +type RewardWalletHistory struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + RewardHistoryId int64 `json:"reward_history_id" xorm:"not null default(0) comment('打赏历史表id') INT(11)"` + CustomerId int64 `json:"customer_id" xrom:"not null comment('客户表id') INT(11)"` + Money float64 `json:"money" xorm:"not null default(0.00) comment('金额[分正负]') DECIMAL(10)"` + HisBalance string `json:"his_balance" xrom:"not null default('0') comment('历史红包余额') VARCHAR(255)"` + Type string `json:"type" xorm:"not null default('打赏') comment('记录类型 打赏/提现') VARCHAR(255)"` + UserId int64 `json:"user_id" xorm:"not null default(0) comment('用户表id') INT(11)"` + RewardUsername string `json:"reward_username" xorm:"not null default('') comment('发起打赏的那个用户的用户名') VARCHAR(255)"` + RewardAccount string `json:"reward_account" xorm:"not null default('') comment('支付打赏的账户 手机号') VARCHAR(255)"` + CashMethod string `json:"cash_method" xorm:"not null default('') comment('提现方式') VARCHAR(255)"` + ReceiveCashAccount string `json:"receive_cash_account" xorm:"not null default('') comment('提现收款账户') VARCHAR(255)"` + Status string `json:"status" xorm:"not null default('交易失败') comment('交易状态') VARCHAR(255)"` + Mark string `json:"mark" xorm:"not null comment('') TEXT"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *RewardWalletHistory) TableName() string { + return RewardWalletHistoryTableName +} diff --git a/models/seminar_activity.go b/models/seminar_activity.go new file mode 100644 index 0000000..6b8fccd --- /dev/null +++ b/models/seminar_activity.go @@ -0,0 +1,18 @@ +package models + +import ( + "time" +) + +//会务活动 +type SeminarActivity struct { + Id int64 `json:"id"` + ActivityId int64 `json:"activity_id" description:"主活动id"` + SeminarActivityName string `json:"seminar_activity_name" description:"会务H5的活动名称"` + OpenInviteCode string `json:"open_invite_code" description:"开启邀请码 [开启|关闭]"` + OpenInvitePage string `json:"open_invite_page" description:"开启邀请涵 [开启|关闭]"` + InviteCodeNum int `json:"invite_code_num" description:"邀请码的数量"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"create" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/seminar_activity_invite_code.go b/models/seminar_activity_invite_code.go new file mode 100644 index 0000000..3d9c42e --- /dev/null +++ b/models/seminar_activity_invite_code.go @@ -0,0 +1,21 @@ +package models + +import ( + "time" +) + +//会务活动邀请码 +type SeminarActivityInviteCode struct { + Id int64 `json:"id"` + SeminarActivityId int64 `json:"seminar_activity_id" description:"会话活动的id"` + Comment string `json:"comment" description:"邀请码的备注"` + InviteCode string `json:"invite_code" description:"邀请码 [规则暂未定义]"` + Prefix string `json:"prefix" description:"邀请码 前缀"` + CodeBind int64 `json:"code_bind" description:"邀请码_绑定用户id 初始为0"` + CodeStartTime time.Time `json:"code_start_time" description:"邀请码的开始时间"` + CodeEndTime time.Time `json:"code_end_time" description:"邀请码的结束时间"` + IsExpire string `json:"is_expire" description:"是否已经过期 [已过期|未过期]"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/seminar_invite_code.go b/models/seminar_invite_code.go new file mode 100644 index 0000000..08579cd --- /dev/null +++ b/models/seminar_invite_code.go @@ -0,0 +1,21 @@ +package models + +import ( + "time" +) + +//会务邀请码 +type SeminarInviteCode struct { + Id int64 `json:"id"` + SeminarActivityId int64 `json:"seminar_activity_id" description:"会话活动的id"` + Comment string `json:"comment" description:"邀请码的备注"` + InviteCode string `json:"invite_code" description:"邀请码 [规则暂未定义]"` + Prefix string `json:"prefix" description:"邀请码 前缀"` + CodeBind int64 `json:"code_bind" description:"邀请码_绑定用户id 初始为0"` + CodeStartTime time.Time `json:"code_start_time" description:"邀请码的开始时间"` + CodeEndTime time.Time `json:"code_end_time" description:"邀请码的结束时间"` + IsExpire string `json:"is_expire" description:"是否已经过期 [已过期|未过期]"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/seminar_invite_page.go b/models/seminar_invite_page.go new file mode 100644 index 0000000..6403e76 --- /dev/null +++ b/models/seminar_invite_page.go @@ -0,0 +1,20 @@ +package models + +import ( + "time" +) + +//会务邀请函 +type SeminarInvitePage struct { + Id int64 `json:"id"` + InvitePageImage string `json:"invite_page_image" description:"邀请涵图片"` + SelfFieldDefine string `json:"self_field_define" description:"自定义字段{'xx':xxx}"` + BeInviteName string `json:"be_invite_name" description:"被邀请的人的姓名"` + SeminarActivityId int64 `json:"seminar_activity_id" description:"会话活动的id"` + BeInvitePhone string `json:"be_invite_phone" description:"被邀请的人的手机号码"` + MoreArea int64 `json:"more_area" description:"多地区 开启则只有该地区可以使用 [开启|关闭]"` + AreaId int64 `json:"area_id" description:"该活动下的地区Id"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否已经删除0未 1删"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/seminar_rule.go b/models/seminar_rule.go new file mode 100644 index 0000000..ca42ac6 --- /dev/null +++ b/models/seminar_rule.go @@ -0,0 +1,32 @@ +package models + +import ( + "time" +) + +//会务规则 +type SeminarRule struct { + Id int64 `json:"id"` + SeminarActivityId int64 `json:"seminar_activity_id" description:"会务活动的id"` + Theme string `json:"theme" description:"会务主题"` + SeminarIndex string `json:"seminar_index" description:"会务排序 {seminar_name:1,seminar_seat:2}"` + SeminarName string `json:"seminar_name" description:"会务主页名称"` + SeminarNameImage string `json:"seminar_name_image" description:"会务主页名称背景图片"` + SeminarNameStatus string `json:"seminar_name_status" description:"会务主页名称 开启|关闭"` + SeminarSeat string `json:"seminar_seat" description:"会务座位安排"` + SeminarSeatImage string `json:"seminar_seat_image" description:"会务座位安排背景图片"` + SeminarSeatStatus string `json:"seminar_seat_status" description:"会务座位安排 开启|关闭"` + SeminarQuestion string `json:"seminar_question" description:"会务常见问题"` + SeminarQuestionImage string `json:"seminar_question_image" description:"会务常见问题背景图片"` + SeminarQuestionStatus string `json:"seminar_question_status" description:"会务常见问题 开启|关闭"` + SeminarHotel string `json:"seminar_hotel" description:"会务酒店"` + SeminarHotelImage string `json:"seminar_hotel_image" description:"会务酒店背景图片"` + SeminarHotelStatus string `json:"seminar_hotel_status" description:"会务酒店 开启|关闭"` + SeminarProcess string `json:"seminar_process" description:"会务议程"` + SeminarProcessImage string `json:"seminar_process_image" description:"会务议程背景图片"` + SeminarProcessStatus string `json:"seminar_process_status" description:"会务议程 开启|关闭"` + StyleImageId string `json:"style_image_id" description:"样式 会务的样式表的id"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/seminar_style.go b/models/seminar_style.go new file mode 100644 index 0000000..882ac08 --- /dev/null +++ b/models/seminar_style.go @@ -0,0 +1,15 @@ +package models + +import ( + "time" +) + +//会务活动的样式 +type SeminarStyle struct { + Id int64 `json:"id"` + StyleName string `json:"style_name" description:"样式的名字"` + StyleImageUrl string `json:"style_image_url" description:"样式的图片地址"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} diff --git a/models/sensitive.go b/models/sensitive.go new file mode 100644 index 0000000..7268788 --- /dev/null +++ b/models/sensitive.go @@ -0,0 +1,40 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "strings" + "time" +) + +type Sensitive struct { + Id int64 `json:"id"` + Keyword string `json:"keyword" description:"关键字"` + Host string `json:"host" description:"二级域名"` + Category string `json:"category" description:"类别"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否已删除"` + CreateAt time.Time `json:"create_at" xorm:"created"` + UpdateAt time.Time `json:"update_at" xorm:"updated"` +} + +var ( + cacheSensitive = make([]*Sensitive, 0) + currentSensitiveTime = time.Time{} +) + +func GetSensitive() []*Sensitive { + if len(cacheSensitive) == 0 || time.Now().Sub(currentSensitiveTime).Hours() > 24 { + core.GetXormAuto().Where("is_delete=0").Find(&cacheSensitive) + currentSensitiveTime = time.Now() + } + return cacheSensitive +} + +//匹配是否包含敏感字眼 +func IsSensitive(str string) bool { + for _, v := range GetSensitive() { + if strings.Contains(str, v.Keyword) { + return true + } + } + return false +} diff --git a/models/shake_red_envelope_activity.go b/models/shake_red_envelope_activity.go new file mode 100644 index 0000000..1810ecf --- /dev/null +++ b/models/shake_red_envelope_activity.go @@ -0,0 +1,42 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const ShakeRedEnvelopeActivityTableName = TableNamePrefix + "shake_red_envelope_activity" + +//摇红包活动 +type ShakeRedEnvelopeActivity struct { + Id int64 `json:"id" xorm:"pk autoincr BIGINT(20)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动id') BIGINT(20)" description:"活动的id"` + RedEnvelopeActivityName string `json:"red_envelope_activity_name" xorm:"not null default('') comment('红包活动名字') VARCHAR(255)"` + ShakeRedEnvelopeRule *ShakeRedEnvelopeRule `json:"shake_red_envelope_rule" xorm:"-" description:"规则"` + MoreAreaMode string `json:"more_area_mode" xorm:"not null default('') comment('多地区') VARCHAR(125)"` + IsPay int `json:"is_pay" xorm:"not null default(0) comment('1支付0未支付') TINYINT(1)"` + TotalMoney float64 `json:"total_money" xorm:"not null comment('轮次的总金额') DECIMAL"` + EditTotalMoney float64 `json:"edit_total_money" xorm:"not null comment('修改后的总额') DECIMAL"` + FinalTotalMoney float64 `json:"final_total_money" xorm:"not null comment('最后总金额') DECIMAL" description:"最后总额"` + IsDelete bool `json:"is_delete" xorm:"default(0) comment('软删除') TINYINT(1)" description:"是否已删除"` + CreatedAt time.Time `json:"create_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"update_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *ShakeRedEnvelopeActivity) TableName() string { + return ShakeRedEnvelopeActivityTableName +} + +func (t *ShakeRedEnvelopeActivity) Alias(name string) string { + return AliasTableName(t, name) +} + +func (t *ShakeRedEnvelopeActivity) GetPayedById(id int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and is_pay=1 and id=?", id).Get(t) +} +func GetSREActivityIdsByActivityId(aid int64) ([]int64, error) { + shakeRbIds := make([]int64, 0) + err := core.GetXormAuto().Table(new(ShakeRedEnvelopeActivity)).Select("id"). + Where("is_delete=0 and activity_id=?", aid).Find(&shakeRbIds) + return shakeRbIds, err +} diff --git a/models/shake_red_envelope_record.go b/models/shake_red_envelope_record.go new file mode 100644 index 0000000..45ba539 --- /dev/null +++ b/models/shake_red_envelope_record.go @@ -0,0 +1,80 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const ShakeRedEnvelopeRecordTableName = TableNamePrefix + "shake_red_envelope_record" + +type ShakeRedEnvelopeRecord struct { + Id int64 `json:"id" xorm:"not null pk autoincr comment('主键') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default 0 comment('主活动id') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id/0正式') INT(11)"` + ShakeRedEnvelopeActivityId int64 `json:"shake_red_envelope_activity_id" xorm:"not null default 0 comment('摇红包活动id') INT(11)"` + ShakeRedEnvelopeRuleId int64 `json:"shake_red_envelope_rule_id" xorm:"not null default 0 comment('摇红包规则id') INT(11)"` + UserId int64 `json:"user_id" xorm:"not null default 0 comment('用户id') INT(11)"` + IsValid bool `json:"is_valid" xorm:"-"` + Name string `json:"name" xorm:"not null default '' comment('红包名字') VARCHAR(255)"` + UserName string `json:"user_name" xorm:"not null default '' comment('用户名字') VARCHAR(255)"` + UserPhone string `json:"user_phone" xorm:"not null default '' comment('用户电话') VARCHAR(18)"` + Amount float64 `json:"amount" xorm:"not null default '0' comment('金额') VARCHAR(18)"` + AreaId int64 `json:"area_id" xorm:"not null default 0 comment('地区id') INT(11)"` + AreaName string `json:"area_name" xorm:"not null default '' comment('地区名字') VARCHAR(18)"` + IsDraw int `json:"is_draw" xorm:"not null default(0) comment('-1未被摇中,0已被摇中,1已被提现')"` + Reason string `json:"reason" xorm:"not null default '' comment('失败原因') VARCHAR(32)"` + MchBillno string `json:"mch_billno" xorm:"not null default 0 comment('')"` + ReOpenid string `json:"re_openid" xorm:"not null default '' comment('接收红包用户openid') VARCHAR(32)"` + Status string `json:"status" xorm:"not null default '' comment('红包状态') VARCHAR(16)"` + RefundTime string `json:"refund_time" xorm:"not null default '' comment('红包退款时间') VARCHAR(32)"` + Version int `json:"version" xorm:"not null version comment('乐观锁') INT(11)"` + IsDelete bool `json:"-" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} + +func (t *ShakeRedEnvelopeRecord) TableName() string { + return ShakeRedEnvelopeRecordTableName +} + +func (t *ShakeRedEnvelopeRecord) ExistRecord(reid, aid, srid, said, uid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and rehearsal_id=? and activity_id=? and "+ + "shake_red_envelope_rule_id=? and shake_red_envelope_activity_id=? and user_id=?", + reid, aid, srid, said, uid).Exist(t) +} + +func (t *ShakeRedEnvelopeRecord) Total(aid, rid, said, srid int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and rehearsal_id=? and "+ + "shake_red_envelope_activity_id=? and shake_red_envelope_rule_id=?", aid, rid, said, srid).Count(t) +} + +func (t *ShakeRedEnvelopeRecord) Sum(aid, rid, said, srid int64) (float64, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and rehearsal_id=? and "+ + "shake_red_envelope_activity_id=? and shake_red_envelope_rule_id=?", aid, rid, said, srid). + Sum(t, "amount") + +} + +func (t *ShakeRedEnvelopeRecord) Count(aid, rid, said, srid int64, status int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0 and is_draw=? and activity_id=? and rehearsal_id=? and "+ + "shake_red_envelope_activity_id=? and shake_red_envelope_rule_id=?", status, aid, rid, said, srid).Count(t) +} + +func (t *ShakeRedEnvelopeRecord) GetByRuleId(ruleId, rehearsalId int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and is_draw=-1 and shake_red_envelope_rule_id=? and rehearsal_id=?", + ruleId, rehearsalId).Get(t) +} + +func (t *ShakeRedEnvelopeRecord) UpdateAllColsById(id int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0 and id=?", id).AllCols().Update(t) +} + +func GetRedEnvelopesByUserId(userId int64) ([]*ShakeRedEnvelopeRecord, error) { + records := make([]*ShakeRedEnvelopeRecord, 0) + err := core.GetXormAuto().Where("user_id=? and is_delete=0 and is_draw<>-1", userId). + Desc("created_at").Find(&records) + for index := range records { + records[index].IsValid = true + } + return records, err +} diff --git a/models/shake_red_envelope_rule.go b/models/shake_red_envelope_rule.go new file mode 100644 index 0000000..7b131ce --- /dev/null +++ b/models/shake_red_envelope_rule.go @@ -0,0 +1,59 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/utils/define" + "time" +) + +const ShakeRedEnvelopeRuleTableName = TableNamePrefix + "shake_red_envelope_rule" + +//摇红包活动规则 +type ShakeRedEnvelopeRule struct { + Id int64 `json:"id" xorm:"pk autoincr"` + ShakeRedEnvelopeActivityId int64 `json:"shake_red_envelope_activity_id" xorm:"not null comment('主活动id')" description:"主活动的id"` + ShakeRedEnvelopeRuleLadders []*ShakeRedEnvelopeRuleLadder `json:"shake_red_envelope_rule_ladders" xorm:"-" description:"阶梯红包"` + AreaId int64 `json:"area_id" xorm:"not null comment('地区id')" description:"地区id"` + Model string `json:"model" description:"[普通红包,随机红包,阶梯红包]"` + RedEnvelopeNum int64 `json:"red_envelope_num" xorm:"not null comment('红包个数')" description:"红包个数"` + RandSum float64 `json:"rand_sum" xorm:"decimal not null comment('红包总金额')"` + Single float64 `json:"single" description:"单个金额" xorm:"not null comment('单个金额')"` + Probability float64 `json:"probability" description:"概率[0-100)" xorm:"not null comment('概率')"` + Des string `json:"des" xorm:"not null default('根据对应得概率获得红包') comment('规则描述')"` + ShakeRedEnvelopeStatus string `json:"shake_red_envelope_status" xorm:"not null default('未开始') comment('未开始|进行中|已结束')"` + IsDelete bool `json:"-" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"-" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"-" xorm:"updated" description:"更新时间"` +} + +func (t *ShakeRedEnvelopeRule) TableName() string { + return ShakeRedEnvelopeRuleTableName +} + +func (t *ShakeRedEnvelopeRule) UpdateStatus(id int64, status string) (int64, error) { + t.ShakeRedEnvelopeStatus = status + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and id=?", id). + Cols("shake_red_envelope_status", "updated_at").Update(t) +} + +func (t *ShakeRedEnvelopeRule) UpdateToStatusBySids(sids []int64, before, after string) (int64, error) { + t.ShakeRedEnvelopeStatus = after + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and shake_red_envelope_status=? ", before). + In("shake_red_envelope_activity_id", sids).Cols("shake_red_envelope_status", "updated_at"). + Update(t) +} + +func (t *ShakeRedEnvelopeRule) GetCurrent(aid int64) (bool, error) { + return core.GetXormAuto().Table(t).Alias("r"). + Join("LEFT", new(ShakeRedEnvelopeActivity).Alias("a"), + "a.id=r.shake_red_envelope_activity_id and a.is_delete=0"). + Where("r.is_delete=0 and (r.shake_red_envelope_status=? or r.shake_red_envelope_status=?) and a.activity_id=?", + define.StatusReady, define.StatusRunning, aid).Get(t) +} + +func UpdateSRERuleStatusBySREActivityIds(ids []int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0").In("shake_red_envelope_activity_id", ids). + Update(&ShakeRedEnvelopeRule{ShakeRedEnvelopeStatus: define.StatusNotBegin}) +} diff --git a/models/shake_red_envelope_rule_ladder.go b/models/shake_red_envelope_rule_ladder.go new file mode 100644 index 0000000..caf769e --- /dev/null +++ b/models/shake_red_envelope_rule_ladder.go @@ -0,0 +1,24 @@ +package models + +import ( + "time" +) + +const ShakeRedEnvelopeRuleLadderTableName = TableNamePrefix + "shake_red_envelope_ladder" + +//摇红包规则阶梯 +type ShakeRedEnvelopeRuleLadder struct { + Id int64 `json:"id"` + ShakeRedEnvelopeRuleId int64 `json:"shake_red_envelope_rule_id" description:"红包轮次的id"` + RedEnvelopeNum int64 `json:"red_envelope_num" description:"红包个数"` + Probability float64 `json:"probability" description:"概率"` + Des string `json:"des" xorm:"-" description:"规则描述"` + Single float64 `json:"single" description:"单个金额"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +} + +func (t *ShakeRedEnvelopeRuleLadder) TableName() string { + return ShakeRedEnvelopeRuleLadderTableName +} diff --git a/models/shake_red_envelope_user.go b/models/shake_red_envelope_user.go new file mode 100644 index 0000000..42295bc --- /dev/null +++ b/models/shake_red_envelope_user.go @@ -0,0 +1,20 @@ +package models + +import "time" + +const ShakeRedEnvelopeUserTableName = TableNamePrefix + "shake_red_envelope_user" + +type ShakeRedEnvelopeUser struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id/0正式') INT(11)"` + ShakeRedEnvelopeActivityId int64 `json:"shake_red_envelope_activity_id" xrom:"not null comment('摇红包活动id') INT(11)"` + ShakeRedEnvelopeRuleId int64 `json:"shake_red_envelope_rule_id" xorm:"not null comment('轮次id') INT(11)"` + UserId int64 `json:"user_id" xorm:"not null comment('用户id') INT(11)"` + IsDelete int `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间')"` + UpdateAt time.Time `json:"update_at" xorm:"not null updated comment('更新时间')"` +} + +func (t *ShakeRedEnvelopeUser) TableName() string { + return ShakeRedEnvelopeUserTableName +} diff --git a/models/shake_red_envelope_wallet.go b/models/shake_red_envelope_wallet.go new file mode 100644 index 0000000..3e3c6c8 --- /dev/null +++ b/models/shake_red_envelope_wallet.go @@ -0,0 +1,13 @@ +package models + +import "time" + +//摇红包钱包 +type ShakeRedEnvelopeWallet struct { + Id int64 `json:"id"` + CustomerId int64 `json:"customer_id" description:"客户id"` + Balance float64 `json:"balance" description:"余额"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +} diff --git a/models/shake_red_envelope_wallet_history.go b/models/shake_red_envelope_wallet_history.go new file mode 100644 index 0000000..3935061 --- /dev/null +++ b/models/shake_red_envelope_wallet_history.go @@ -0,0 +1,19 @@ +package models + +import "time" + +//摇红包钱包历史 +type ShakeRedEnvelopeWalletHistory struct { + Id int64 `json:"id"` + CustomerId int64 `json:"customer_id" description:"客户id"` + HisBalance float64 `json:"his_balance" description:"历史余额"` + Type string `json:"type" description:"记录类型 充值、消费、转出、未领取、发送失败"` + RechargeType string `json:"recharge_type" description:"充值方式 支付宝、微信"` + Status string `json:"status" description:"交易状态"` + Account string `json:"account" description:"领取红包的账户"` + Money float64 `json:"money" description:"金额[分正负]"` + Mark string `json:"mark" description:"备注"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +} diff --git a/models/shake_red_envelope_winner.go b/models/shake_red_envelope_winner.go new file mode 100644 index 0000000..43db144 --- /dev/null +++ b/models/shake_red_envelope_winner.go @@ -0,0 +1,14 @@ +package models + +//摇红包中奖名单 +//type ShakeRedEnvelopeWinner struct { +// Id int64 `json:"id"` +// ShakeRedEnvelopeRuleId int64 `json:"shake_red_envelope_rule_id" description:"红包轮次的id"` +// Amount float64 `json:"amount" description:"金额"` +// UserId int64 `json:"user_id" description:"用户表得id"` +// User *User `json:"user" xorm:"-" description:"用户信息"` +// IsOpen bool `json:"is_open"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/sign_history.go b/models/sign_history.go new file mode 100644 index 0000000..9bfdb51 --- /dev/null +++ b/models/sign_history.go @@ -0,0 +1,31 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const SignHistoryTableName = TableNamePrefix + "sign_history" + +//签到历史表 +type SignHistory struct { + Id int64 `json:"id" xorm:"pk autoincr comment('主键') BIGINT(20)"` + AreaId int64 `json:"area_id" xorm:"not null default 0 comment('地区id') BIGINT(20)"` + ActivityId int64 `json:"activity_id" xorm:"not null default 0 comment('主活动id') BIGINT(20)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default 0 comment('彩排id/ 0正式') BIGINT(20)"` + SignRuleId int64 `json:"sign_rule_id" xorm:"not null default 0 comment('sign_up表id') BIGINT(20)"` + UserId int64 `json:"user_id" xorm:"not null default 0 comment('用户表id') BIGINT(20)"` + User *User `json:"user" xorm:"-" description:"用户得信息"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *SignHistory) TableName() string { + return SignHistoryTableName +} + +func (t *SignHistory) GetByUserId(aid, uid, rid, arid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and user_id=? and "+ + "rehearsal_id=? and area_id=?", aid, uid, rid, arid).Get(t) +} diff --git a/models/sign_rule.go b/models/sign_rule.go new file mode 100644 index 0000000..4fd7758 --- /dev/null +++ b/models/sign_rule.go @@ -0,0 +1,13 @@ +package models + +//签到规则 +//type SignRule struct { +// Id int64 `json:"id"` +// ActivityId int64 `json:"activity_id" description:"主活动签到活动的id"` +// SignModel string `json:"sign_model" description:"[普通签到|设备人脸识别|H5人脸识别|扫码签到|手环签到|手绘签到|ibeacon签到] 签到模式"` +// MaxModel string `json:"max_model" description:"[logo墙|数字看板|] 大屏类型"` +// OnlyEntered string `json:"only_entered" description:"[允许|不允许] 允许不报名的和不允许不报名的"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/sign_up.go b/models/sign_up.go new file mode 100644 index 0000000..8ae8b8e --- /dev/null +++ b/models/sign_up.go @@ -0,0 +1,28 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const SignUpTableName = TableNamePrefix + "sign_up" + +type SignUp struct { + Id int64 `json:"id"` + ActivityId int64 `json:"activity_id"` + Title string `json:"title"` + MaxModel string `json:"max_model"` + OnlyInvitation int `json:"only_invitation"` + LogoUrl string `json:"logo_url"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +} + +func (t *SignUp) TableName() string { + return SignUpTableName +} + +func (t *SignUp) GetByActivityId(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid).Get(t) +} diff --git a/models/test/config.json b/models/test/config.json new file mode 100644 index 0000000..bf79829 --- /dev/null +++ b/models/test/config.json @@ -0,0 +1,8 @@ +{ + "port": "20181", + "host": "0.0.0.0", + "cross_domain": "*", + "post_max_memory": 1024000, + "api_router": "/PcClient/*", + "update_path": "example_update" +} \ No newline at end of file diff --git a/models/test/private.json b/models/test/private.json new file mode 100644 index 0000000..af8778c --- /dev/null +++ b/models/test/private.json @@ -0,0 +1,11 @@ +{ + "db": { + "host": "gz-cdb-onvbcfqn.sql.tencentcdb.com", + "port": "61232", + "user": "root", + "password": "Pox2210XXa@", + "name": "hudongzhuanjia", + "prefix": "ox_", + "max_open_conn": 500 + } +} \ No newline at end of file diff --git a/models/test/sensitive_test.go b/models/test/sensitive_test.go new file mode 100644 index 0000000..6032441 --- /dev/null +++ b/models/test/sensitive_test.go @@ -0,0 +1,32 @@ +package test + +import ( + "github.com/360EntSecGroup-Skylar/excelize/v2" + "hudongzhuanjia/models" + "testing" + "time" +) + +func TestAddSensitive(t *testing.T) { + f, err := excelize.OpenFile("敏感词汇.xlsx") + if err != nil { + t.Fatal(err) + } + + rows, err := f.GetRows("big_audit_keyword") + for i, row := range rows { + if i == 0 { + continue + } + + if err := models.Save(nil, &models.Sensitive{ + Keyword: row[1], + Category: row[2], + Host: row[3], + CreateAt: time.Now(), + UpdateAt: time.Now(), + }, nil); err != nil { + t.Fatal(err) + } + } +} diff --git a/models/test/敏感词汇.xlsx b/models/test/敏感词汇.xlsx new file mode 100644 index 0000000..494b696 Binary files /dev/null and b/models/test/敏感词汇.xlsx differ diff --git a/models/tug_of_war.go b/models/tug_of_war.go new file mode 100644 index 0000000..bf399a7 --- /dev/null +++ b/models/tug_of_war.go @@ -0,0 +1,51 @@ +package models + +import ( + "hudongzhuanjia/utils/define" + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type TugOfWar struct { + Id int64 `json:"id" description:"主键"` + Model string `json:"model" description:"拔河模式.随机分配模式|H5挑选模式|大屏幕二维码模式"` + Status string `json:"status" description:"拔河活动状态[未开始,准备中,进行中,已结束]"` + Number int `json:"number" description:"预测人数"` + ActivityId int64 `json:"activity_id" description:"主活动id"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +} + +func (t *TugOfWar) TableName() string { + return TableNamePrefix + "tug_of_war" +} + +func (t *TugOfWar) GetByActivityId(aid int64, status string) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and status=?", aid, status). + Desc("created_at").Get(t) +} + +func (t *TugOfWar) GetCurrent(aid int64) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=? and (status=? or status=?)", + aid, define.StatusReady, define.StatusRunning).Get(t) +} + +func (t *TugOfWar) UpdateStatusById(id int64, status string) (int64, error) { + t.Status = status + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and id=?", id).Cols("status", "updated_at").Update(t) +} + +func (t *TugOfWar) UpdateToStatusByAid(aid int64, before, after string) (int64, error) { + t.Status = after + t.UpdatedAt = time.Now() + return core.GetXormAuto().Where("is_delete=0 and status=? and activity_id=?", before, aid). + Cols("status", "updated_at").Update(t) +} + +func UpdateTOWStatusByActivityId(aid int64) (int64, error) { + return core.GetXormAuto().Where("is_delete=0 and activity_id=?", aid). + Update(&TugOfWar{Status: define.StatusNotBegin}) +} diff --git a/models/ui_base.go b/models/ui_base.go new file mode 100644 index 0000000..d790138 --- /dev/null +++ b/models/ui_base.go @@ -0,0 +1,13 @@ +package models + +//背景图 +//type UiBase struct { +// Id int64 `json:"id"` +// ActivityId int64 `json:"activity_id" description:"主活动的id"` +// PhoneImageUrl string `json:"phone_image_url" description:"手机端通用背景地址"` +// MaxImageUrl string `json:"max_image_url" description:"互动大屏背景地址"` +// LogoUrl string `json:" logo_url" description:"自定义logo地址"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/upper_wall.go b/models/upper_wall.go new file mode 100644 index 0000000..19236f9 --- /dev/null +++ b/models/upper_wall.go @@ -0,0 +1,23 @@ +package models + +import ( + "time" +) + +//上墙 +type UpperWall struct { + Id int64 `json:"id" xorm:"pk autoincr INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('主活动id') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排、0正式') INT(11)"` + Category string `json:"category" xorm:"not null comment('类型[1文本|2图片|3图片+文本]') INT(11)"` + UserId int64 `json:"user_id" xorm:"not null comment('用户得id') INT(11)"` + User *User `json:"user" xorm:"-" description:"用户信息"` + Content string `json:"content" xorm:"comment('内容') text" ` + Img string `json:"img" xorm:"comment('图片') text" description:"图片"` + Imgs []string `json:"imgs" xorm:"-" description:"图片数组"` + Status int `json:"status" xorm:"not null default(0) comment('0未审核,1未通过,2已通过,3已推送') INT(11)"` + ReviewTime int64 `json:"review_time" xorm:"not null default(0) comment('审核的时间,10位') INT(11)"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +} diff --git a/models/user.go b/models/user.go new file mode 100644 index 0000000..488dcf2 --- /dev/null +++ b/models/user.go @@ -0,0 +1,58 @@ +package models + +import ( + "time" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +const UserTableName = TableNamePrefix + "user" + +//用户 +type User struct { + Id int64 `json:"id" xorm:"pk autoincr"` + Phone string `json:"phone" description:"手机号码"` + Code string `json:"code" description:"验证码"` + City string `json:"city" xorm:"not null"` + Province string `json:"province" xorm:"not null"` + Country string `json:"country"` + Unionid string `json:"unionid" description:"unionid"` + Openid string `json:"openid" description:"openid"` + AccessToken string `json:"access_token" description:"token"` + Nickname string `json:"nickname" description:"昵称"` + Avatar string `json:"avatar" description:"头像"` + Gender string `json:"gender" description:"性别[男,女]"` + Balance float64 `json:"balance" description:"余额"` + ActivityId int64 `json:"activity_id" description:"主活动id"` // 不存在 + AreaId int64 `json:"area_id" description:"地区id"` // 不存在 + AreaName string `json:"area_name" description:"地区名字"` + IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +} + +func (t *User) TableName() string { + return UserTableName +} + +func (t *User) Alias(name string) string { + return AliasTableName(t, name) +} + +func (t *User) GetUserByOpenid(openId string) (bool, error) { + return core.GetXormAuto().Where("openid=?", openId).Get(t) +} + +func (t *User) SaveAndUpdateWithOpenId() error { + exist, err := core.GetXormAuto().Table("ox_user"). + Where("openid=?", t.Openid).Exist() + if err != nil { + return err + } + if !exist { + _, err := core.GetXormAuto().Insert(t) + return err + } + _, err = core.GetXormAuto().Where("openid=?", t.Openid).AllCols().Update(t) + return err +} diff --git a/models/user_order.go b/models/user_order.go new file mode 100644 index 0000000..2d6652d --- /dev/null +++ b/models/user_order.go @@ -0,0 +1,39 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const UserOrderTableName = TableNamePrefix + "user_order" + +type UserOrder struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + DeviceInfo string `json:"device_info" xorm:"not null default('') comment('设备号') VARCHAR(32)"` + GoodType int `json:"good_type" xorm:"not null default(0) comment('1霸屏2打赏')"` + Desc string `json:"desc" xorm:"not null default('') comment('') VARCHAR(128)"` + OutTradeNo string `json:"out_trade_no" xorm:"not null default('') comment('商户订单号') VARCHAR(32)"` + FeeType string `json:"fee_type" xorm:"not null default('CNY') comment('货币种类') VARCHAR(16)"` + TotalFee int `json:"total_fee" xorm:"not null default(0) comment('订单总金额,单位是分') INT(88)"` + TradeType string `json:"trade_type" xorm:"not null default('JSAPI') comment('交易类型') VARCHAR(16)"` + OpenId string `json:"open_id" xorm:"not null default('') comment('用户标识') VARCHAR(128)"` + UserId int64 `json:"user_id" xorm:"not null default(0) comment('用户id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default(0) comment('活动id') INT(11)"` + TransactionId string `json:"transaction_id" xorm:"not null default('') comment('微信支付订单号') VARCHAR(32)"` + TimeStart string `json:"time_start" xorm:"not null default('') comment('交易起始时间') VARCHAR(14)"` + TimeExpire string `json:"time_expire" xorm:"not null default('') comment('交易结束时间') VARCHAR(14)"` + TimeEnd string `json:"time_end" xorm:"not null default('') comment('交易结算时间') VARCHAR(14)"` + PrepayId string `json:"prepay_id" xorm:"not null default('') comment('预支付交易会话标识') VARCHAR(64)"` + Status int `json:"status" xorm:"not null default(0) comment('-1订单关闭0尚未支付1支付成功') TINYINT(1)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"` +} + +func (t *UserOrder) TableName() string { + return UserOrderTableName +} + +func (t *UserOrder) GetByOutTradeNo(no string) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and out_trade_no=?", no).Get(t) +} diff --git a/models/user_prize.go b/models/user_prize.go new file mode 100644 index 0000000..04ec442 --- /dev/null +++ b/models/user_prize.go @@ -0,0 +1,31 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const UserPrizeTableName = TableNamePrefix + "user_prize" + +type UserPrize struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + UserId int64 `json:"user_id" xorm:"not null comment('用户表id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null comment('互动表id') INT(11)"` + RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id') INT(11)"` + ActivityName string `json:"activity_name" xorm:"not null default('') comment('互动名字') VARCHAR(128)"` + PrizeName string `json:"prize_name" xorm:"not null default('') comment('奖品名字') VARCHAR(128)"` + PrizeImg string `json:"prize_img" xorm:"not null default('') comment('奖品图片') VARCHAR(255)"` + PrizeType int `json:"prize_type" xorm:"not null default(0) comment('订单来源1普通抽奖2订单抽奖3订单送礼') INT(11)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} + +func (t *UserPrize) TableName() string { + return UserPrizeTableName +} + +func (t *UserPrize) SoftDeleteById(id int64) (int64, error) { + t.IsDelete = true + return core.GetXormAuto().Id(id).Cols("is_delete").Update(t) +} diff --git a/models/user_red_pack.go b/models/user_red_pack.go new file mode 100644 index 0000000..8844274 --- /dev/null +++ b/models/user_red_pack.go @@ -0,0 +1,35 @@ +package models + +import "time" + +const UserRedPackTableName = TableNamePrefix + "user_red_pack" + +// todo: 红包号码 +type UserRedPack struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + MchBillno string `json:"mch_billno" xorm:"not null default('') comment('商户订单号') VARCHAR(28)"` + SendName string `json:"send_name" xorm:"not null default('') comment('商户名称') VARCHAR(32)"` + ReOpenid string `json:"re_openid" xorm:"not null default '' comment('接收红包用户openid') VARCHAR(32)"` + TotalAmount int `json:"total_amount" xorm:"not null default 0 comment('付款金额, 单位分') INT(11)"` + TotalNum int `json:"total_num" xorm:"not null default 0 comment('红包发放总人数') INT(11)"` + SceneId int `json:"scene_id" xorm:"not null default 0 comment('场景id') INT(11)"` + SendListid string `json:"send_listid" xorm:"not null default '' comment('红包订单的微信单号') VARCHAR(32)"` + Status string `json:"status" xorm:"not null default '' comment('红包状态') VARCHAR(16)"` + HbType string `json:"hb_type" xorm:"not null default '' comment('红包类型') VARCHAR(32)"` + Reason string `json:"reason" xorm:"not null default '' comment('失败原因') VARCHAR(32)"` + SendTime string `json:"send_time" xorm:"not null default '' comment('红包发送时间') VARCHAR(32)"` + RefundTime string `json:"refund_time" xorm:"not null default '' comment('红包退款时间') VARCHAR(32)"` + RefundAmount string `json:"refund_amount" xorm:"not null default '' comment('红包退款金额') VARCHAR(32)"` + ResultCode string `json:"result_code" xorm:"not null default '' comment('业务结果') VARCHAR(16)"` + ErrCode string `json:"err_code" xorm:"not null default '' comment('错误代码') VARCHAR(32)"` + ErrCodeDes string `json:"err_code_des" xorm:"not null default '' comment('错误代码描述') VARCHAR(128)"` + UserId int64 `json:"user_id" xorm:"not null default 0 comment('用户id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default 0 comment('互动id') INT(11)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"` +} + +func (t *UserRedPack) TableName() string { + return UserRedPackTableName +} diff --git a/models/user_refund.go b/models/user_refund.go new file mode 100644 index 0000000..b481638 --- /dev/null +++ b/models/user_refund.go @@ -0,0 +1,38 @@ +package models + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +const UserRefundTableName = TableNamePrefix + "user_refund" + +type UserRefund struct { + Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"` + GoodType int `json:"good_type" xorm:"not null default(0) comment('1霸屏2打赏')"` + RefundDesc string `json:"refund_desc" xorm:"not null default('') comment('') VARCHAR(128)"` + WxRefundId string `json:"wx_refund_id" xorm:"not null default '' comment('微信退单号') VARCHAR(32)"` + TransactionId string `json:"transaction_id" xorm:"not null default '' comment('微信订单号')"` + OutTradeNo string `json:"out_trade_no" xorm:"not null default '' comment('商户订单号') VARCHAR(32)"` + FeeType string `json:"fee_type" xorm:"not null default 'CNY' comment('货币种类') VARCHAR(16)"` + TotalFee int `json:"total_fee" xorm:"not null default 0 comment('订单总金额,单位是分') INT(88)"` + OpenId string `json:"open_id" xorm:"not null default '' comment('用户标识') VARCHAR(128)"` + UserId int64 `json:"user_id" xorm:"not null default 0 comment('用户id') INT(11)"` + ActivityId int64 `json:"activity_id" xorm:"not null default 0 comment('互动id') INT(11)"` + RefundStatus string `json:"refund_status" xorm:"not null default '' comment('微信退款状态') VARCHAR(16)"` + Status int `json:"status" xorm:"not null default 0 comment('0未查询,1已查询') TINYINT(1)"` + SuccessTime string `json:"success_time" xorm:"not null default '' comment('退款成功时间') VARCHAR(20)"` + RefundRecvAccount string `json:"refund_recv_account" xorm:"not null default '' comment('入账账号') VARCHAR(64)"` + RefundAccount string `json:"refund_account" xorm:"not null default '' comment('入账账号') VARCHAR(64)"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)" description:"是否删除"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"` +} + +func (t *UserRefund) TableName() string { + return UserRefundTableName +} + +func (t *UserRefund) GetByOutRefundNo(no string) (bool, error) { + return core.GetXormAuto().Where("is_delete=0 and out_refund_no=?", no).Get(t) +} diff --git a/models/user_wallet_history.go b/models/user_wallet_history.go new file mode 100644 index 0000000..37af62b --- /dev/null +++ b/models/user_wallet_history.go @@ -0,0 +1,16 @@ +package models + +import ( + "time" +) + +//用户得钱包流水 +type UserWalletHistory struct { + Id int64 `json:"id" xorm:"pk autoincr INT(11)"` + UserId int64 `json:"user_id" xorm:"not null comment('用户id') INT(11)"` + Amount float64 `json:"amount" xorm:"not null comment('金额, 分正负') DECIMAL"` + Mark string `json:"mark" xorm:"not null comment('备注') VARCHAR(125)"` + IsDelete bool `json:"is_delete" xorm:"default(0) comment('软删除') TINYINT(1)"` + CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME"` + UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME"` +} diff --git a/models/vote_activity.go b/models/vote_activity.go new file mode 100644 index 0000000..0d52d08 --- /dev/null +++ b/models/vote_activity.go @@ -0,0 +1,12 @@ +package models + +//投票活动 +//type VoteActivity struct { +// Id int64 `json:"id"` +// ActivityId int64 `json:"activity_id" description:"活动的id"` +// VoteActivityName string `json:"vote_activity_name" description:"投票轮次名称"` +// VoteRule *VoteRule `json:"vote_rule" xorm:"-" description:"投票规则"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/vote_envelope_wallet.go b/models/vote_envelope_wallet.go new file mode 100644 index 0000000..1ac6a0e --- /dev/null +++ b/models/vote_envelope_wallet.go @@ -0,0 +1,11 @@ +package models + +////投票得红包钱包 +//type VoteEnvelopeWallet struct { +// Id int64 `json:"id"` +// CustomerId int64 `json:"customer_id" description:"客户id"` +// Balance float64 `json:"balance" description:"余额"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/vote_history.go b/models/vote_history.go new file mode 100644 index 0000000..4b07b37 --- /dev/null +++ b/models/vote_history.go @@ -0,0 +1,13 @@ +package models + +// +////投票历史表 +//type VoteHistory struct { +// Id int64 `json:"id"` +// VoteRuleId int64 `json:"vote_rule_id" description:"投票规则的id"` +// UserId int64 `json:"user_id" description:"用户id"` +// VoteRuleLadderId int64 `json:"vote_rule_ladder_id" description:"投票规则阶梯id"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/vote_rule.go b/models/vote_rule.go new file mode 100644 index 0000000..3b44eb9 --- /dev/null +++ b/models/vote_rule.go @@ -0,0 +1,30 @@ +package models + +////投票规则 +//type VoteRule struct { +// Id int64 `json:"id"` +// VoteActivityId int64 `json:"vote_activity_id" description:"投票的id"` +// AreaId int64 `json:"area_id" description:"地区id"` +// Theme string `json:"theme" description:"投票主题"` +// JoinWay string `json:"join_way" description:"参与方式"` +// Description string `json:"description" description:"投票描述"` +// Model string `json:"model" description:"[单选|多选]"` +// StyleImageId int64 `json:"style_image_id" description:"投票的样式表的id"` +// Style *VoteStyle `json:"style" xorm:"-" description:"投票样式表"` +// VoteRuleLadders []*VoteRuleLadder `json:"vote_rule_ladders" xorm:"-" description:"投票的物品或人"` +// Repeat string `json:"repeat" description:"[允许|不允许] 重复投票"` +// RcCode string `json:"rc_code" description:"链接地址或者二维码地址"` +// ResultDisplay string `json:"result_display" description:"[百分比|票数]"` +// ResultOrder string `json:"result_order" description:"[添加顺序|多到少|少到多]"` +// ResultLimit int64 `json:"result_limit" description:"默认显示多少名"` +// DisplayVoteNumber string `json:"display_vote_number" description:"[显示|不显示] 投票人数"` +// PhoneVoteDisplayResult string `json:"phone_vote_display_result" description:"[显示|不显示] 手机端投票是否显示结果"` +// VoteNeedNameAndPhone string `json:"vote_need_name_and_phone" description:"[需要|不需要] 投票是否需要名字和手机号码"` +// VoteByCommittee string `json:"vote_by_committee" description:"[指定|不指定] 是否指定评委来投票"` +// VoteBySignUser string `json:"vote_by_sign_user" description:"[指定|不指定] 是否指定签到用户投票"` +// UseTimes int `json:"use_times" description:"使用次数"` +// VoteStatus string `json:"vote_status" description:"投票活动的状态[可投票|不可投票]"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/vote_rule_ladder.go b/models/vote_rule_ladder.go new file mode 100644 index 0000000..c5f984f --- /dev/null +++ b/models/vote_rule_ladder.go @@ -0,0 +1,14 @@ +package models + +////投票规则阶梯 +//type VoteRuleLadder struct { +// Id int64 `json:"id"` +// VoteRuleId int64 `json:"vote_rule_id" description:"投票规则的id"` +// VoteNumber int64 `json:"vote_number" description:"投票的初始票数"` +// VoteMember string `json:"vote_member" description:"被投票的人员名字"` +// MemberImg string `json:"member_img" description:"被投票的人员图片"` +// VoteTotal int64 `json:"vote_total" xorm:"-" description:"投票的总数"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/vote_style.go b/models/vote_style.go new file mode 100644 index 0000000..f46e5b1 --- /dev/null +++ b/models/vote_style.go @@ -0,0 +1,11 @@ +package models + +//投票样式 +//type VoteStyle struct { +// Id int64 `json:"id"` +// StyleName string `json:"style_name" description:"样式的名字"` +// StyleImageUrl string `json:"style_image_url" description:"样式的图片地址"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/vote_wallet_history.go b/models/vote_wallet_history.go new file mode 100644 index 0000000..ccfd1a0 --- /dev/null +++ b/models/vote_wallet_history.go @@ -0,0 +1,12 @@ +package models + +//投票钱包历史 +//type VoteWalletHistory struct { +// Id int64 `json:"id"` +// CustomerId int64 `json:"customer_id" description:"客户id"` +// Money float64 `json:"money" description:"金额[分正负]"` +// Mark string `json:"mark" description:"备注"` +// IsDelete bool `json:"is_delete" xorm:"default(0)" description:"是否删除"` +// CreatedAt time.Time `json:"created_at" xorm:"created" description:"创建时间"` +// UpdatedAt time.Time `json:"updated_at" xorm:"updated" description:"更新时间"` +//} diff --git a/models/wechat_ticket.go b/models/wechat_ticket.go new file mode 100644 index 0000000..17b7291 --- /dev/null +++ b/models/wechat_ticket.go @@ -0,0 +1,15 @@ +package models + +import "time" + +type WeChatTicket struct { + Id int64 `json:"id" xorm:"pk autoincr"` + Url string `json:"url" xorm:"not null comment('路径')"` + Token string `json:"-" xorm:"not null comment('token')"` + TokenExpired int64 `json:"ticket_expired" xorm:"not null default(0) comment('token过期时间')"` + Ticket string `json:"ticket" xorm:"not null comment('ticket')"` + TicketExpired int64 `json:"ticket_expired" xorm:"not null default(0) comment('ticket 过期时间')"` + IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('删除')"` + CreatedAt time.Time `json:"created_at" xorm:"created comment('创建')"` + UpdatedAt time.Time `json:"updated_at" xorm:"updated comment('更新')"` +} diff --git a/private.json b/private.json new file mode 100644 index 0000000..af8778c --- /dev/null +++ b/private.json @@ -0,0 +1,11 @@ +{ + "db": { + "host": "gz-cdb-onvbcfqn.sql.tencentcdb.com", + "port": "61232", + "user": "root", + "password": "Pox2210XXa@", + "name": "hudongzhuanjia", + "prefix": "ox_", + "max_open_conn": 500 + } +} \ No newline at end of file diff --git a/services/activity/activity.go b/services/activity/activity.go new file mode 100644 index 0000000..74bf52d --- /dev/null +++ b/services/activity/activity.go @@ -0,0 +1,189 @@ +package activity_service + +import ( + "fmt" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/define" +) + +func GetActivitiesByCustomerId(cid int64) ([]*models.Activity, error) { + // 登陆限制 + // 获取用户拥有的activity + activities := make([]*models.Activity, 0) + err := core.GetXormAuto().Where("is_delete=0 and customer_id=?", cid). + Desc("created_at").Find(&activities) + if err != nil { + return nil, err + } + // customer -> activity -> activity module service -> module service history -> module service + // customer -> activity -> 某次具体的活动(已经启动了的) + aids := make([]int64, 0) + for _, activity := range activities { + aids = append(aids, activity.Id) + } + + areaStores := make([]*models.AreaStore, 0) + err = core.GetXormAuto().Where("is_delete=0").In("activity_id", aids).Find(&areaStores) + if err != nil { + return nil, err + } + + for j := range activities { + for i := range areaStores { + if areaStores[i].ActivityId == activities[j].Id { + activities[j].AreaStores = append(activities[j].AreaStores, areaStores[i]) + } + } + } + + services := make([]*models.ActivityModuleService, 0) + err = core.GetXormAuto().Where("is_delete=0 and service_module_status=?", "开启"). + In("activity_id", aids).Find(&services) + if err != nil { + return nil, err + } + + hids := make([]int64, 0) + for _, service := range services { + hids = append(hids, service.ServiceModuleHistoryId) + } + + histories := make([]*models.ModuleServiceHistory, 0) + err = core.GetXormAuto().Where("is_delete=0").In("id", hids).Find(&histories) + if err != nil { + return nil, err + } + + for j := range services { + for i := range histories { + if histories[i].Id == services[j].ServiceModuleHistoryId { + services[j].ServiceModuleName = histories[i].Name + break + } + } + } + + for j := range activities { + for i := range services { + if activities[j].Id == services[i].ActivityId { + activities[j].Services = append(activities[j].Services, services[i]) + } + } + } + return activities, nil +} + +func GetActivityById(id int64) (*models.Activity, bool, error) { + activity := new(models.Activity) + exist, err := models.GetById(activity, id) + if err != nil || !exist { + return nil, exist, err + } + services := make([]*models.ActivityModuleService, 0) + err = core.GetXormAuto().Where("is_delete=0 and activity_id=? and service_module_status=?", id, define.StatusOpen). + Find(&services) + if err != nil { + return nil, false, err + } + + hids := make([]int64, 0) + for _, service := range services { + hids = append(hids, service.ServiceModuleHistoryId) + } + histories := make([]*models.ModuleServiceHistory, 0) + err = core.GetXormAuto().Where("is_delete=0").In("id", hids).Find(&histories) + if err != nil { + return nil, false, err + } + + for j := range services { + for i := range histories { + if histories[i].Id == services[j].ServiceModuleHistoryId { + services[j].ServiceModuleName = histories[i].Name + break + } + } + } + activity.Services = services + + // 增加对上墙 霸屏 弹幕 打赏 + mServer := new(models.MsgWallServer) + exist, err = mServer.GetByActivityId(id) + if err != nil { + return nil, false, err + } + if !exist { + activity.UpperWallStatus = define.StatusClose + } else { + activity.UpperWallStatus = mServer.UpWallStatus + } + + rServer := new(models.RewardServer) + exist, err = rServer.GetByActivityId(id) + if err != nil { + return nil, false, err + } + if !exist { + activity.RewardStatus = define.StatusClose + } else { + activity.RewardStatus = rServer.ServerStart + } + + dServer := new(models.DanMuServer) + exist, err = dServer.GetByActivityId(id) + if err != nil { + return nil, false, err + } + if !exist { + activity.BarrageStatus = define.StatusClose + } else { + activity.BarrageStatus = dServer.DanmuSwitch + } + + bServer := new(models.BullyScreenServer) + exist, err = bServer.GetByActivityId(id) + if err != nil { + return nil, false, err + } + if !exist { + activity.BullyScreenStatus = define.StatusClose + } else { + activity.BullyScreenStatus = bServer.Start + } + return activity, true, nil +} + +func ExistModuleByActivityId(aid int64, module string) (bool, error) { + switch module { + case define.MODULE_TUGWAR: // 拔河 + bahe := new(models.TugOfWar) + return bahe.GetCurrent(aid) + case define.MODULE_ORDER: //下订单 + option := new(models.CustomerOrderOption) + return option.GetOpen(aid) + case define.MODULE_SHAKRB: //摇红包 + rule := new(models.ShakeRedEnvelopeRule) + return rule.GetCurrent(aid) + case define.MODULE_AUCTION: // 竞拍 + auction := new(models.NewAuctionActivity) + return auction.GetCurrent(aid) + case define.MODULE_VOTE: + vote := new(models.NewVoteActivity) + return vote.GetCurrent(aid) + case define.MODULE_CALORIE: + calorie := new(models.Calorie) + return calorie.GetCurrent(aid) + case define.MODULE_BARRAGE: + fallthrough + case define.MODULE_BULLYS: + fallthrough + case define.MODULE_REWARD: + fallthrough + case define.MODULE_UPPERW: + return true, nil + + default: + return false, fmt.Errorf("不存在该活动模块") + } +} diff --git a/services/activity/module.go b/services/activity/module.go new file mode 100644 index 0000000..f9236e9 --- /dev/null +++ b/services/activity/module.go @@ -0,0 +1,19 @@ +package activity_service + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/models" +) + +func GetModuleService(moduleName string, activityId int64) (*models.ActivityModuleService, bool, error) { + hids := make([]int64, 0) + err := core.GetXormAuto().Table(new(models.ModuleServiceHistory)).Select("id"). + Where("is_delete=0 and name=?", moduleName).Find(&hids) + if err != nil { + return nil, false, err + } + moduleService := new(models.ActivityModuleService) + exist, err := core.GetXormAuto().Where("is_delete=0 and activity_id=?", activityId). + In("service_module_history_id", hids).Get(moduleService) + return moduleService, exist, err +} diff --git a/services/auction/auction.go b/services/auction/auction.go new file mode 100644 index 0000000..2eccd9c --- /dev/null +++ b/services/auction/auction.go @@ -0,0 +1,103 @@ +package auction_service + +import ( + "errors" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/define" + "strconv" + "time" +) + +func GetCurrentAuction(aid, rid, uid int64) (map[string]interface{}, error) { + auction := new(models.NewAuctionActivity) + exist, err := auction.GetCurrent(aid) + if err != nil { + return nil, err + } + if !exist { + return nil, errors.New("轮次尚未开启") + } + + // 计算当前价格 和 当前数量 + if auction.AuctionModel == define.INCR_AUCTION { // 加价竞拍 最高价格 + history := new(models.AuctionHistory) + exist, err = history.GetHighestMoney(rid, auction.Id) + if err != nil { + return nil, err + } + if !exist { + auction.CurrentMoney = auction.StartPrice + } else { + auction.CurrentMoney = history.Money + } + } else { // 初始价格 - (竞拍时长 - (竞拍结束时间 - 现在时间)) * 减价速率 + if auction.AuctionEndTime == 0 { + auction.CurrentMoney = auction.StartPrice + } else { + duration, _ := strconv.ParseInt(auction.AuctionDuration, 10, 64) + reduceRate, _ := strconv.ParseInt(auction.ReduceRate, 10, 64) + money := auction.StartPrice - float64((duration-(auction.AuctionEndTime-time.Now().Unix()))*reduceRate) + auction.CurrentMoney = money + } + record := new(models.AuctionResultRecord) + count, err := record.CountHistory(rid, aid) + if err != nil { + return nil, err + } + auction.GoodsNum -= int(count) + } + + player := new(models.AuctionPlayer) + exist, err = player.GetByAuctionIdAndUid(auction.Id, uid, rid) + if err != nil { + return nil, err + } + if !exist { + // 领取号码, 开启事务: 获取人数和写入人数 保证原子性 + session := core.GetXormAuto().NewSession() + if session.Begin(); err != nil { // 开启事务 + return nil, err + } + num, err := session.Where("is_delete=0 and auction_activity_id=? and rehearsal_id=?", auction.Id, rid).Count(player) + if err != nil { + session.Rollback() + return nil, err + } + player.AuctionActivityId = auction.Id + player.UserId = uid + player.RehearsalId = rid + player.Code = num + 1 + player.UpdatedAt = time.Now() + player.CreatedAt = time.Now() + _, err = session.Insert(player) + if err != nil { + session.Rollback() + return nil, err + } + session.Commit() + } + return map[string]interface{}{ + "auction": auction, + "player": player, + }, nil +} + +type UserAuctionsResult struct { + Id int64 `json:"id"` + AuctionActivityId int64 `json:"auction_activity_id"` + AuctionGoodsName string `json:"auction_goods_name"` + GoodsPicUrl string `json:"goods_pic_url"` + DealPrice float64 `json:"deal_price"` + Unit int64 `json:"unit"` +} + +func GetUserAuctions(activityId, userId int64) ([]*UserAuctionsResult, error) { + records := make([]*UserAuctionsResult, 0) + err := core.GetXormAuto().Table(new(models.AuctionResultRecord)).Alias("r"). + Select("r.id, a.id as auction_activity_id, a.auction_goods_name, a.goods_pic_url, r.deal_price, a.unit"). + Join("LEFT", new(models.NewAuctionActivity).Alias("a"), "a.id=r.auction_activity_id and a.is_delete=0"). + Where("r.is_delete=0 and r.activity_id=? and r.user_id=?", activityId, userId). + Desc("r.created_at").Find(&records) + return records, err +} diff --git a/services/bahe/score.go b/services/bahe/score.go new file mode 100644 index 0000000..4c10b42 --- /dev/null +++ b/services/bahe/score.go @@ -0,0 +1,30 @@ +package bahe_service + +import ( + "hudongzhuanjia/models" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +func GetScoreByTeamId(tid, rid int64) (int64, error) { + return core.GetXormAuto().Where("team_id=? and rehearsal_id=?", tid, rid). + SumInt(&models.BaheTeamMember{}, "score") +} + +func GetUsersByBaheActivityId(id int64) []*models.BaheTeamMember { + teams := make([]*models.BaheTeam, 0) + err := core.GetXormAuto().Where("bahe_activity_id=? and is_delete=?", id, false).Find(&teams) + if err != nil { + return nil + } + teamIds := make([]int64, 0) + for i := range teams { + teamIds = append(teamIds, teams[i].Id) + } + members := make([]*models.BaheTeamMember, 0) + err = core.GetXormAuto().In("team_id", teamIds).Find(&members) + if err != nil { + return nil + } + return members +} diff --git a/services/bahe/tug_war.go b/services/bahe/tug_war.go new file mode 100644 index 0000000..f3c71a6 --- /dev/null +++ b/services/bahe/tug_war.go @@ -0,0 +1,71 @@ +package bahe_service + +import ( + "fmt" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/define" + + "github.com/ouxuanserver/osmanthuswine/src/core" +) + +type CountMembersResult struct { + Number int `json:"number,omitempty"` + TeamId int64 `json:"team_id,omitempty"` + Color string `json:"color,omitempty"` +} + +func CountMembers(baheId int64) ([]*CountMembersResult, error) { + result := make([]*CountMembersResult, 0) + err := core.GetXormAuto().Table(new(models.BaheTeam)).Alias("t"). + Select("count(m.id) as number, t.id as team_id, t.bahe_team_name as color"). + Join("left", "ox_bahe_team_member as m", "m.team_id=t.id and m.is_delete=0"). + Where("t.is_delete=0 and t.bahe_activity_id = ?", baheId).Desc("color"). + GroupBy("t.id").Find(&result) + return result, err +} + +func GetMember(bid, rid, uid int64) (*models.BaheTeamMember, bool, error) { + member := new(models.BaheTeamMember) + exist, err := core.GetXormAuto().Where("is_delete=0 and rehearsal_id=? and "+ + "bahe_activity_id=? and member_id=?", rid, bid, uid).Get(member) + return member, exist, err +} + +func GetCurrentTugWar(aid, uid, rid int64) (map[string]interface{}, error) { + bahe := new(models.TugOfWar) + exist, err := bahe.GetCurrent(aid) + if err != nil { + return nil, err + } + if !exist { + return nil, fmt.Errorf("轮次尚未开启") + } + + member := new(models.BaheTeamMember) + exist, err = member.GetMemberByBaheIdAndUserId(uid, bahe.Id, rid) + if err != nil { + return nil, err + } + if exist { + return map[string]interface{}{ + "member": member, + }, nil + } + if bahe.Model == define.TUGWAR_MODEL_RANDOM { + return map[string]interface{}{ + "model": bahe.Model, + "bahe_activity_id": bahe.Id, + }, nil + } + + res, err := CountMembers(bahe.Id) + if err != nil { + return nil, err + } + return map[string]interface{}{ + "list": res, + "model": bahe.Model, + "bahe_activity_id": bahe.Id, + "limit": bahe.Number, + }, nil +} diff --git a/services/balance/balance.go b/services/balance/balance.go new file mode 100644 index 0000000..ddced62 --- /dev/null +++ b/services/balance/balance.go @@ -0,0 +1,34 @@ +package balance_service + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "time" +) + +func IncrUserBalance(id int64, balance float64) (int64, error) { + res, err := core.GetXormAuto().Exec("update ox_user set balance=balance+?, updated_at=? "+ + "where id=? and ox_user.is_delete=0", balance, time.Now(), id) + if err != nil { + return 0, err + } + return res.RowsAffected() +} + +func IncrRewardBalance(cid int64, balance float64) (int64, error) { + res, err := core.GetXormAuto().Exec("update ox_reward_wallet set balance=balance+?, updated_at=? "+ + "where customer_id=? and is_delete=0", balance, time.Now(), cid) + if err != nil { + return 0, err + } + + return res.RowsAffected() +} + +func IncrBullyScreenBalance(cid int64, balance float64) (int64, error) { + res, err := core.GetXormAuto().Exec("update ox_bully_screen_wallet set balance=balance+?, update_at=? "+ + "Where customer_id=? and is_delete=0", balance, time.Now(), cid) + if err != nil { + return 0, err + } + return res.RowsAffected() +} diff --git a/services/bully_screen/current.go b/services/bully_screen/current.go new file mode 100644 index 0000000..d591c24 --- /dev/null +++ b/services/bully_screen/current.go @@ -0,0 +1,20 @@ +package bully_screen_service + +import ( + "errors" + "hudongzhuanjia/models" +) + +func GetCurrentBullyScreen(activityId int64) (map[string]interface{}, error) { + server := new(models.BullyScreenServer) + exist, err := server.GetByActivityId(activityId) + if err != nil { + return nil, err + } + if !exist { + return nil, errors.New("霸屏不存在") + } + return map[string]interface{}{ + "bully_screen": server, + }, nil +} diff --git a/services/bully_screen/dao.go b/services/bully_screen/dao.go new file mode 100644 index 0000000..fa2e678 --- /dev/null +++ b/services/bully_screen/dao.go @@ -0,0 +1,21 @@ +package bully_screen_service + +import ( + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/models" +) + +type ReviewListResult struct { + Id int `json:"id"` + Content string `json:"content"` + Status int `json:"status"` + Second int `json:"second"` +} + +func GetReviewList(uid, bssid int64) ([]*ReviewListResult, error) { + list := make([]*ReviewListResult, 0) + err := core.GetXormAuto().Table(new(models.BullyScreenHistory)).Select("id, content, status, second"). + Where("is_delete=0 and user_id=? and bully_screen_server_id=? and status<> -1", uid, bssid). + OrderBy("created_at desc").Find(&list) + return list, err +} diff --git a/services/calorie/calorie.go b/services/calorie/calorie.go new file mode 100644 index 0000000..e1e5d50 --- /dev/null +++ b/services/calorie/calorie.go @@ -0,0 +1,77 @@ +package calorie_service + +import ( + "errors" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/models" + "time" +) + +func GetCurrentCalorie(aid, uid, rid int64) (map[string]interface{}, error) { + calorie := new(models.Calorie) + exist, err := calorie.GetCurrent(aid) + if err != nil { + return nil, err + } + if !exist { + return nil, errors.New("轮次尚未开启") + } + calorieUser := new(models.CalorieUser) + exist, err = calorieUser.GetByCalorieIdAndUserId(calorie.Id, uid, rid) + if err != nil { + return nil, err + } + if !exist { // 不存在,代表最后一名 + calorieUser.ActivityId = aid + calorieUser.RehearsalId = rid + calorieUser.UserId = uid + calorieUser.CalorieId = calorie.Id + calorieUser.Score = 0 + calorieUser.IsDelete = false + calorieUser.JoinTime = time.Now().UnixNano() + calorieUser.CreatedAt = time.Now() + calorieUser.UpdatedAt = time.Now() + if _, err = core.GetXormAuto().InsertOne(calorieUser); err != nil { + return nil, err + } + rank, err := core.GetXormAuto().Where("is_delete=0 and calorie_id=? and rehearsal_id=?", + calorie.Id, rid).Count(new(models.CalorieUser)) + if err != nil { + return nil, err + } + return map[string]interface{}{ + "rank": rank, + "score": calorieUser.Score, + "calorie_id": calorie.Id, + }, nil + } else { // 存在 + + // 计算总数 + count, err := core.GetXormAuto().Where("is_delete=0 and calorie_id=? and rehearsal_id=?", calorie.Id, rid).Count(new(models.CalorieUser)) + if err != nil { + return nil, err + } + + // 计算分数 和 用户偏移量 + users := make([]*models.CalorieUser, 0) + err = core.GetXormAuto().Where("is_delete=0 and calorie_id=? and rehearsal_id=? and score<=?", + calorie.Id, rid, calorieUser.Score).Desc("score").Asc("join_time").Find(&users) // desc score asc updated_at + if err != nil { + return nil, err + } + + var rank int + for index, u := range users { + if u.Id == calorieUser.Id { + rank = int(count) - len(users) + index + 1 // 总数 + break + } + } + + return map[string]interface{}{ + "rank": rank, + "score": calorieUser.Score, + "calorie_id": calorie.Id, + }, nil + } +} diff --git a/services/invitation/setting.go b/services/invitation/setting.go new file mode 100644 index 0000000..131e569 --- /dev/null +++ b/services/invitation/setting.go @@ -0,0 +1,52 @@ +package invitation_service + +import ( + "encoding/json" + "errors" + "hudongzhuanjia/models" + "strings" +) + +func GetOptionItem(aid int64) ([]string, error) { + // 添加邀请函的内容 + option := new(models.CustomerOrderOption) + exist, err := option.GetByActivityId(aid) + if err != nil { + return nil, err + } + if !exist { + return nil, errors.New("订单表单设置不存在") + } + if option.SettingBox == "" { + return []string{}, nil + } + + optionItems := make([]string, 0) + err = json.Unmarshal([]byte(option.SettingBox), &optionItems) + if err != nil { + return nil, err + } + return optionItems, nil + +} + +func GetOptionValue(items []string, extra string) ([]map[string]interface{}, error) { + if len(items) == 0 || len(extra) == 0 { + return []map[string]interface{}{}, nil + } + + answers := make([]map[string]interface{}, 0) + err := json.Unmarshal([]byte(strings.Trim(extra, `"`)), &answers) + if err != nil { + return nil, err + } + data := make([]map[string]interface{}, 0) + for _, answer := range answers { + for _, item := range items { + if item == answer["name"] { + data = append(data, answer) + } + } + } + return data, nil +} diff --git a/services/lottery/order.go b/services/lottery/order.go new file mode 100644 index 0000000..7a22883 --- /dev/null +++ b/services/lottery/order.go @@ -0,0 +1 @@ +package lottery_service diff --git a/services/lottery/rand_lottery.go b/services/lottery/rand_lottery.go new file mode 100644 index 0000000..52570b8 --- /dev/null +++ b/services/lottery/rand_lottery.go @@ -0,0 +1,27 @@ +package lottery_service + +import ( + "math/rand" + "time" +) + +type LotteryUser struct { + UserId int64 + Username string + UserPhone string + Avatar string + PrizeName string + LadderId int64 + PrizeImg string +} + +func RandLotteryUser(users []*LotteryUser) { + r := rand.New(rand.Source(rand.NewSource(time.Now().Unix()))) + if len(users) <= 0 { + return + } + for i := len(users) - 1; i > 0; i-- { + num := r.Intn(i + 1) + users[i], users[num] = users[num], users[i] + } +} diff --git a/services/pay/client.go b/services/pay/client.go new file mode 100644 index 0000000..bc402c9 --- /dev/null +++ b/services/pay/client.go @@ -0,0 +1,72 @@ +package pay_service + +import ( + "crypto/md5" + "crypto/tls" + "crypto/x509" + "encoding/hex" + "encoding/xml" + "errors" + "fmt" + "github.com/iGoogle-ink/gopay/v2" + "hudongzhuanjia/libs/wx" + "strings" +) + +func ClientExtend(bm gopay.BodyMap, url string) ([]byte, error) { + + //bm.Set("appid", wx.Appid) + //bm.Set("mch_id", wx.Mchid) + + h := md5.New() + h.Write([]byte(bm.EncodeWeChatSignParams(wx.ApiKey))) + bm.Set("sign", strings.ToUpper(hex.EncodeToString(h.Sum(nil)))) + + certP12, err := Asset("cacert/apiclient_cert.p12") + if err != nil { + return nil, err + } + certPem, err := Asset("cacert/apiclient_cert.pem") + if err != nil { + return nil, err + } + keyPem, err := Asset("cacert/apiclient_key.pem") + if err != nil { + return nil, err + } + + pkcsPool := x509.NewCertPool() + pkcsPool.AppendCertsFromPEM(certP12) + certificate, err := tls.X509KeyPair(certPem, keyPem) + if err != nil { + return nil, fmt.Errorf("tls.LoadX509KeyPair:%s", err) + } + + tlsConfig := &tls.Config{ + Certificates: []tls.Certificate{certificate}, + RootCAs: pkcsPool, + InsecureSkipVerify: true} + + httpClient := gopay.NewHttpClient() + httpClient.SetTLSConfig(tlsConfig) + + bs, err := xml.Marshal(bm) + if err != nil { + return nil, err + } + + res, bs, errs := httpClient.Type(gopay.TypeXML).Post(url).SendString(string(bs)).EndBytes() + + if len(errs) > 0 { + return nil, fmt.Errorf("http client return error: %v", errs[0]) + } + + if res.StatusCode != 200 { + return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode) + } + + if strings.Contains(string(bs), "HTML") || strings.Contains(string(bs), "html") { + return nil, errors.New(string(bs)) + } + return bs, nil +} diff --git a/services/pay/order.go b/services/pay/order.go new file mode 100644 index 0000000..d528725 --- /dev/null +++ b/services/pay/order.go @@ -0,0 +1,281 @@ +package pay_service + +import ( + "errors" + "fmt" + "github.com/iGoogle-ink/gopay/v2" + "github.com/iGoogle-ink/gopay/v2/wechat" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/libs/wx" + "hudongzhuanjia/logger" + "hudongzhuanjia/models" + "net/http" + "strconv" + "time" +) + +const CALLBACK_ORDER_URL = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackOrder" + +func Order(content, ip, openid string, fee, goodType int, userId, activityId int64) (map[string]interface{}, error) { + client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true) + + //设置国家 + client.SetCountry(wechat.China) + now := time.Now() + + outTradeNo := gopay.GetRandomString(32) + nonceStr := gopay.GetRandomString(32) + timeStart := now.Format("20060101150405") + timeExpire := now.Add(2 * time.Hour).Format("20060101150405") + + //初始化参数Map + body := make(gopay.BodyMap) + body.Set("nonce_str", nonceStr) + body.Set("body", content) + body.Set("out_trade_no", outTradeNo) + body.Set("total_fee", fee) + body.Set("spbill_create_ip", ip) + body.Set("notify_url", CALLBACK_ORDER_URL) + body.Set("trade_type", wechat.TradeType_JsApi) + body.Set("device_info", "WEB") + body.Set("sign_type", wechat.SignType_MD5) + body.Set("openid", openid) + body.Set("time_start", timeStart) + //body.Set("time_expire", timeExpire) + + //请求支付下单,成功后得到结果 + res, err := client.UnifiedOrder(body) + if err != nil { + return nil, err + } + //ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res) + //if err != nil { + // return nil, err + //} + //if !ok { + // return nil, errors.New("签名验证失败") + //} + + if res.ReturnCode != wx.CODE_SUCCESS { + return nil, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + + if res.ResultCode != wx.CODE_SUCCESS { + return nil, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + + userOrder := new(models.UserOrder) + userOrder.DeviceInfo = "WEB" + userOrder.Desc = content + userOrder.UserId = userId + userOrder.ActivityId = activityId + userOrder.FeeType = "CNY" + userOrder.GoodType = goodType + userOrder.OpenId = openid + userOrder.OutTradeNo = outTradeNo + userOrder.TimeStart = timeStart + userOrder.TimeExpire = timeExpire + userOrder.TotalFee = fee + userOrder.TradeType = wechat.TradeType_JsApi + userOrder.PrepayId = res.PrepayId + userOrder.Status = 0 + userOrder.IsDelete = false + userOrder.CreatedAt = time.Now() + userOrder.UpdatedAt = time.Now() + if _, err := core.GetXormAuto().InsertOne(userOrder); err != nil { + return nil, err + } + + timestamp := strconv.FormatInt(time.Now().Unix(), 10) + //获取H5支付需要的paySign + pac := "prepay_id=" + res.PrepayId + paySign := wechat.GetH5PaySign(wx.Appid, res.NonceStr, pac, wechat.SignType_MD5, timestamp, wx.ApiKey) + return map[string]interface{}{ + "appid": wx.Appid, + "timestamp": timestamp, + "nonce_str": res.NonceStr, + "package": pac, + "sign_type": wechat.SignType_MD5, + "pay_sign": paySign, + "out_trade_no": outTradeNo, + "user_order_id": userOrder.Id, + }, nil +} + +func CallbackOrder(req *http.Request) error { + res, err := wechat.ParseNotifyResult(req) + if err != nil { + logger.Sugar.Error("解析微信毁掉结果失败") + return err + } + //ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res) + //if err != nil { + // return err + //} + //if !ok { + // return errors.New("sign verify failed") + //} + + if res.ReturnCode != wx.CODE_SUCCESS { + return fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + + if res.ResultCode != wx.CODE_SUCCESS { + return fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + + userOrder := new(models.UserOrder) + exist, err := userOrder.GetByOutTradeNo(res.OutTradeNo) + if err != nil { + return err + } + if !exist { + return fmt.Errorf("user order not exist") + } + userOrder.TimeEnd = res.TimeEnd + userOrder.TransactionId = res.TransactionId + userOrder.Status = 1 + if _, err := core.GetXormAuto().Id(userOrder.Id).Cols("time_end, transaction_id, status").Update(userOrder); err != nil { + return err + } + // 设置一下 + if userOrder.GoodType == 1 { // 霸屏 + history := new(models.BullyScreenHistory) + history.Status = 0 + _, err := core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrder.Id).Cols("status").Update(history) + return err + } else if userOrder.GoodType == 2 { + history := new(models.RewardHistory) + history.Status = 0 + _, err := core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrder.Id).Cols("status").Update(history) + return err + } + logger.Sugar.Infof("%+v", res) + return nil +} + +func Query(outTradeNo string) (*wechat.QueryOrderResponse, error) { + client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true) + + client.SetCountry(wechat.China) + + body := make(gopay.BodyMap) + body.Set("out_trade_no", outTradeNo) + body.Set("nonce_str", gopay.GetRandomString(32)) + body.Set("sign_type", wechat.SignType_MD5) + + // 请求订单查询,成功后得到结果 + res, err := client.QueryOrder(body) + if err != nil { + logger.Sugar.Errorf("wechat query order error, %s", err) + return nil, err + } + + if res.TradeState == wx.CODE_SUCCESS { // 付款成功 + userOrder := new(models.UserOrder) + userOrder.Status = 1 + if _, err := core.GetXormAuto().Where("is_delete=0 and out_trade_no=?", outTradeNo). + Cols("status").Update(userOrder); err != nil { + return nil, err + } + } + return res, nil +} + +func BatchQueryByUserId(userId int64) error { + orders := make([]*models.UserOrder, 0) + if err := core.GetXormAuto().Where("is_delete = 0 and status = 0 and user_id = ?", userId).Find(&orders); err != nil { + return err + } + + return batchQuery(orders) +} + +func BatchQueryByActivityId(activityId int64) error { + orders := make([]*models.UserOrder, 0) + if err := core.GetXormAuto().Where("is_delete = 0 and status = 0 and activity_id = ?", activityId).Find(&orders); err != nil { + return err + } + + return batchQuery(orders) +} + +func batchQuery(orders []*models.UserOrder) error { + for _, order := range orders { + res, err := Query(order.OutTradeNo) + if err != nil { + return err + } + if res.TradeState == wx.CODE_SUCCESS { // 付款成功 + order.Status = 1 // 已支付 + order.TransactionId = res.TransactionId + + if _, err := core.GetXormAuto().ID(order.Id).Cols("status, transaction_id").Update(order); err != nil { + return err + } + if order.GoodType == 1 { + history := new(models.BullyScreenHistory) + exist, err := history.GetByUserOrderId(order.Id) + if err != nil { + return err + } + if !exist { + return errors.New("BullyScreenHistory not exist") + } + if history.Status == -1 { + if _, err := history.UpdateStatus(history.Id, 0); err != nil { + return err + } + } + + } else if order.GoodType == 2 { + history := new(models.RewardHistory) + exist, err := history.GetByUserOrderId(order.Id) + if err != nil { + return err + } + if !exist { + return errors.New("RewardHistory not exist") + } + if history.Status == 0 { + break + } + if history.Status == -1 { + if _, err := history.UpdateStatus(history.Id, 0); err != nil { + return err + } + } + + } else { + logger.Sugar.Info("支付测试") + } + } else if order.TimeExpire <= time.Now().Format("20060101150405") { + Close(order.OutTradeNo) + order.Status = -1 // 关闭支付 + order.TransactionId = res.TransactionId + if _, err := core.GetXormAuto().ID(order.Id).Cols("status, transaction_id").Update(order); err != nil { + return err + } + } + } + return nil +} + +func Close(outTradeNo string) (*wechat.CloseOrderResponse, error) { + client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true) + + // 初始化参数结构体 + body := make(gopay.BodyMap) + body.Set("out_trade_no", outTradeNo) + body.Set("nonce_str", gopay.GetRandomString(32)) + body.Set("sign_type", wechat.SignType_MD5) + + // 请求关闭订单,成功后得到结果 + wxRsp, err := client.CloseOrder(body) + if err != nil { + fmt.Println("Error:", err) + return nil, err + } + fmt.Println("wxRsp:", *wxRsp) + return wxRsp, nil +} diff --git a/services/pay/refund.go b/services/pay/refund.go new file mode 100644 index 0000000..d33d372 --- /dev/null +++ b/services/pay/refund.go @@ -0,0 +1,217 @@ +package pay_service + +import ( + "encoding/xml" + "errors" + "fmt" + "github.com/iGoogle-ink/gopay/v2" + "github.com/iGoogle-ink/gopay/v2/wechat" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/libs/wx" + "hudongzhuanjia/models" + "net/http" + "time" +) + +const CALLBACK_REFUND_URL = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackRefund" + +func RefundExtend(bm gopay.BodyMap) (*wechat.RefundResponse, error) { + + err := bm.CheckEmptyError("nonce_str", "out_refund_no", "total_fee", "refund_fee") + if err != nil { + return nil, err + } + if bm.Get("out_trade_no") == gopay.NULL && bm.Get("transaction_id") == gopay.NULL { + return nil, errors.New("out_trade_no and transaction_id are not allowed to be null at the same time") + } + + bs, err := ClientExtend(bm, wx.RefundURL) + if err != nil { + return nil, err + } + wxRsp := new(wechat.RefundResponse) + if err = xml.Unmarshal(bs, wxRsp); err != nil { + return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err) + } + return wxRsp, nil +} + +func Refund(reason, outTradeNo, openId string, goodType, totalFee, refundFee int, userId, activityId int64) (*wechat.RefundResponse, error) { + //client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true) + + outRefundNo := gopay.GetRandomString(64) + // 初始化参数结构体 + body := make(gopay.BodyMap) + body.Set("out_trade_no", outTradeNo) + body.Set("nonce_str", gopay.GetRandomString(32)) + body.Set("sign_type", wechat.SignType_MD5) + body.Set("out_refund_no", outRefundNo) + body.Set("total_fee", totalFee) + body.Set("refund_fee", refundFee) + body.Set("notify_url", CALLBACK_REFUND_URL) + body.Set("refund_desc", reason) + body.Set("refund_fee_type", "CNY") + body.Set("appid", wx.Appid) + body.Set("mch_id", wx.Mchid) + + res, err := RefundExtend(body) + if err != nil { + return nil, err + } + + //ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res) + //if err != nil { + // return nil, err + //} + // + //if !ok { + // return nil, errors.New("签名验证失败") + //} + + if res.ReturnCode != wx.CODE_SUCCESS { + return nil, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + + if res.ResultCode != wx.CODE_SUCCESS { + return nil, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + + refund := new(models.UserRefund) + refund.OutTradeNo = outTradeNo + refund.Status = 0 + refund.TotalFee = totalFee + refund.GoodType = goodType + refund.RefundDesc = reason + refund.FeeType = "CNY" + refund.OpenId = openId + refund.UserId = userId + refund.ActivityId = activityId + refund.IsDelete = false + refund.CreatedAt = time.Now() + refund.UpdatedAt = time.Now() + if _, err := core.GetXormAuto().InsertOne(refund); err != nil { + return nil, err + } + + return res, err +} + +func CallbackRefund(req *http.Request) error { + res, err := wechat.ParseRefundNotifyResult(req) + if err != nil { + return err + } + //ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res) + //if err != nil { + // return err + //} + //if !ok { + // return errors.New("sign verify failed") + //} + if res.ReturnCode != wx.CODE_SUCCESS { + return fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + + info, err := wechat.DecryptRefundNotifyReqInfo(res.ReqInfo, wx.ApiKey) + if err != nil { + return err + } + + userRefund := new(models.UserRefund) + exist, err := userRefund.GetByOutRefundNo(info.OutRefundNo) + if err != nil { + return err + } + if !exist { + return errors.New("user refund not exist") + } + + userRefund.Status = 1 + userRefund.RefundStatus = info.RefundStatus + userRefund.TransactionId = info.TransactionId + userRefund.OutTradeNo = info.OutTradeNo + userRefund.RefundRecvAccount = info.RefundRecvAccout + userRefund.RefundAccount = info.RefundAccount + userRefund.SuccessTime = info.SuccessTime + if _, err := core.GetXormAuto().Id(userRefund.Id).Update(userRefund); err != nil { + return err + } + return nil +} + +func QueryRefund(outTradeNo string) (*wechat.QueryRefundResponse, error) { + client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true) + + // 初始化参数结构体 + body := make(gopay.BodyMap) + body.Set("out_trade_no", outTradeNo) + body.Set("nonce_str", gopay.GetRandomString(32)) + body.Set("sign_type", wechat.SignType_MD5) + + //请求申请退款 + res, err := client.QueryRefund(body) + if err != nil { + return nil, err + } + + ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res) + if err != nil { + return nil, err + } + if !ok { + return nil, errors.New("签名验证失败") + } + + if res.ReturnCode != wx.CODE_SUCCESS { + return nil, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + } + + if res.ResultCode != wx.CODE_SUCCESS { + return nil, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) + } + + fmt.Println("wxRsp:", *res) + return res, nil +} + +func BatchQueryRefundByUserId(userId int64) error { + refunds := make([]*models.UserRefund, 0) + if err := core.GetXormAuto().Where("status = 0 and user_id=?", userId).Find(&refunds); err != nil { + return err + } + if err := batchQueryRefund(refunds); err != nil { + return err + } + return nil +} +func BatchQueryRefundByActivityId(activityId int64) error { + refunds := make([]*models.UserRefund, 0) + if err := core.GetXormAuto().Where("status = 0 and user_id=?", activityId).Find(&refunds); err != nil { + return err + } + if err := batchQueryRefund(refunds); err != nil { + return err + } + return nil +} + +func batchQueryRefund(refunds []*models.UserRefund) error { + for _, refund := range refunds { + res, err := QueryRefund(refund.OutTradeNo) + if err != nil { + return err + } + refund.RefundAccount = res.RefundAccount0 + refund.RefundRecvAccount = res.RefundRecvAccout0 + refund.RefundStatus = res.RefundStatus0 + refund.Status = 1 + refund.SuccessTime = res.RefundSuccessTime0 + refund.WxRefundId = res.RefundId0 + refund.TransactionId = res.TransactionId + if _, err = core.GetXormAuto().Id(refund.Id).Cols("refund_account, refund_recv_account, " + + "status, refund_status, success_time, wx_refund_id, transaction_id").Update(refund); err != nil { + return err + } + } + return nil +} diff --git a/services/pay/transfer.go b/services/pay/transfer.go new file mode 100644 index 0000000..deafab4 --- /dev/null +++ b/services/pay/transfer.go @@ -0,0 +1,148 @@ +package pay_service + +import ( + "encoding/xml" + "fmt" + "github.com/iGoogle-ink/gopay/v2" + "github.com/iGoogle-ink/gopay/v2/wechat" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/libs/wx" + "hudongzhuanjia/logger" + "hudongzhuanjia/models" + "time" +) + +func TransferExtend(bm gopay.BodyMap) (*wechat.TransfersResponse, error) { + err := bm.CheckEmptyError("nonce_str", "partner_trade_no", "openid", "check_name", "amount", "desc", "spbill_create_ip") + if err != nil { + return nil, err + } + + bs, err := ClientExtend(bm, wx.TransfersURL) + if err != nil { + return nil, err + } + + wxRsp := new(wechat.TransfersResponse) + if err = xml.Unmarshal(bs, wxRsp); err != nil { + return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err) + } + return wxRsp, nil +} + +// 企业向微信用户个人付款(不支持沙箱环境) +func Transfer(desc, ip, openId string, amount int) (*wechat.TransfersResponse, error) { + + nonceStr := gopay.GetRandomString(32) + partnerTradeNo := gopay.GetRandomString(32) + // 初始化参数结构体 + body := make(gopay.BodyMap) + body.Set("nonce_str", nonceStr) + body.Set("partner_trade_no", partnerTradeNo) + body.Set("openid", openId) + body.Set("check_name", "NO_CHECK") // NO_CHECK:不校验真实姓名 , FORCE_CHECK:强校验真实姓名 + body.Set("amount", amount) // 企业付款金额,单位为分 + body.Set("desc", desc) // 企业付款备注,必填。注意:备注中的敏感词会被转成字符* + body.Set("spbill_create_ip", ip) + body.Set("mchid", wx.Mchid) + body.Set("mch_appid", wx.Appid) + + res, err := TransferExtend(body) + if err != nil { + fmt.Println("Error:", err) + return nil, err + } + fmt.Println("wxRsp:", *res) + // 保存到user_transfer + return res, nil +} + +func QueryTransfer(partnerTradeNo string) { + body := make(gopay.BodyMap) + body.Set("nonce_str", gopay.GetRandomString(32)) + body.Set("partner_trade_no", partnerTradeNo) + // todo: 查询, 遇到查询失败,需要原订单号重新请求 +} + +// 发送红包 +func SendRedPack(sendName, openId, wishing, ip, actName, remark string, totalAmount, totalNum, scene int) (*wx.RedPackResult, error) { + mchBillNo := gopay.GetRandomString(28) + + body := make(gopay.BodyMap) + body.Set("nonce_str", gopay.GetRandomString(32)) + body.Set("mch_billno", mchBillNo) + body.Set("send_name", sendName) + body.Set("re_openid", openId) + body.Set("total_amount", totalAmount) + body.Set("total_num", totalNum) + body.Set("wishing", wishing) + body.Set("client_ip", ip) + body.Set("act_name", actName) + body.Set("remark", remark) + body.Set("scene_id", fmt.Sprintf("PRODUCT_%d", scene)) + body.Set("wxappid", wx.Appid) + body.Set("mch_id", wx.Mchid) + + bs, err := ClientExtend(body, wx.SendRedPackURL) + if err != nil { + return nil, err + } + res := new(wx.RedPackResult) + if err = xml.Unmarshal(bs, res); err != nil { + logger.Sugar.Errorf("xml.Unmarshal(%s): %s", string(bs), err) + return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err) + } + + if res.ReturnCode != wx.CODE_SUCCESS { + err = fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + logger.Sugar.Error(err) + return nil, err + } + + userRedPack := new(models.UserRedPack) + userRedPack.ErrCode = res.ErrCode + userRedPack.ErrCodeDes = res.ErrCodeDes + userRedPack.MchBillno = mchBillNo + userRedPack.ReOpenid = openId + userRedPack.SceneId = scene + userRedPack.SendListid = res.SendListid + userRedPack.TotalAmount = totalAmount + userRedPack.TotalNum = totalNum + userRedPack.ResultCode = res.ResultCode + userRedPack.IsDelete = false + userRedPack.UpdatedAt = time.Now() + userRedPack.CreatedAt = time.Now() + if _, err := core.GetXormAuto().InsertOne(userRedPack); err != nil { + logger.Sugar.Errorf("insert into user red pack error: %s", err) + return nil, err + } + return res, nil + +} + +// todo: 小心谨慎查询 +func QueryRedPack(mchBillno string) (*wx.QueryRedPackResult, error) { + body := make(gopay.BodyMap) + body.Set("nonce_str", gopay.GetRandomString(32)) + body.Set("mch_billno", mchBillno) + body.Set("bill_type", "MCHT") + body.Set("appid", wx.Appid) + body.Set("mch_id", wx.Mchid) + bs, err := ClientExtend(body, wx.QueryRedPackURL) + if err != nil { + logger.Sugar.Errorf("client extend request wx error: %s", err) + return nil, err + } + res := new(wx.QueryRedPackResult) + if err = xml.Unmarshal(bs, res); err != nil { + logger.Sugar.Errorf("xml.Unmarshal(%s):%s", string(bs), err) + return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err) + } + if res.ReturnCode != wx.CODE_SUCCESS { + err = fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) + logger.Sugar.Error(err) + return nil, err + } + + return res, nil +} diff --git a/services/red_envelope/red_envelop.go b/services/red_envelope/red_envelop.go new file mode 100644 index 0000000..8dcaf12 --- /dev/null +++ b/services/red_envelope/red_envelop.go @@ -0,0 +1,146 @@ +package red_envelope_service + +import ( + "errors" + "github.com/ouxuanserver/osmanthuswine/src/core" + "hudongzhuanjia/models" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/define" + "math/rand" + "time" +) + +func GetCurrentRB(aid, uid, rid int64) (map[string]interface{}, error) { + // 信息 一轮只能有一个 + rule := new(models.ShakeRedEnvelopeRule) + exist, err := rule.GetCurrent(aid) + if err != nil { + return nil, err + } + if exist { + + shakeUser := new(models.ShakeRedEnvelopeUser) + shakeUser.UserId = uid + shakeUser.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId + shakeUser.ShakeRedEnvelopeRuleId = rule.Id + shakeUser.RehearsalId = rid + shakeUser.CreatedAt = time.Now() + shakeUser.UpdateAt = time.Now() + shakeUser.IsDelete = 0 + err := models.Save(map[string]interface{}{ + "user_id=": uid, + "shake_red_envelope_activity_id=": rule.ShakeRedEnvelopeActivityId, + "shake_red_envelope_rule_id=": rule.Id, + "rehearsal_id=": rid, + }, shakeUser) + if err != nil { + return nil, err + } + return map[string]interface{}{ + "rule": rule, + }, nil + } + return nil, errors.New("尚未开启轮次") + // 记录一下参与人数 +} + +const ( + MinRedPackAmount = 1 + MaxRedPackAmount = 499 +) + +// 提前生成红包 +func GenRedEnvelope(aid, rid int64, rule *models.ShakeRedEnvelopeRule) error { + // 判断红包是否存在 + // 根据算法提前生成红包 + + // 删除掉之前存在对的 + _, err := core.GetXormAuto().Where("is_delete=0 and shake_red_envelope_rule_id=? "+ + " and shake_red_envelope_activity_id=? and activity_id=? and rehearsal_id=?", + rule.Id, rule.ShakeRedEnvelopeActivityId, aid, rid).Cols("is_delete"). + Update(&models.ShakeRedEnvelopeRecord{IsDelete: true}) + if err != nil { + return err + } + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + if rule.Model == define.SHAKERB_RULE_RANDOM { // 随机红包 + // 检测红包是否存在 + sumMoney := 0.0 + for i := 0; i < int(rule.RedEnvelopeNum); i++ { + money := r.Float64() * 2 * (rule.RandSum - sumMoney) / float64(int(rule.RedEnvelopeNum)-i) + amount := utils.Float64CusDecimal(money, 2) + if amount < MinRedPackAmount { // 随机的金额可能小于1块钱 + amount = MinRedPackAmount + } else if amount >= MaxRedPackAmount { + amount = MaxRedPackAmount + } + // 提前预判剩余红包和红包的金额比例 ==> money/num <= 0.01 + rate := (rule.RandSum - sumMoney - amount) / float64(int(rule.RedEnvelopeNum)-i) + if rate <= MinRedPackAmount { + amount = MinRedPackAmount + } else if rate >= MaxRedPackAmount { + amount = MaxRedPackAmount + } + + if int(rule.RedEnvelopeNum)-i == 1 { + amount = rule.RandSum - sumMoney + } + record := new(models.ShakeRedEnvelopeRecord) + record.ActivityId = aid + record.RehearsalId = rid + record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId + record.ShakeRedEnvelopeRuleId = rule.Id + record.Amount = amount + record.IsDraw = -1 + record.IsDelete = false + record.CreatedAt = time.Now() + record.UpdatedAt = time.Now() + + if _, err := core.GetXormAuto().InsertOne(record); err != nil { + return err + } + sumMoney += record.Amount + } + } else if rule.Model == define.SHAKERB_RULE_COMMON { // 普通红包 + for i := 0; i < int(rule.RedEnvelopeNum); i++ { + record := new(models.ShakeRedEnvelopeRecord) + record.ActivityId = aid + record.RehearsalId = rid + record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId + record.ShakeRedEnvelopeRuleId = rule.Id + record.Amount = rule.Single + record.IsDraw = -1 + record.IsDelete = false + record.CreatedAt = time.Now() + record.UpdatedAt = time.Now() + if _, err := core.GetXormAuto().InsertOne(record); err != nil { + return err + } + } + } else if rule.Model == define.SHAKERB_RULE_LADDER { // 阶梯红包 + ladders := make([]*models.ShakeRedEnvelopeRuleLadder, 0) + err := core.GetXormAuto().Where("is_delete=0 and shake_red_envelope_rule_id=?", rule.Id). + Desc("created_at").Find(&ladders) + if err != nil { + return err + } + for _, ladder := range ladders { + for i := 0; i < int(ladder.RedEnvelopeNum); i++ { + record := new(models.ShakeRedEnvelopeRecord) + record.ActivityId = aid + record.RehearsalId = rid + record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId + record.ShakeRedEnvelopeRuleId = rule.Id + record.Amount = ladder.Single + record.IsDraw = -1 + record.CreatedAt = time.Now() + record.UpdatedAt = time.Now() + if _, err := core.GetXormAuto().InsertOne(record); err != nil { + return err + } + } + } + } + return nil +} diff --git a/services/vote/vote.go b/services/vote/vote.go new file mode 100644 index 0000000..75de1e1 --- /dev/null +++ b/services/vote/vote.go @@ -0,0 +1,76 @@ +package vote_service + +import ( + "errors" + "hudongzhuanjia/models" +) + +func GetCurrentVote(aid, uid, rid int64) (map[string]interface{}, error) { + vote := new(models.NewVoteActivity) + exist, err := vote.GetCurrent(aid) + if err != nil { + return nil, err + } + if !exist { + return nil, errors.New("轮次尚未开启") + } + return map[string]interface{}{ + "vote": vote, + }, nil +} + +//type VoteRankResult struct { +// TotalNumber int64 `json:"total_number"` +// Id int64 `json:"id"` +// VoteActivityId int64 `json:"vote_activity_id" description:"投票轮次的id"` +// VoteNumber int64 `json:"vote_number" description:"投票的初始票数"` +// VoteMember string `json:"vote_member" description:"被投票的人员名字"` +// MemberImg string `json:"member_img" description:"被投票的人员图片"` +// IsVoted bool `json:"is_vote" description:"是否已經被投票"` +//} +//type VoteRankResults []*VoteRankResult +// +//func RankVote(vid, uid, rid int64) ([]*VoteRankResult, error) { +// result := make([]*models.NewVoteActivityLadder, 0) +// err := core.GetXormAuto().Where("vote_activity_id=? and is_delete=0", vid). +// Desc("total_number").Desc("updated_at").Find(&result) +// if err != nil { +// return nil, err +// } +// ladderIds := make([]int64, 0) +// for index, item := range result { +// result[index].TotalNumber += result[index].VoteNumber +// ladderIds = append(ladderIds, item.Id) +// } +// sort.Sort(result) +// +// histories := make([]*models.NewVoteActivityHistory, 0) +// err = core.GetXormAuto().Where("is_delete=0 and user_id=? and rehearsal_id=?", uid, rid). +// In("vote_activity_ladder_id", ladderIds).Find(&histories) +// if err != nil { +// return nil, err +// } +// for i := range result { +// for j := range histories { +// if result[i].Id == histories[j].VoteActivityLadderId { +// result[i].IsVoted = true +// break +// } +// } +// } +// +// return result, nil +//} +//func (s VoteRankResults) Len() int { +// return len(s) +//} +// +//func (s VoteRankResults) Less(i, j int) bool { +// if s[i].TotalNumber > s[j].TotalNumber { +// return true +// } +// return false +//} +//func (s VoteRankResults) Swap(i, j int) { +// s[i], s[j] = s[j], s[i] +//} diff --git a/services/ws_send/send.go b/services/ws_send/send.go new file mode 100644 index 0000000..26da1ab --- /dev/null +++ b/services/ws_send/send.go @@ -0,0 +1,79 @@ +package ws_send_service + +import ( + "github.com/kirinlabs/HttpRequest" +) + +var SendUrl = "https://api.ouxuanhudong.com:20182/PcClient/Connect/MessageCtl/Receive" + +// https://api.hudongzhuanjia.com:20182/PcClient/Connect/MessageCtl/Receive + +// func init() { +// SendUrl = "http://127.0.0.1:20182/PcClient/Handle/MessageCtl/receive" +// } + +type Message struct { + Type string `json:"type"` + Tag string `json:"tag"` + Dest int64 `json:"dest"` + RoomId string `json:"room_id"` + Data map[string]interface{} `json:"data"` +} + +// pc send upper wall +func SendUpperWall(roomId string, tag string, dest int64, data map[string]interface{}) { + m := Message{ + Type: "upper_wall", + Tag: tag, + Dest: dest, + RoomId: roomId, + Data: data, + } + HttpRequest.Debug(true).JSON().Post(SendUrl, HttpRequest.Json(&m)) +} + +func SendShakeRedEnvelope(roomId string, tag string, dest int64, data map[string]interface{}) { + m := Message{ + Type: "shake_rb", + Tag: tag, + Dest: dest, + RoomId: roomId, + Data: data, + } + HttpRequest.Debug(true).JSON().Post(SendUrl, HttpRequest.Json(&m)) +} + +func SendBarrage(roomId string, tag string, dest int64, data map[string]interface{}) { + m := Message{ + Type: "barrage", + Tag: tag, + Dest: dest, + RoomId: roomId, + Data: data, + } + HttpRequest.Debug(true).JSON().Post(SendUrl, HttpRequest.Json(&m)) +} + +func SendSign(roomId string, tag string, dest int64, data map[string]interface{}) { + m := Message{ + Type: "sign_up", + Tag: tag, + Dest: dest, + RoomId: roomId, + Data: data, + } + HttpRequest.Debug(true).JSON().Post(SendUrl, HttpRequest.Json(&m)) +} + +func SendAuction(roomId string, tag string, dest int64, data map[string]interface{}) { + m := Message{ + Type: "auction", + Tag: tag, + RoomId: roomId, + Dest: dest, + Data: data, + } + HttpRequest.Debug(true).JSON().Post(SendUrl, HttpRequest.Json(&m)) +} + +// 可以设置通用的ws链接进行通信 diff --git a/test/api.json b/test/api.json new file mode 100644 index 0000000..c802fb8 --- /dev/null +++ b/test/api.json @@ -0,0 +1,13 @@ +{ + "host": "http://127.0.0.1", + "activity_id": 19, + "user_id": 19, + "user_token": "", + "customer_id": 10, + "customer_token": "", + "customer_name": "", + "customer_pwd": "", + "entry_account": "", + "entry_pwd": "", + "entry_token": "" +} \ No newline at end of file diff --git a/test/config.go b/test/config.go new file mode 100644 index 0000000..fb97c4a --- /dev/null +++ b/test/config.go @@ -0,0 +1,50 @@ +package test + +import ( + "encoding/json" + "fmt" + "github.com/kirinlabs/HttpRequest" + "io/ioutil" +) + +const RootHost = "http://127.0.0.1:20181" +const ActivityId = 19 +const UserId = 19 + +type ApiConfig struct { + Host string `json:"host"` + ActivityId int64 `json:"activity_id"` // 互动id + UserId int64 `json:"user_id"` //用户id + UserToken string `json:"user_token"` // token + CustomerId string `json:"customer_id"` + CustomerToken string `json:"customer_token"` + CustomerName string `json:"customer_name"` + CustomerPwd string `json:"customer_pwd"` + EntryAccount string `json:"entry_account"` + EntryPwd string `json:"entry_pwd"` + EntryToken string `json:"entry_token"` +} + +// get 方法 +func Api(token string) *HttpRequest.Request { + return HttpRequest.NewRequest().Debug(true).SetHeaders(map[string]string{ + "token": token, + }) +} + +func ApiUrl(path string) string { + return fmt.Sprintf("%s/%s", RootHost, path) +} + +func GetConfig() *ApiConfig { + bs, err := ioutil.ReadFile("api.json") + if err != nil { + panic(err) + } + config := new(ApiConfig) + err = json.Unmarshal(bs, config) + if err != nil { + panic(err) + } + return config +} diff --git a/test/config.json b/test/config.json new file mode 100644 index 0000000..eba0c8a --- /dev/null +++ b/test/config.json @@ -0,0 +1,8 @@ +{ + "port": "20181", + "host": "127.0.0.1", + "cross_domain": "*", + "post_max_memory": 1024000, + "api_router": "/PcClient/*", + "update_path": "./" +} \ No newline at end of file diff --git a/test/config_test.go b/test/config_test.go new file mode 100644 index 0000000..a6a7316 --- /dev/null +++ b/test/config_test.go @@ -0,0 +1,201 @@ +package test + +import ( + "fmt" + "github.com/gorilla/websocket" + "github.com/ouxuanserver/osmanthuswine/src/helper" + "github.com/panjf2000/ants" + . "github.com/smartystreets/goconvey/convey" + "hudongzhuanjia/services/pay" + "hudongzhuanjia/utils" + "hudongzhuanjia/utils/define" + "math/rand" + "net/http" + "regexp" + "runtime" + "sort" + "sync" + "testing" + "time" +) + +func TestHttpGet(t *testing.T) { + Convey("测试http get 方法", t, func() { + resp, err := Api("").Get(fmt.Sprintf("%s/%s", RootHost, "PcClient/common/WeChatOauthCtl/checkin")) + So(err, ShouldBeNil) + res := make(map[string]interface{}) + err = resp.Json(&res) + So(err, ShouldBeNil) + So(res["code"], ShouldEqual, 0) + }) +} + +func TestTime(t *testing.T) { + re := regexp.MustCompile("[a-z]+:[1-9]+") + fmt.Println(re.MatchString("customer:19")) +} + +func TestWs(t *testing.T) { + ws := websocket.DefaultDialer + conn, resp, err := ws.Dial("ws://127.0.0.1:20182/PcClient/Node/webSocket?activity_id=12", nil) + if err != nil && resp.StatusCode == http.StatusOK { + fmt.Printf("%v:%v", err, resp.StatusCode) + t.Error(err) + } + conn.WriteJSON(map[string]interface{}{ + "type": "login", + "data": map[string]interface{}{ + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBY2NvdW50VHlwZSI6ImN1c3RvbWVyIiwiQWNjb3VudElkIjo1NCwiQ3VzdG9tZXJJZCI6NTQsIkN1c3RvbWVyUGlkIjoxOSwiVXNlcm5hbWUiOiIxNTg4OTI3Mzc3MCIsIkFjdGl2aXR5SWQiOjAsIkFyZWFJZCI6NDIsImF1ZCI6Im9zbWFudGh1c3dpbmUtYXVkaWVuY2Utb3giLCJleHAiOjE2NjA3MTY2MDMsImp0aSI6ImVlYWYyMTJjLWQ3Y2YtNGJlMy1hYWYyLWY0NDQ4ZjY2YjE5ZSIsImlzcyI6Im9zbWFudGh1c3dpbmUtaXNzdWVyLW94Iiwic3ViIjoib3NtYW50aHVzd2luZS1zdWJqZWN0LW94In0.igNC7sBFigsxRGpyjnemGm7dgEuoAyWZmMpLkDwDcto", + }, + }) + ts, msg, err := conn.ReadMessage() + if err != nil { + t.Error(err) + } + fmt.Printf("%v:%s", ts, msg) +} + +func TestMd5(t *testing.T) { + pw := helper.Md5("hdzj==ouxuan123") + fmt.Println(pw) + pw2 := helper.Md5("ouxuan123") + fmt.Println(pw2) +} + +func TestTimeFormat(t *testing.T) { + //s, _ := strconv.ParseInt("2000", 10, 64) + m := 12000 / 60 + s := 12000 - m*60 + h := m / 60 + m = m - h*60 + fmt.Printf("%02d:%02d:%02d", h, m, s) +} + +func TestSortSearch(t *testing.T) { + fmt.Println(sort.SearchInts([]int{1, 2, 3, 3, 5, 6}, 3)) +} + +func TestTimeDurationGame(t *testing.T) { + fmt.Println(600 - (time.Now().Unix() - 1574837339)) +} + +func TestInts(t *testing.T) { + f := func(i *[]int64) { + i = &([]int64{1, 2, 3, 4, 5}) + } + a := make([]int64, 0) + f(&a) + fmt.Println(a) +} + +func TestGenUrl(t *testing.T) { + path, _ := utils.GenH5Qrcode(define.H5Auction, map[string]interface{}{ + "activity_id": 1, + "uid=": 2, + "auction_id": 3, + }) + fmt.Println(path) +} + +func TestGoLoop(t *testing.T) { + go func() { + go func() { + fmt.Println("inner") + for { + select { + case <-time.NewTicker(1 * time.Second).C: + fmt.Println("对你哎哎哎啊") + } + } + }() + fmt.Println("outer") + }() + time.Sleep(10 * time.Second) +} + +func TestAnts(t *testing.T) { + runtime.GOMAXPROCS(runtime.NumCPU()) + now := time.Now().Unix() + wg := new(sync.WaitGroup) + wg.Add(1000000) + for i := 0; i < 1000000; i++ { + ants.Submit(func() { + defer wg.Done() + fmt.Println(i) + }) + } + wg.Wait() + fmt.Println(time.Now().Unix() - now) +} + +func TestFor(t *testing.T) { + now := time.Now().Unix() + for i := 0; i < 1000000; i++ { + fmt.Println(i) + } + fmt.Println("end===>", time.Now().Unix()-now) +} + +func TestChan(t *testing.T) { + now := time.Now().Unix() + channel := make(chan int, 0) + for i := 0; i < 1000000; i++ { + channel <- i + } +loop: + for { + select { + case i, ok := <-channel: + if ok { + fmt.Println(i) + } else { + break loop + } + } + } + fmt.Println(time.Now().Unix() - now) +} + +func TestRand(t *testing.T) { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + fmt.Println(r.Float64() * 100) +} + +func TestDuration(t *testing.T) { + //fmt.Println(6 / 2.0) + //fmt.Println(math.Ceil(5 / 2.0)) + //fmt.Println(math.Ceil(4 / 2.0)) + //fmt.Println(math.Ceil(3 / 2)) + //fmt.Println(2 / 2) + //fmt.Println(1 / 2) + //fmt.Println(0 / 2) + fmt.Print(time.Now().UnixNano()) +} + +//func TestVerifySign(t *testing.T) { +// a := wechat.GetH5PaySign(wx.Appid, "VG8BjImdNo6dHB91", "prepay_id=wx0316103340944880625537321039416000", +// "MD5", "1578039033", wx.ApiKey) +// fmt.Println(a) +//} + +//func TestRedPack(t *testing.T) { +// user := new(models.User) +// exist, err := models.GetById(user, 19) +// if err != nil { +// t.Error(err) +// } +// if !exist { +// t.Errorf("error occur: %s", err) +// } +// res, err := pay_service.SendRedPack("欧轩互动", user.Openid, "测试", "123.207.246.51", +// "测试", "测试", 1, 1, 1, user.Id, 1) +// if err != nil { +// t.Error(err) +// } +// fmt.Printf("%+v", res) +//} + +func TestRefundRedPack(t *testing.T) { + res, err := pay_service.QueryRedPack("tDYW8edlzegSlVNaJMXsteZEeuVL") + fmt.Printf("%+v, %+v", res, err) +} diff --git a/test/log/hdzj.log b/test/log/hdzj.log new file mode 100644 index 0000000..3a21742 --- /dev/null +++ b/test/log/hdzj.log @@ -0,0 +1 @@ +2020-01-08 15:45:51.408 ERROR pay/transfer.go:114 insert into user red pack error: Error 1406: Data too long for column 'mch_billno' at row 1 diff --git a/test/private.json b/test/private.json new file mode 100644 index 0000000..af8778c --- /dev/null +++ b/test/private.json @@ -0,0 +1,11 @@ +{ + "db": { + "host": "gz-cdb-onvbcfqn.sql.tencentcdb.com", + "port": "61232", + "user": "root", + "password": "Pox2210XXa@", + "name": "hudongzhuanjia", + "prefix": "ox_", + "max_open_conn": 500 + } +} \ No newline at end of file diff --git a/utils/code/code.go b/utils/code/code.go new file mode 100644 index 0000000..56b08ce --- /dev/null +++ b/utils/code/code.go @@ -0,0 +1,54 @@ +package code + +const ( + MSG_NOT_LOGIN = -1 + MSG_LOGIN = 0 + MSG_LOGIN_SIGNIN = 1 + MSG_SUCCESS = 200 // 成功 + MSG_DATA_NOT_EXIST = 404 + MSG_ERR_Authority = 501 + MSG_ERR_Param = 503 + MSG_ERR = 504 + MSG_ERR_SERVER = 505 + MSG_USER_NOT_EXIST = 600 + MSG_WX_UNIFIEDORDER_ERR = 601 + MSG_USER_ORDER_NOT_EXIST = 602 + MSG_USER_DATA_ERROR = 603 + MSG_CUSTOMER_NOT_EXIST = 700 + MSG_AREASTORE_NOT_EXIST = 800 + MSG_ENTRYPEOPLE_NOT_EXIST = 900 + MSG_ACTIVITY_NOT_EXIST = 1000 // 互动不存在 + MSG_MODULE_NOT_EXIST = 1001 // 模块活动不存在 + MSG_MODULE_STATUS_END = 1002 // 该模块活动已结束 + MSG_MODULE_STATUS_NOT_RUNNING = 1003 // 该模块活动不在进行中 + MSG_MODULE_STATUS_NOT_BEGIN = 1004 // 该模块获取未开始 + MSG_MODULE_STATUS_ERROR = 1005 // 状态出差 + MSG_TUGWAR_NOT_EXIST = 2000 // 拔河不存在 + MSG_TUGWAR_TEAM_OVER_LIMIT = 2001 // 拔河队伍满人 + MSG_TUGWAR_MEMBER_NOT_EXIST = 2002 // 拔河队伍不存在人员 + MSG_TUGWAR_TEAM_NOT_EXIST = 2003 // 拔河队伍不存在 + MSG_INVITE_LETTER_NOT_EXIST = 3000 // 邀请函不存在 + MSG_INVITE_LETTER_EXIST = 3001 // 邀请函存在 + MSG_INVITE_SETTING_NOT_EXIST = 3002 // 邀请函设置不存在 + MSG_INVITE_ORDER_SETTING_NOT_EXIST = 3003 // 订单设置不存在 + MSG_LOTTERY_PRIZE_NOT_ENOUGH = 4001 // 奖品不足 + MSG_LOTTERY_PEOPLE_NOT_ENOUGH = 4002 // 抽奖人数不足 + MSG_LOTTERY_RULE_NOT_EXIST = 4003 // 抽奖规则不存在 + MSG_ORDER_RULE_NOT_EXIST = 4005 // 订单抽奖规则不存在 + MSG_ORDER_LADDER_NOT_EXIST = 4006 // 订单抽奖阶梯不存在 + MSG_LOTTERY_LADDER_NOT_EXIST = 4007 // 抽奖等级不存在 + MSG_SIGN_UP_NOT_EXIST = 5000 // 签到规则不存在 + MSG_SIGN_HISTORY_EXIST = 5001 // 签到存在 + MSG_SIGN_UP_REHEARSAL_LIMIT = 5002 // 签到彩排人数限制 + MSG_BULLY_SCREEN_SERVER_NOT_EXIST = 6000 // 霸屏 不存在 + MSG_BARRAGE_SERVER_NOT_EXIST = 6001 // 弹幕 不存在 + MSG_REWARD_NOT_EXIST = 6002 // 打赏不存 + MSG_VOTE_HISTORY_EXIST = 7001 // 投票历史存在 + MSG_VOTE_LADDER_NOT_EXIST = 7002 // 投票人不存在 + MSG_SHAKERB_NOT_EXIST = 8000 // 摇红包不存在 + MSG_SHAKERB_RECORD_NOT_EXIST = 8001 // 摇红包不存在 + MSG_SHAKERB_RULE_NOT_EXIST = 8002 // 红包规则不存在 + MSG_AUCTION_NOT_EXIST = 9000 // 竞拍不存在 + MSG_AUCTION_PLAYER_NOT_EXIST = 9001 // 竞拍人不存在 + MSG_CALORIE_NOT_EXIST = 10001 // 卡路里轮次不存在 +) diff --git a/utils/define/define.go b/utils/define/define.go new file mode 100644 index 0000000..04fca6f --- /dev/null +++ b/utils/define/define.go @@ -0,0 +1,85 @@ +package define + +const TimeFormat = "2006-01-01 15:04:05" + +const ( + MODULE_SIGNIN = "签到" + MODULE_TUGWAR = "拔河" + MODULE_SHAKRB = "摇红包" + MODULE_SHAKETK = "摇奖券" + MODULE_ORDER = "订单" + MODULE_UPPERW = "上墙" + MODULE_BULLYS = "霸屏" + MODULE_LOTTERY = "抽奖" + MODULE_VOTE = "投票" + MODULE_AUCTION = "竞拍" + MODULE_REWARD = "打赏" + MODULE_SEMINAR = "会务" + MODULE_MOREAREA = "多地区" + MODULE_BARRAGE = "弹幕" + MODULE_INVITATION = "邀请函" + MODULE_ORDERLY = "订单抽奖" + MODULE_MSGWALL = "消息墙" + MODULE_CALORIE = "卡路里" +) + +const ( + StatusNotBegin = "未开始" + StatusReady = "准备中" + StatusRunning = "进行中" + StatusEnding = "已结束" + StatusOpen = "开启" + StatusClose = "关闭" +) + +const ( + INCR_AUCTION = "加价竞拍" + DECR_AUCTION = "减价竞拍" +) + +const ( + TUGWAR_MODEL_RANDOM = "随机分配模式" + TUGWAR_MODEL_SELECT = "大屏幕二维码模式" + TUGWAR_TEAM_BULE = "blue" + TUGWAR_TEAM_RED = "red" +) + +const ( + SHAKERB_RULE_RANDOM = "拼手气红包" + SHAKERB_RULE_COMMON = "普通红包" + SHAKERB_RULE_LADDER = "阶梯红包" +) + +// 模块去除 BesideRepeat +const MODULE_BESIDE_REPEAT = "去除" + +const ( + TOKEN = "token" +) + +const ( + WSSENDURL = "https://api.ouxuanhudong.com:20182/PcClient/Handle/MessageCtl/Receive" + HOST = "https://api.ouxuanhudong.com" + H5Host = "https://h5.ouxuanhudong.com/web" +) + +const ( + H5Index = "index.html" + H5SignIn = "SignIn.html" + H5ShakeRb = "shakeRb.html" + H5TugOfWar = "tugOfWar.html" + H5UpperWall = "UpperWall.html" + H5Barrage = "barrage.html" + H5Order = "order.html" + H5Reward = "reward.html" + H5BScreen = "bScreen.html" + H5Auction = "auction.html" + H5Vote = "vote.html" + H5Calorie = "calorie.html" +) + +const ( + TYPE_USER = "user" + TYPE_CUSTOMER = "customer" + TYPE_ENTRY = "entry" +) diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 0000000..cec6bcb --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,108 @@ +package utils + +import ( + "crypto/sha1" + "encoding/base64" + "fmt" + "github.com/skip2/go-qrcode" + "hudongzhuanjia/utils/define" + "io/ioutil" + "net/http" + "os" + "strconv" + "strings" +) + +func Int(str string) int { + i, _ := strconv.Atoi(str) + return i +} + +func Int64(str string) int64 { + i, _ := strconv.ParseInt(str, 10, 64) + return i +} + +func Float64(str string) float64 { + f, _ := strconv.ParseFloat(strings.TrimSpace(str), 64) + return f +} + +//除法,校验被除数为0时返回接口为0 +// return one/two +func Except(one, two float64) float64 { + if two == 0 { + return 0 + } + return one / two +} + +//自定义小数的位数 +func Float64CusDecimal(v float64, decimal int) float64 { + return Float64(fmt.Sprintf("%."+fmt.Sprintf("%d", decimal)+"f", v)) +} + +func Qrcode2Base64(url string) (string, error) { + qr, err := qrcode.Encode(url, qrcode.Medium, 256) + return fmt.Sprintf("data:image/png;base64,%s", base64.StdEncoding.EncodeToString(qr)), err +} + +func GenH5Url(webName string, param map[string]interface{}) string { + path := fmt.Sprintf("%s/%s?", define.H5Host, webName) + for key, value := range param { + if key[len(key)-1] == '=' { + key = key[:len(key)-1] + } + path += fmt.Sprintf("%s=%v&", key, value) + } + lastChar := path[len(path)-1] + if lastChar == '&' || lastChar == '?' { + path = path[:len(path)-1] + } + return path +} + +func GenH5Qrcode(WebName string, param map[string]interface{}) (string, error) { + path := GenH5Url(WebName, param) + return Qrcode2Base64(path) +} + +func Gif2Base64(url string) (string, error) { + if strings.HasSuffix(url, ".gif") { + resp, err := http.Get(url) + if err != nil { + return "", err + } + bys, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + return fmt.Sprintf("data:image/gif;base64,%s", base64.StdEncoding.EncodeToString(bys)), err + } + return url, nil +} + +func Sha1(b string) string { + h := sha1.New() + h.Write([]byte(b)) + return fmt.Sprintf("%x", h.Sum(nil)) +} + +func PathExists(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return false, err +} + +func CountDownFormat(duration int64) string { + m := duration / 60 // 分钟 + s := duration - m*60 // 剩余秒 + h := m / 60 // 小时 + m = m - h*60 // 剩余分钟 + return fmt.Sprintf("%02d:%02d:%02d", h, m, s) +} diff --git a/utils/utils_test.go b/utils/utils_test.go new file mode 100644 index 0000000..8a40cfd --- /dev/null +++ b/utils/utils_test.go @@ -0,0 +1,70 @@ +package utils + +import ( + . "github.com/smartystreets/goconvey/convey" + "testing" +) + +func TestQrcode2Base64(t *testing.T) { + Convey("测试生成二维码并把二维码变成base64编码", t, func() { + urlPath := "https://www.baidu.com" + code, err := Qrcode2Base64(urlPath) + So(err, ShouldBeNil) + So(code, ShouldStartWith, "data:image/png;base64,") + }) +} + +func TestFloat64CusDecimal(t *testing.T) { + Convey("测试把float64精度截断", t, func() { + f1 := 2000.22202 + f := Float64CusDecimal(f1, 2) + So(f, ShouldEqual, 2000.22) + f2 := 5000.4 + f = Float64CusDecimal(f2, 1) + So(f, ShouldEqual, f2) + f3 := 5000.509 + f = Float64CusDecimal(f3, 2) + So(f, ShouldNotEqual, 5000.50) + }) +} + +func TestGif2Base64(t *testing.T) { + Convey("测试把gif编码为base64", t, func() { + urlPath := "http://photocdn.sohu.com/20150721/mp23627612_1437451852870_2.gif" + gif, err := Gif2Base64(urlPath) + So(err, ShouldEqual, nil) + So(gif, ShouldStartWith, "data:image/gif;base64") + + urlPath = "https://www.baidu.com" + gif, err = Gif2Base64(urlPath) + So(err, ShouldBeNil) + So(urlPath, ShouldEqual, urlPath) + + urlPath = "xxxx.gif" + gif, err = Gif2Base64(urlPath) + So(err, ShouldNotEqual, nil) + }) +} + +func TestPathExists(t *testing.T) { + Convey("测试文件是否存在", t, func() { + // 存在状态 + path := "utils.go" + exist, err := PathExists(path) + So(err, ShouldEqual, nil) + So(exist, ShouldBeTrue) + // 不存在状态 + path = "utils.+" + exist, err = PathExists(path) + So(err, ShouldBeNil) + So(exist, ShouldBeFalse) + }) +} + +func TestCountDownFormat(t *testing.T) { + Convey("测试倒计时格式", t, func() { + num := 12000 + str := CountDownFormat(num) + So(str, ShouldEqual, "3:20:0") + }) +}