twin-api/app/common/middle/user_pkg.go

68 lines
2.0 KiB
Go

package middle
import (
"fmt"
"time"
"twin-api/app/common/dao"
"twin-api/app/common/model"
"twin-api/base/config"
"git.u8t.cn/open/go-server/session"
"github.com/gin-gonic/gin"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
)
func UserPkg(ctx *gin.Context) {
ctx.Keys[config.TraceId] = fmt.Sprintf("trace_id:%d", time.Now().UnixNano())
sess, ok := ctx.Keys[session.ContextSession].(*session.ApiSession)
if !ok {
panic(config.ErrInternal.New().Append("user_pkg: error user"))
}
header := sess.GetUserHeader()
if header.Package == "" || header.Version == "" {
panic(config.ErrParam.New().Append("user_pkg: error pkg"))
}
var userPkgInfo *model.Pkg
var err error
// 检查用户是否有新版本,如果没有则落库,
if userPkgInfo, err = dao.NewPackage().GetUserPkg(sess.GetUserId(), header.Package, header.Version); err != nil {
panic(config.ErrDb.New().Append("user_pkg: ", err))
}
if userPkgInfo == nil {
// 查询当前的userPkg以及version是否存在
var pkg *model.Pkg
if pkg, err = dao.NewPackage().GetOne(header.Package, header.Version); err != nil {
panic(config.ErrDb.New().Append("user_pkg: ", err))
}
if pkg == nil {
panic(config.ErrParam.New().Append(fmt.Sprintf("user_pkg: error pkg: %s version %s", header.Package, header.Version)))
}
if pkg.ExpireTime < time.Now().Unix() {
panic(config.ErrPkgExpire.New())
}
userPkg := &model.UserPkg{}
userPkg.UserId = sess.GetUserId()
userPkg.PackageId = pkg.Id
userPkg.CreateTime = time.Now().Unix()
userPkg.Extra = goutil.EncodeJSON(pkg)
// 人数限制:先计数再落库,满员则拒绝该版本(引导用户更新)。
// 非严格原子,高并发下存在极小超限窗口,业务可接受。
limit := cast.ToInt64(sess.GetExperiment().GetParam(config.ServicePackageLimit, config.KeysDefault[config.ServicePackageLimit]))
ok, err := dao.NewUserPkg().CreateWithinLimit(userPkg, limit)
if err != nil {
panic(config.ErrDb.New().Append("user_pkg: create error: ", err))
}
if !ok {
panic(config.ErrPkgLimit.New())
}
}
}