feat: many

This commit is contained in:
wangfuduo 2026-07-08 17:13:18 +08:00
parent ca93be0371
commit 7463e2dacd
10 changed files with 144 additions and 66 deletions

View File

@ -24,7 +24,7 @@ type PkgDelete struct {
}
type PkgCreate struct {
Name string `json:"package_name"`
Name string `json:"name"`
Version string `json:"version"`
Expire string `json:"expire"`
Link string `json:"link"`

View File

@ -3,7 +3,6 @@ package response
import (
"fmt"
"time"
"twin-api/base/config"
"github.com/gin-gonic/gin"
)
@ -12,6 +11,7 @@ type Button struct {
Color string `json:"-"`
Text string `json:"text"`
Url string `json:"url"`
Type string `json:"type"`
}
type Window struct {
@ -20,7 +20,7 @@ type Window struct {
}
type Data struct {
Buttons []Button `json:"buttons"`
Buttons []*Button `json:"buttons"`
Window Window `json:"window"`
}
@ -45,20 +45,20 @@ func New(ctx *gin.Context, code int, message string) *Response {
response.Code = code
response.Msg = message
response.Trace = trace
response.Data.Buttons = make([]Button, 0)
response.Data.Buttons = make([]*Button, 0)
response.Data.Window = Window{Title: "温馨提示", Close: true}
return response
}
func (r *Response) Success(ctx *gin.Context) *Response {
resp := New(ctx, config.Success, "success")
resp.Window(&Window{Title: "", Close: true})
resp.Data.Buttons = make([]Button, 0)
return resp
}
func (r *Response) Button(b ...*Button) *Response {
if len(b) > 1 {
r.Data.Buttons = append(r.Data.Buttons[:0], b...)
}
if len(b) == 1 {
r.Data.Buttons = append(r.Data.Buttons, b...)
}
func (r *Response) Botton(b *Button) *Response {
r.Data.Buttons = append(r.Data.Buttons, *b)
return r
}
@ -70,3 +70,8 @@ func (r *Response) Window(win *Window) *Response {
r.Data.Window.Close = win.Close
return r
}
func (r *Response) Message(message string) *Response {
r.Msg = message
return r
}

41
app/api/service/button.go Normal file
View File

@ -0,0 +1,41 @@
package service
import (
"twin-api/app/api/response"
"twin-api/base/config"
)
type Button struct {
param map[string]any
}
func New(param map[string]any) *Button {
b := new(Button)
b.param = param
return b
}
func (b *Button) CouponButton() []*response.Button {
button := new(response.Button)
button.Url = b.param[config.ServiceVipExpireUrl].(string)
button.Type = config.ButtonInput
submitBtn := new(response.Button)
submitBtn.Text = "提交"
submitBtn.Type = config.ButtonClick
customBtn := new(response.Button)
customBtn.Text = b.param[config.ButtonTxtContractCustomer].(string)
customBtn.Type = config.ButtonClick
return []*response.Button{button, submitBtn, customBtn}
}
func (b *Button) PayButton() []*response.Button {
button := new(response.Button)
button.Text = b.param[config.ServiceVipExpireButton].(string)
button.Url = b.param[config.ServiceVipExpireUrl].(string)
button.Type = config.ButtonInput
return []*response.Button{button}
}

View File

@ -49,12 +49,14 @@ func NewUser(ctx *gin.Context) *User {
// 判断包是否提示强制更新
// 判断包是否提示更新
func (u *User) Verify() *response.Response {
// 检查免费使用时间
if resp := u.FreeCheck(); resp != nil {
func (u *User) success() *response.Response {
resp := response.New(u.ctx, config.Success, "success")
resp.Window(&response.Window{Title: "", Close: true})
resp.Data.Buttons = make([]*response.Button, 0)
return resp
}
}
func (u *User) Verify() *response.Response {
// 检查会员状况
if resp := u.VipCheck(); resp != nil {
return resp
@ -64,30 +66,7 @@ func (u *User) Verify() *response.Response {
return resp
}
resp := response.New(u.ctx, config.Success, "success")
resp.Window(&response.Window{Title: "", Close: true})
resp.Data.Buttons = make([]response.Button, 0)
return resp
}
func (u *User) FreeCheck() *response.Response {
var resp *response.Response
free := time.Unix(u.sess.GetUserInfo().ActiveTime, 0).AddDate(0, 0, cast.ToInt(u.params[config.ServiceFreeDay]))
if free.Unix() >= time.Now().Unix() {
// 提示需要充值
resp = response.New(u.ctx, config.VipExpire, u.params[config.ServiceVipExpireNotice].(string))
button := &response.Button{
Text: u.params[config.ServiceVipExpireButton].(string),
Url: u.params[config.ServiceVipExpireUrl].(string),
}
window := &response.Window{Close: false}
resp.Botton(button)
resp.Window(window)
return resp
}
return resp
return u.success()
}
func (u *User) VipCheck() *response.Response {
@ -97,15 +76,35 @@ func (u *User) VipCheck() *response.Response {
return nil
}
free := time.Unix(u.sess.GetUserInfo().ActiveTime, 0).AddDate(0, 0, cast.ToInt(u.params[config.ServiceFreeDay])).Unix()
if free-u.sess.GetUserInfo().ActiveTime > 0 {
return nil
}
//
if expire < time.Now().Unix() {
resp = response.New(u.ctx, config.VipExpire, u.params[config.ServiceVipExpireNotice].(string))
button := &response.Button{
Text: u.params[config.ServiceVipExpireButton].(string),
Url: u.params[config.ServiceVipExpireUrl].(string),
}
window := &response.Window{Close: false}
resp.Botton(button)
resp.Window(window)
buttons := make([]*response.Button, 0)
// 首次支付按钮
if u.sess.GetUserInfo().VipCreateTime == 0 {
if u.params[config.ServiceFirstPayWay] == config.FirstRechargeByCoupon {
resp.Message(u.params[config.ServerCouponNotice].(string))
buttons = append(buttons, New(u.params).CouponButton()...)
} else {
buttons = append(buttons, New(u.params).PayButton()...)
}
} else {
if u.params[config.ServicePayWay] == config.FirstRechargeByCoupon {
resp.Message(u.params[config.ServerCouponNotice].(string))
buttons = append(buttons, New(u.params).CouponButton()...)
} else {
buttons = append(buttons, New(u.params).PayButton()...)
}
}
resp.Button(buttons...)
}
return resp
@ -134,9 +133,10 @@ func (u *User) PkgCheck() *response.Response {
button := &response.Button{
Text: u.params[config.ServicePackageLackButton].(string),
Url: u.params[config.ServicePackageLackUrl].(string),
Type: config.ButtonClick,
}
window := &response.Window{Close: false}
resp.Botton(button)
resp.Button(button)
resp.Window(window)
return resp
@ -196,9 +196,10 @@ func (u *User) expireCheck(userPkg *model.UserPkgInfo, day int) *response.Respon
button := &response.Button{
Text: u.params[config.ServiceInstallButton].(string),
Url: pkg.Link,
Type: config.ButtonClick,
}
window := &response.Window{Close: false}
resp.Botton(button)
resp.Button(button)
resp.Window(window)
}

View File

@ -13,6 +13,7 @@ import (
)
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"))
@ -41,6 +42,10 @@ func UserPkg(ctx *gin.Context) {
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

View File

@ -32,8 +32,8 @@ func (p *Pkg) Format() map[string]any {
res["link"] = p.Link
res["status"] = p.Status
res["expire"] = gsUtils.TimeToDateTime(p.ExpireTime)
res["create_date"] = gsUtils.TimeToDateTime(p.CreateTime)
res["update_date"] = gsUtils.TimeToDateTime(p.UpdateTime)
res["create_time"] = gsUtils.TimeToDateTime(p.CreateTime)
res["update_time"] = gsUtils.TimeToDateTime(p.UpdateTime)
return res
}

View File

@ -23,7 +23,7 @@ func InitRouter(engine *gin.Engine) {
// 客户端接口路由
func initApiRouter(engine *gin.Engine) {
base := new(gsApiController.BaseController)
userGroup := engine.Group("/api/user").Use(base.Recovery).Use(base.Before).Use(base.Token).Use(base.IpLimit).Use(base.Response).Use(middle.UserPkg)
userGroup := engine.Group("/api").Use(base.Recovery).Use(base.Before).Use(base.Token).Use(base.IpLimit).Use(base.Response).Use(middle.UserPkg)
userApi := new(controller.User)
userGroup.GET("/verify", userApi.Verify)

View File

@ -7,3 +7,16 @@ const (
NoPkg = 30002
NeedUpgrade = 30003
)
const (
TraceId = "trace_id"
)
const (
FirstRechargeByCoupon = "coupon"
)
const (
ButtonClick = "click"
ButtonInput = "input"
)

View File

@ -16,4 +16,6 @@ var (
ErrParam = errors.T(11000, "参数错误")
ErrNoData = errors.T(11001, "数据不存在")
ErrExist = errors.T(11002, "数据已存在")
ErrPkgExpire = errors.T(30004, "包已过期")
)

View File

@ -20,6 +20,13 @@ const (
ServiceContactCustomer = "service.contact.customer" // 联系客服提示语
ServiceInstallButton = "service.install.button" // 安装按钮提示
ServiceFirstPayWay = "service.first.pay.way" // 首次激活的支付方式
ServicePayWay = "service.pay.way" // 后续的支付方式
ServerCouponNotice = "service.coupon.notice" // 激活码兑换
)
const (
ButtonTxtContractCustomer = "service.button.contract.customer" // 联系客服按钮文字
)
var KeysDefault = map[string]any{
@ -37,4 +44,8 @@ var KeysDefault = map[string]any{
ServicePackageLackUrl: "",
ServiceContactCustomer: "安装包缺失请联系客服解决all@batiao8.com",
ServiceInstallButton: "安装",
ServiceFirstPayWay: "coupon", // coupon | recharge
ServicePayWay: "coupon",
ServerCouponNotice: "请输入兑换码",
ButtonTxtContractCustomer: "联系客服",
}