Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25d190c498 | |||
| f1dfa61578 | |||
| 2c0026267e | |||
| ab84984fb0 | |||
| 4f6e516ade | |||
| c9aeb90209 | |||
| 2125fd4bde | |||
| 41dfe9ff54 | |||
| 18fc1cee7a |
@@ -29,7 +29,7 @@ jobs:
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
- name: Extract metadata for Docker
|
||||
id: meta
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ FROM golang:alpine AS backend-builder
|
||||
WORKDIR /build
|
||||
COPY . .
|
||||
|
||||
RUN go build -ldflags="-s -w" -o bin/server cmd/server
|
||||
RUN go build -ldflags="-s -w" -o bin/server
|
||||
|
||||
RUN apk add --no-cache upx
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.6
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.71
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.84.1
|
||||
github.com/breml/rootcerts v0.3.3
|
||||
github.com/bytedance/sonic v1.14.0
|
||||
github.com/deatil/go-cryptobin v1.1.1005
|
||||
github.com/go-sql-driver/mysql v1.9.3
|
||||
|
||||
@@ -44,6 +44,8 @@ github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw=
|
||||
github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
|
||||
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
|
||||
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
|
||||
github.com/breml/rootcerts v0.3.3 h1://GnaRtQ/9BY2+GtMk2wtWxVdCRysiaPr5/xBwl7NKw=
|
||||
github.com/breml/rootcerts v0.3.3/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
|
||||
@@ -9,5 +9,6 @@ import (
|
||||
var Cpdaily = resty.New().
|
||||
SetCookieJar(nil).
|
||||
SetTimeout(30 * time.Second).
|
||||
SetDoNotParseResponse(true).
|
||||
SetProxy("http://127.0.0.1:9000")
|
||||
SetDoNotParseResponse(true)
|
||||
|
||||
//SetProxy("http://127.0.0.1:9000")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package cst
|
||||
|
||||
const (
|
||||
BasePointCpdaily = 1
|
||||
)
|
||||
@@ -88,8 +88,8 @@ func (ts *TaskScanner) scanCpdailyTask() {
|
||||
minExecuteTime := currentTime.Add(-30 * time.Minute).Unix()
|
||||
|
||||
allTasks := db.Global.CpTask.Query().
|
||||
Where(cptask.NextExecuteTimeLTE(currentTime.Unix()), cptask.NextExecuteTimeNotNil(), cptask.NextExecuteTimeGT(0)).
|
||||
Select(cptask.FieldID, cptask.FieldExecuteHour, cptask.FieldExecuteMinute).
|
||||
Where(cptask.NextExecuteTimeLTE(currentTime.Unix()), cptask.NextExecuteTimeNotNil(), cptask.NextExecuteTimeGT(0), cptask.StepEQ(cptask.StepComplete), cptask.TaskStatusEQ(cptask.TaskStatusNotStart)).
|
||||
Select(cptask.FieldID, cptask.FieldExecuteHour, cptask.FieldExecuteMinute, cptask.FieldNextExecuteTime).
|
||||
AllX(ts.ctx)
|
||||
|
||||
var failedIDS []int64
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/util/gvalid"
|
||||
)
|
||||
|
||||
func ExceptionHandler(r *ghttp.Request) {
|
||||
@@ -50,6 +51,15 @@ func ExceptionHandler(r *ghttp.Request) {
|
||||
code = tmpErr.Code()
|
||||
} else if code == gcode.CodeNil {
|
||||
code = errors.CodeInternal.Code()
|
||||
} else if code == gcode.CodeValidationFailed {
|
||||
// 请求参数校验失败返回第一个错误信息
|
||||
if validationErr, ok := err.(gvalid.Error); ok {
|
||||
if firstErr := validationErr.FirstError(); firstErr != nil {
|
||||
c := errors.CodeParam
|
||||
c.SetMessage(firstErr.Error())
|
||||
code = c.Code()
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Response.ClearBuffer()
|
||||
r.Response.WriteHeader(200)
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"likedream-goframe/internal/ent"
|
||||
"likedream-goframe/internal/ent/sysrole"
|
||||
"likedream-goframe/internal/ent/sysuser"
|
||||
"likedream-goframe/internal/service/balance"
|
||||
"likedream-goframe/internal/utils"
|
||||
|
||||
"github.com/samber/oops"
|
||||
@@ -22,7 +23,9 @@ func NewV1() *AgentServiceV1 {
|
||||
|
||||
func (s *AgentServiceV1) List(ctx context.Context, req *v1.AgentListReq) *utils.Response[[]v1.AgentListRes] {
|
||||
query := db.Global.SysUser.Query()
|
||||
query.Where(sysuser.HasParentWith(sysuser.IDEQ(utils.GetUserInfoFromCtx(ctx).ID)))
|
||||
if !utils.IsAdminFromCtx(ctx) {
|
||||
query.Where(sysuser.HasParentWith(sysuser.IDEQ(utils.GetUserInfoFromCtx(ctx).ID)))
|
||||
}
|
||||
if req.Email != "" {
|
||||
query.Where(sysuser.EmailContains(req.Email))
|
||||
}
|
||||
@@ -109,13 +112,15 @@ func (s *AgentServiceV1) Add(ctx context.Context, req *v1.AgentAddReq) *utils.Re
|
||||
}
|
||||
|
||||
func (s *AgentServiceV1) Ban(ctx context.Context, req *v1.AgentBanReq) *utils.Response[any] {
|
||||
// 参数校验
|
||||
currentUser := utils.GetUserInfoFromCtx(ctx)
|
||||
user := db.Global.SysUser.Query().Where(sysuser.IDEQ(req.ID)).OnlyX(ctx)
|
||||
// 判断是否是自己的下级代理
|
||||
parent := user.QueryParent().OnlyX(ctx)
|
||||
if parent.ID != currentUser.ID {
|
||||
return utils.FailParam("非法的下级代理参数")
|
||||
if !utils.IsAdminFromCtx(ctx) {
|
||||
// 参数校验
|
||||
currentUser := utils.GetUserInfoFromCtx(ctx)
|
||||
// 判断是否是自己的下级代理
|
||||
parent := user.QueryParent().OnlyX(ctx)
|
||||
if parent.ID != currentUser.ID {
|
||||
return utils.FailParam("非法的下级代理参数")
|
||||
}
|
||||
}
|
||||
db.Global.SysUser.UpdateOne(user).SetBlock(req.Block).ExecX(ctx)
|
||||
return utils.SuccessWithMsg("操作成功")
|
||||
@@ -123,41 +128,20 @@ func (s *AgentServiceV1) Ban(ctx context.Context, req *v1.AgentBanReq) *utils.Re
|
||||
|
||||
func (s *AgentServiceV1) Recharge(ctx context.Context, req *v1.AgentRechargeReq) *utils.Response[any] {
|
||||
// 参数校验
|
||||
currentUser := db.Global.SysUser.Query().Where(sysuser.ID(utils.GetUserInfoFromCtx(ctx).ID)).WithAgent().WithRoles().OnlyX(ctx)
|
||||
user := db.Global.SysUser.Query().Where(sysuser.IDEQ(req.ID)).WithAgent().OnlyX(ctx)
|
||||
// 判断是否是自己的下级代理
|
||||
parent := user.QueryParent().WithAgent().FirstX(ctx)
|
||||
if parent == nil || parent.ID != currentUser.ID {
|
||||
return utils.FailParam("非法的下级代理参数")
|
||||
}
|
||||
tx, err := db.Global.Tx(ctx)
|
||||
utils.OkOrPanic(err, func(err error) error {
|
||||
return oops.
|
||||
WithContext(ctx).
|
||||
With("创建事务失败").
|
||||
Wrap(err)
|
||||
})
|
||||
if !utils.HasRole(currentUser.Edges.Roles, cst.KeyRoleAdmin) {
|
||||
parent.Balance = utils.CalculateBalance(parent.Balance, parent.Edges.Agent.Rate, req.Amount, user.Edges.Agent.Rate)
|
||||
if parent.Balance.Compare(decimal.NewFromInt(0)) < 0 {
|
||||
return utils.FailParam("余额不足")
|
||||
if !utils.IsAdminFromCtx(ctx) {
|
||||
currentUser := db.Global.SysUser.Query().Where(sysuser.ID(utils.GetUserInfoFromCtx(ctx).ID)).WithAgent().WithRoles().OnlyX(ctx)
|
||||
// 判断是否是自己的下级代理
|
||||
parent := user.QueryParent().WithAgent().FirstX(ctx)
|
||||
if parent == nil || parent.ID != currentUser.ID {
|
||||
return utils.FailParam("非法的下级代理参数")
|
||||
}
|
||||
if !utils.HasRole(currentUser.Edges.Roles, cst.KeyRoleAdmin) {
|
||||
needBalance := utils.CalculateBalance(parent.Balance, parent.Edges.Agent.Rate, req.Amount, user.Edges.Agent.Rate)
|
||||
balance.BalanceService.ChangeUserBalance(ctx, parent.ID, needBalance.Neg())
|
||||
}
|
||||
}
|
||||
tx.SysUser.UpdateOne(parent).SetBalance(parent.Balance).SaveX(ctx)
|
||||
utils.OkOrPanic(err, func(err error) error {
|
||||
return oops.
|
||||
WithContext(ctx).
|
||||
With("更新用户余额失败").
|
||||
Wrap(err)
|
||||
})
|
||||
tx.SysUser.UpdateOne(user).SetBalance(user.Balance.Add(req.Amount)).SaveX(ctx)
|
||||
utils.OkOrPanic(err, func(err error) error {
|
||||
return oops.
|
||||
WithContext(ctx).
|
||||
With("更新用户余额失败").
|
||||
Wrap(err)
|
||||
})
|
||||
err = tx.Commit()
|
||||
balance.BalanceService.ChangeUserBalance(ctx, user.ID, req.Amount)
|
||||
return utils.SuccessWithMsg("操作成功")
|
||||
}
|
||||
|
||||
@@ -170,18 +154,21 @@ func (s *AgentServiceV1) AgentPutInfoReq(ctx context.Context, req *v1.AgentPutIn
|
||||
With("创建事务失败").
|
||||
Wrap(err)
|
||||
})
|
||||
currentUser := tx.SysUser.Query().Where(sysuser.ID(utils.GetUserInfoFromCtx(ctx).ID)).WithAgent().WithRoles().OnlyX(ctx)
|
||||
defer tx.Rollback()
|
||||
user := tx.SysUser.Query().Where(sysuser.ID(req.ID)).WithParent().WithAgent().FirstX(ctx)
|
||||
if user.Edges.Parent == nil || user.Edges.Parent.ID != currentUser.ID {
|
||||
return utils.FailParam("非法的下级代理参数")
|
||||
}
|
||||
// 2. 如果没有代理权限
|
||||
if !utils.HasRole(currentUser.Edges.Roles, cst.KeyRoleAdmin) && !utils.HasRole(currentUser.Edges.Roles, cst.KeyRoleAgent) {
|
||||
return utils.FailParam("代理权限不足")
|
||||
}
|
||||
// 3. 检测代理费率或level是否低于自己
|
||||
if currentUser.Edges.Agent != nil && (req.Level > currentUser.Edges.Agent.Level || req.Rate.LessThan(currentUser.Edges.Agent.Rate)) {
|
||||
return utils.FailParam("代理等级或费率低于自己")
|
||||
if !utils.IsAdminFromCtx(ctx) {
|
||||
currentUser := tx.SysUser.Query().Where(sysuser.ID(utils.GetUserInfoFromCtx(ctx).ID)).WithAgent().WithRoles().OnlyX(ctx)
|
||||
if user.Edges.Parent == nil || user.Edges.Parent.ID != currentUser.ID {
|
||||
return utils.FailParam("非法的下级代理参数")
|
||||
}
|
||||
// 2. 如果没有代理权限
|
||||
if !utils.HasRole(currentUser.Edges.Roles, cst.KeyRoleAdmin) && !utils.HasRole(currentUser.Edges.Roles, cst.KeyRoleAgent) {
|
||||
return utils.FailParam("代理权限不足")
|
||||
}
|
||||
// 3. 检测代理费率或level是否低于自己
|
||||
if currentUser.Edges.Agent != nil && (req.Level > currentUser.Edges.Agent.Level || req.Rate.LessThan(currentUser.Edges.Agent.Rate)) {
|
||||
return utils.FailParam("代理等级或费率低于自己")
|
||||
}
|
||||
}
|
||||
// 5. 检测是否存在代理信息,
|
||||
// 将用户余额先计算为比例为1的用户余额
|
||||
@@ -201,7 +188,7 @@ func (s *AgentServiceV1) AgentPutInfoReq(ctx context.Context, req *v1.AgentPutIn
|
||||
//按照新费率计算余额
|
||||
newBalance := utils.TransformBalance(oldBalance, req.Rate)
|
||||
// 6. 更新用户余额
|
||||
tx.SysUser.UpdateOne(user).SetBalance(newBalance).SaveX(ctx)
|
||||
balance.BalanceService.ChangeUserBalance(ctx, user.ID, newBalance.Sub(oldBalance))
|
||||
err = tx.Commit()
|
||||
utils.OkOrPanic(err, func(err error) error {
|
||||
return oops.
|
||||
|
||||
@@ -17,9 +17,6 @@ type BalanceServiceV1 struct {
|
||||
}
|
||||
|
||||
func (v *BalanceServiceV1) ChangeUserBalance(ctx context.Context, userId int64, balance decimal.Decimal) {
|
||||
if utils.IsAdminFromCtx(ctx) {
|
||||
return
|
||||
}
|
||||
tx, err := db.Global.Tx(ctx)
|
||||
utils.OkOrPanic(err, oops.WithContext(ctx).Wrap)
|
||||
defer tx.Rollback()
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"likedream-goframe/internal/ent/sysuser"
|
||||
"likedream-goframe/internal/framework/queue"
|
||||
"likedream-goframe/internal/framework/schedule"
|
||||
"likedream-goframe/internal/service/balance"
|
||||
"likedream-goframe/internal/utils"
|
||||
"time"
|
||||
|
||||
@@ -28,6 +29,7 @@ import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/hibiken/asynq"
|
||||
"github.com/samber/oops"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
type CpTaskServiceV1 struct {
|
||||
@@ -172,11 +174,18 @@ func (v CpTaskServiceV1) PostExecute(ctx context.Context, req *v1.PostCpTaskExec
|
||||
if cpTask.Step == cptask.StepForm {
|
||||
utils.OkOrPanic(errors2.NewBusinessError(400, "请先完成前置参数设置"))
|
||||
}
|
||||
pointConsume := req.Frequency - cpTask.Frequency
|
||||
if req.Frequency < 1 || pointConsume < 0 {
|
||||
consume := req.Frequency - cpTask.Frequency
|
||||
if req.Frequency < 1 || consume < 0 {
|
||||
utils.OkOrPanic(errors2.NewBusinessError(400, "执行次数应不低于原有次数"))
|
||||
}
|
||||
//todo 扣积分
|
||||
//扣积分
|
||||
basePoint := decimal.NewFromInt(cst.BasePointCpdaily)
|
||||
if user.Edges.Agent != nil {
|
||||
basePoint = basePoint.Mul(user.Edges.Agent.Rate)
|
||||
}
|
||||
needPoint := basePoint.Mul(decimal.NewFromInt(int64(consume)))
|
||||
balance.BalanceService.ChangeUserBalance(ctx, user.ID, needPoint.Neg())
|
||||
// 更新任务
|
||||
e := db.WithTx(ctx, func(ctx context.Context, tx *ent.Tx) {
|
||||
cpTask := db.Global.CpTask.UpdateOne(cpTask).
|
||||
SetStep(cptask.StepComplete).
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "go.uber.org/automaxprocs"
|
||||
"likedream-goframe/cmd/entc"
|
||||
"likedream-goframe/cmd/server"
|
||||
"likedream-goframe/internal/cst"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
_ "time/tzdata"
|
||||
|
||||
_ "github.com/breml/rootcerts"
|
||||
|
||||
_ "go.uber.org/automaxprocs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// fix: time: unknown time zone Asia/Shanghai
|
||||
var err error
|
||||
cst.TimeZoneShangHai, err = time.LoadLocation("Asia/Shanghai")
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
args := ""
|
||||
if len(os.Args) > 1 {
|
||||
args = os.Args[1]
|
||||
|
||||
Reference in New Issue
Block a user