✨ 循环依赖 & 卡密管理

This commit is contained in:
sugarBecomer
2025-11-01 21:38:33 +08:00
parent cd854fd74e
commit 02ec22b80b
23 changed files with 282 additions and 169 deletions
+2
View File
@@ -3,6 +3,7 @@ package api
import (
"context"
"likedream-goframe/internal/controller/agent"
"likedream-goframe/internal/controller/card"
"likedream-goframe/internal/controller/common"
"likedream-goframe/internal/controller/cpdaily"
"likedream-goframe/internal/controller/menu"
@@ -45,6 +46,7 @@ func StartServer(ctx context.Context) {
// 代理信息路由
agentGroup := group.Group("/agent").Middleware(middleware.AuthHandler, middleware.PermissionHandler)
agentGroup.Bind(agent.NewV1())
agentGroup.Bind(card.NewCardCtrlV1())
// 今日校园
cpdailyGroup := group.Group("/cpdaily").Middleware(middleware.AuthHandler, middleware.PermissionHandler)
cpdailyGroup.Bind(cpdaily.NewCpUserCtrlV1())
+26
View File
@@ -0,0 +1,26 @@
package v1
import (
"likedream-goframe/internal/ent/syscard"
"github.com/gogf/gf/v2/frame/g"
)
type ListCardReq struct {
g.Meta `path:"/card" method:"get" tags:"Card" summary:"获取卡片列表"`
Content string `json:"content"`
Status syscard.Status `json:"status"`
Page int `json:"page" d:"1"`
Size int `json:"size" d:"10"`
}
type CardAddReq struct {
g.Meta `path:"/card" method:"post" tags:"Card" summary:"添加卡片"`
Value uint64 `json:"value"`
Length int64 `json:"length"`
}
type CardBanReq struct {
g.Meta `path:"/card/ban/{id}" method:"put" tags:"Card" summary:"禁用卡片"`
Id int64 `json:"id"`
}
+31
View File
@@ -0,0 +1,31 @@
package card
import (
"context"
v1 "likedream-goframe/internal/api/v1"
"likedream-goframe/internal/ent"
"likedream-goframe/internal/service"
"likedream-goframe/internal/utils"
)
type CardCtrlV1 struct {
}
func (c CardCtrlV1) List(ctx context.Context, req *v1.ListCardReq) (res *utils.Response[[]*ent.SysCard], err error) {
defer utils.Pass(&err)
return service.Global.Card.List(ctx, req), nil
}
func (c CardCtrlV1) Add(ctx context.Context, req *v1.CardAddReq) (res *utils.Response[any], err error) {
defer utils.Pass(&err)
return service.Global.Card.Add(ctx, req), nil
}
func (c CardCtrlV1) Ban(ctx context.Context, req *v1.CardBanReq) (res *utils.Response[any], err error) {
defer utils.Pass(&err)
return service.Global.Card.Ban(ctx, req), nil
}
func NewCardCtrlV1() ICardCtrlV1 {
return &CardCtrlV1{}
}
+14
View File
@@ -0,0 +1,14 @@
package card
import (
"context"
v1 "likedream-goframe/internal/api/v1"
"likedream-goframe/internal/ent"
"likedream-goframe/internal/utils"
)
type ICardCtrlV1 interface {
List(ctx context.Context, req *v1.ListCardReq) (res *utils.Response[[]*ent.SysCard], err error)
Add(ctx context.Context, req *v1.CardAddReq) (res *utils.Response[any], err error)
Ban(ctx context.Context, req *v1.CardBanReq) (res *utils.Response[any], err error)
}
-8
View File
@@ -1,8 +0,0 @@
package cst
const (
CardStatusEnable = iota + 1
CardStatusUsed
CardStatusDisable
CardStatusCashback
)
+3 -3
View File
@@ -158,7 +158,7 @@ var schemaGraph = func() *sqlgraph.Schema {
syscard.FieldCreateTime: {Type: field.TypeString, Column: syscard.FieldCreateTime},
syscard.FieldUpdateTime: {Type: field.TypeString, Column: syscard.FieldUpdateTime},
syscard.FieldContent: {Type: field.TypeString, Column: syscard.FieldContent},
syscard.FieldStatus: {Type: field.TypeInt, Column: syscard.FieldStatus},
syscard.FieldStatus: {Type: field.TypeEnum, Column: syscard.FieldStatus},
syscard.FieldValue: {Type: field.TypeUint64, Column: syscard.FieldValue},
syscard.FieldCreatorID: {Type: field.TypeInt64, Column: syscard.FieldCreatorID},
syscard.FieldUsedID: {Type: field.TypeInt64, Column: syscard.FieldUsedID},
@@ -1320,8 +1320,8 @@ func (f *SysCardFilter) WhereContent(p entql.StringP) {
f.Where(p.Field(syscard.FieldContent))
}
// WhereStatus applies the entql int predicate on the status field.
func (f *SysCardFilter) WhereStatus(p entql.IntP) {
// WhereStatus applies the entql string predicate on the status field.
func (f *SysCardFilter) WhereStatus(p entql.StringP) {
f.Where(p.Field(syscard.FieldStatus))
}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -181,7 +181,7 @@ var (
{Name: "create_time", Type: field.TypeString, SchemaType: map[string]string{"mysql": "datetime", "postgres": "timestamp", "sqlite3": "datetime"}},
{Name: "update_time", Type: field.TypeString, SchemaType: map[string]string{"mysql": "datetime", "postgres": "timestamp", "sqlite3": "datetime"}},
{Name: "content", Type: field.TypeString, Unique: true},
{Name: "status", Type: field.TypeInt, Default: 1},
{Name: "status", Type: field.TypeEnum, Enums: []string{"enable", "used", "cashback", "disable"}},
{Name: "value", Type: field.TypeUint64},
{Name: "cash_value", Type: field.TypeString, SchemaType: map[string]string{"mysql": "decimal(10,2)", "postgres": "numeric(10,2)"}},
{Name: "creator_id", Type: field.TypeInt64},
+6 -39
View File
@@ -5199,8 +5199,7 @@ type SysCardMutation struct {
create_time **ent2.CustomTime
update_time **ent2.CustomTime
content *string
status *int
addstatus *int
status *syscard.Status
value *uint64
addvalue *int64
cash_value *decimal.Decimal
@@ -5423,13 +5422,12 @@ func (m *SysCardMutation) ResetContent() {
}
// SetStatus sets the "status" field.
func (m *SysCardMutation) SetStatus(i int) {
m.status = &i
m.addstatus = nil
func (m *SysCardMutation) SetStatus(s syscard.Status) {
m.status = &s
}
// Status returns the value of the "status" field in the mutation.
func (m *SysCardMutation) Status() (r int, exists bool) {
func (m *SysCardMutation) Status() (r syscard.Status, exists bool) {
v := m.status
if v == nil {
return
@@ -5440,7 +5438,7 @@ func (m *SysCardMutation) Status() (r int, exists bool) {
// OldStatus returns the old "status" field's value of the SysCard entity.
// If the SysCard object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *SysCardMutation) OldStatus(ctx context.Context) (v int, err error) {
func (m *SysCardMutation) OldStatus(ctx context.Context) (v syscard.Status, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldStatus is only allowed on UpdateOne operations")
}
@@ -5454,28 +5452,9 @@ func (m *SysCardMutation) OldStatus(ctx context.Context) (v int, err error) {
return oldValue.Status, nil
}
// AddStatus adds i to the "status" field.
func (m *SysCardMutation) AddStatus(i int) {
if m.addstatus != nil {
*m.addstatus += i
} else {
m.addstatus = &i
}
}
// AddedStatus returns the value that was added to the "status" field in this mutation.
func (m *SysCardMutation) AddedStatus() (r int, exists bool) {
v := m.addstatus
if v == nil {
return
}
return *v, true
}
// ResetStatus resets all changes to the "status" field.
func (m *SysCardMutation) ResetStatus() {
m.status = nil
m.addstatus = nil
}
// SetValue sets the "value" field.
@@ -5944,7 +5923,7 @@ func (m *SysCardMutation) SetField(name string, value ent.Value) error {
m.SetContent(v)
return nil
case syscard.FieldStatus:
v, ok := value.(int)
v, ok := value.(syscard.Status)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
@@ -5993,9 +5972,6 @@ func (m *SysCardMutation) SetField(name string, value ent.Value) error {
// this mutation.
func (m *SysCardMutation) AddedFields() []string {
var fields []string
if m.addstatus != nil {
fields = append(fields, syscard.FieldStatus)
}
if m.addvalue != nil {
fields = append(fields, syscard.FieldValue)
}
@@ -6007,8 +5983,6 @@ func (m *SysCardMutation) AddedFields() []string {
// was not set, or was not defined in the schema.
func (m *SysCardMutation) AddedField(name string) (ent.Value, bool) {
switch name {
case syscard.FieldStatus:
return m.AddedStatus()
case syscard.FieldValue:
return m.AddedValue()
}
@@ -6020,13 +5994,6 @@ func (m *SysCardMutation) AddedField(name string) (ent.Value, bool) {
// type.
func (m *SysCardMutation) AddField(name string, value ent.Value) error {
switch name {
case syscard.FieldStatus:
v, ok := value.(int)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.AddStatus(v)
return nil
case syscard.FieldValue:
v, ok := value.(int64)
if !ok {
-4
View File
@@ -110,10 +110,6 @@ func init() {
syscardDescUpdateTime := syscardMixinFields0[1].Descriptor()
// syscard.DefaultUpdateTime holds the default value on creation for the update_time field.
syscard.DefaultUpdateTime = syscardDescUpdateTime.Default.(func() *ent2.CustomTime)
// syscardDescStatus is the schema descriptor for status field.
syscardDescStatus := syscardFields[1].Descriptor()
// syscard.DefaultStatus holds the default value on creation for the status field.
syscard.DefaultStatus = syscardDescStatus.Default.(int)
// syscardDescCashValue is the schema descriptor for cash_value field.
syscardDescCashValue := syscardFields[6].Descriptor()
// syscard.DefaultCashValue holds the default value on creation for the cash_value field.
+6 -7
View File
@@ -1,7 +1,6 @@
package schema
import (
"likedream-goframe/internal/cst"
"likedream-goframe/internal/ent/schema/mix"
"likedream-goframe/internal/framework/ent2"
@@ -21,12 +20,12 @@ type SysCard struct {
func (SysCard) Fields() []ent.Field {
return []ent.Field{
field.String("content").Unique(), // 充值卡密
field.Int("status").Default(cst.CardStatusEnable), //1:未使用 2:使用 3:禁用
field.Uint64("value"), // 充值金额
field.Int64("creator_id"), //创建者
field.Int64("used_id").Optional(), //使用者
field.Int64("cash_user_id").Optional(), //返现者
field.String("content").Unique(), // 充值卡密
field.Enum("status").Values("enable", "used", "cashback", "disable"), // 状态 启用 使用 返现 禁用
field.Uint64("value"), // 充值金额
field.Int64("creator_id"), //创建者
field.Int64("used_id").Optional(), //使用者
field.Int64("cash_user_id").Optional(), //返现者
field.String("cash_value").GoType(decimal.Decimal{}).SchemaType(map[string]string{
dialect.MySQL: "decimal(10,2)",
dialect.Postgres: "numeric(10,2)",
+5 -5
View File
@@ -26,7 +26,7 @@ type SysCard struct {
// Content holds the value of the "content" field.
Content string `json:"content,omitempty"`
// Status holds the value of the "status" field.
Status int `json:"status,omitempty"`
Status syscard.Status `json:"status,omitempty"`
// Value holds the value of the "value" field.
Value uint64 `json:"value,omitempty"`
// CreatorID holds the value of the "creator_id" field.
@@ -98,9 +98,9 @@ func (*SysCard) scanValues(columns []string) ([]any, error) {
values[i] = new(decimal.Decimal)
case syscard.FieldCreateTime, syscard.FieldUpdateTime:
values[i] = new(ent2.CustomTime)
case syscard.FieldID, syscard.FieldStatus, syscard.FieldValue, syscard.FieldCreatorID, syscard.FieldUsedID, syscard.FieldCashUserID:
case syscard.FieldID, syscard.FieldValue, syscard.FieldCreatorID, syscard.FieldUsedID, syscard.FieldCashUserID:
values[i] = new(sql.NullInt64)
case syscard.FieldContent:
case syscard.FieldContent, syscard.FieldStatus:
values[i] = new(sql.NullString)
default:
values[i] = new(sql.UnknownType)
@@ -142,10 +142,10 @@ func (_m *SysCard) assignValues(columns []string, values []any) error {
_m.Content = value.String
}
case syscard.FieldStatus:
if value, ok := values[i].(*sql.NullInt64); !ok {
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field status", values[i])
} else if value.Valid {
_m.Status = int(value.Int64)
_m.Status = syscard.Status(value.String)
}
case syscard.FieldValue:
if value, ok := values[i].(*sql.NullInt64); !ok {
+26 -2
View File
@@ -3,6 +3,7 @@
package syscard
import (
"fmt"
"likedream-goframe/internal/framework/ent2"
"entgo.io/ent"
@@ -100,12 +101,35 @@ var (
DefaultCreateTime func() *ent2.CustomTime
// DefaultUpdateTime holds the default value on creation for the "update_time" field.
DefaultUpdateTime func() *ent2.CustomTime
// DefaultStatus holds the default value on creation for the "status" field.
DefaultStatus int
// DefaultCashValue holds the default value on creation for the "cash_value" field.
DefaultCashValue func() decimal.Decimal
)
// Status defines the type for the "status" enum field.
type Status string
// Status values.
const (
StatusEnable Status = "enable"
StatusUsed Status = "used"
StatusCashback Status = "cashback"
StatusDisable Status = "disable"
)
func (s Status) String() string {
return string(s)
}
// StatusValidator is a validator for the "status" field enum values. It is called by the builders before save.
func StatusValidator(s Status) error {
switch s {
case StatusEnable, StatusUsed, StatusCashback, StatusDisable:
return nil
default:
return fmt.Errorf("syscard: invalid enum value for status field: %q", s)
}
}
// OrderOption defines the ordering options for the SysCard queries.
type OrderOption func(*sql.Selector)
+4 -29
View File
@@ -72,11 +72,6 @@ func Content(v string) predicate.SysCard {
return predicate.SysCard(sql.FieldEQ(FieldContent, v))
}
// Status applies equality check predicate on the "status" field. It's identical to StatusEQ.
func Status(v int) predicate.SysCard {
return predicate.SysCard(sql.FieldEQ(FieldStatus, v))
}
// Value applies equality check predicate on the "value" field. It's identical to ValueEQ.
func Value(v uint64) predicate.SysCard {
return predicate.SysCard(sql.FieldEQ(FieldValue, v))
@@ -308,45 +303,25 @@ func ContentContainsFold(v string) predicate.SysCard {
}
// StatusEQ applies the EQ predicate on the "status" field.
func StatusEQ(v int) predicate.SysCard {
func StatusEQ(v Status) predicate.SysCard {
return predicate.SysCard(sql.FieldEQ(FieldStatus, v))
}
// StatusNEQ applies the NEQ predicate on the "status" field.
func StatusNEQ(v int) predicate.SysCard {
func StatusNEQ(v Status) predicate.SysCard {
return predicate.SysCard(sql.FieldNEQ(FieldStatus, v))
}
// StatusIn applies the In predicate on the "status" field.
func StatusIn(vs ...int) predicate.SysCard {
func StatusIn(vs ...Status) predicate.SysCard {
return predicate.SysCard(sql.FieldIn(FieldStatus, vs...))
}
// StatusNotIn applies the NotIn predicate on the "status" field.
func StatusNotIn(vs ...int) predicate.SysCard {
func StatusNotIn(vs ...Status) predicate.SysCard {
return predicate.SysCard(sql.FieldNotIn(FieldStatus, vs...))
}
// StatusGT applies the GT predicate on the "status" field.
func StatusGT(v int) predicate.SysCard {
return predicate.SysCard(sql.FieldGT(FieldStatus, v))
}
// StatusGTE applies the GTE predicate on the "status" field.
func StatusGTE(v int) predicate.SysCard {
return predicate.SysCard(sql.FieldGTE(FieldStatus, v))
}
// StatusLT applies the LT predicate on the "status" field.
func StatusLT(v int) predicate.SysCard {
return predicate.SysCard(sql.FieldLT(FieldStatus, v))
}
// StatusLTE applies the LTE predicate on the "status" field.
func StatusLTE(v int) predicate.SysCard {
return predicate.SysCard(sql.FieldLTE(FieldStatus, v))
}
// ValueEQ applies the EQ predicate on the "value" field.
func ValueEQ(v uint64) predicate.SysCard {
return predicate.SysCard(sql.FieldEQ(FieldValue, v))
+10 -37
View File
@@ -43,19 +43,11 @@ func (_c *SysCardCreate) SetContent(v string) *SysCardCreate {
}
// SetStatus sets the "status" field.
func (_c *SysCardCreate) SetStatus(v int) *SysCardCreate {
func (_c *SysCardCreate) SetStatus(v syscard.Status) *SysCardCreate {
_c.mutation.SetStatus(v)
return _c
}
// SetNillableStatus sets the "status" field if the given value is not nil.
func (_c *SysCardCreate) SetNillableStatus(v *int) *SysCardCreate {
if v != nil {
_c.SetStatus(*v)
}
return _c
}
// SetValue sets the "value" field.
func (_c *SysCardCreate) SetValue(v uint64) *SysCardCreate {
_c.mutation.SetValue(v)
@@ -190,10 +182,6 @@ func (_c *SysCardCreate) defaults() error {
v := syscard.DefaultUpdateTime()
_c.mutation.SetUpdateTime(v)
}
if _, ok := _c.mutation.Status(); !ok {
v := syscard.DefaultStatus
_c.mutation.SetStatus(v)
}
if _, ok := _c.mutation.CashValue(); !ok {
if syscard.DefaultCashValue == nil {
return fmt.Errorf("ent: uninitialized syscard.DefaultCashValue (forgotten import ent/runtime?)")
@@ -218,6 +206,11 @@ func (_c *SysCardCreate) check() error {
if _, ok := _c.mutation.Status(); !ok {
return &ValidationError{Name: "status", err: errors.New(`ent: missing required field "SysCard.status"`)}
}
if v, ok := _c.mutation.Status(); ok {
if err := syscard.StatusValidator(v); err != nil {
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "SysCard.status": %w`, err)}
}
}
if _, ok := _c.mutation.Value(); !ok {
return &ValidationError{Name: "value", err: errors.New(`ent: missing required field "SysCard.value"`)}
}
@@ -271,7 +264,7 @@ func (_c *SysCardCreate) createSpec() (*SysCard, *sqlgraph.CreateSpec) {
_node.Content = value
}
if value, ok := _c.mutation.Status(); ok {
_spec.SetField(syscard.FieldStatus, field.TypeInt, value)
_spec.SetField(syscard.FieldStatus, field.TypeEnum, value)
_node.Status = value
}
if value, ok := _c.mutation.Value(); ok {
@@ -413,7 +406,7 @@ func (u *SysCardUpsert) UpdateContent() *SysCardUpsert {
}
// SetStatus sets the "status" field.
func (u *SysCardUpsert) SetStatus(v int) *SysCardUpsert {
func (u *SysCardUpsert) SetStatus(v syscard.Status) *SysCardUpsert {
u.Set(syscard.FieldStatus, v)
return u
}
@@ -424,12 +417,6 @@ func (u *SysCardUpsert) UpdateStatus() *SysCardUpsert {
return u
}
// AddStatus adds v to the "status" field.
func (u *SysCardUpsert) AddStatus(v int) *SysCardUpsert {
u.Add(syscard.FieldStatus, v)
return u
}
// SetValue sets the "value" field.
func (u *SysCardUpsert) SetValue(v uint64) *SysCardUpsert {
u.Set(syscard.FieldValue, v)
@@ -582,19 +569,12 @@ func (u *SysCardUpsertOne) UpdateContent() *SysCardUpsertOne {
}
// SetStatus sets the "status" field.
func (u *SysCardUpsertOne) SetStatus(v int) *SysCardUpsertOne {
func (u *SysCardUpsertOne) SetStatus(v syscard.Status) *SysCardUpsertOne {
return u.Update(func(s *SysCardUpsert) {
s.SetStatus(v)
})
}
// AddStatus adds v to the "status" field.
func (u *SysCardUpsertOne) AddStatus(v int) *SysCardUpsertOne {
return u.Update(func(s *SysCardUpsert) {
s.AddStatus(v)
})
}
// UpdateStatus sets the "status" field to the value that was provided on create.
func (u *SysCardUpsertOne) UpdateStatus() *SysCardUpsertOne {
return u.Update(func(s *SysCardUpsert) {
@@ -933,19 +913,12 @@ func (u *SysCardUpsertBulk) UpdateContent() *SysCardUpsertBulk {
}
// SetStatus sets the "status" field.
func (u *SysCardUpsertBulk) SetStatus(v int) *SysCardUpsertBulk {
func (u *SysCardUpsertBulk) SetStatus(v syscard.Status) *SysCardUpsertBulk {
return u.Update(func(s *SysCardUpsert) {
s.SetStatus(v)
})
}
// AddStatus adds v to the "status" field.
func (u *SysCardUpsertBulk) AddStatus(v int) *SysCardUpsertBulk {
return u.Update(func(s *SysCardUpsert) {
s.AddStatus(v)
})
}
// UpdateStatus sets the "status" field to the value that was provided on create.
func (u *SysCardUpsertBulk) UpdateStatus() *SysCardUpsertBulk {
return u.Update(func(s *SysCardUpsert) {
+16 -26
View File
@@ -53,26 +53,19 @@ func (_u *SysCardUpdate) SetNillableContent(v *string) *SysCardUpdate {
}
// SetStatus sets the "status" field.
func (_u *SysCardUpdate) SetStatus(v int) *SysCardUpdate {
_u.mutation.ResetStatus()
func (_u *SysCardUpdate) SetStatus(v syscard.Status) *SysCardUpdate {
_u.mutation.SetStatus(v)
return _u
}
// SetNillableStatus sets the "status" field if the given value is not nil.
func (_u *SysCardUpdate) SetNillableStatus(v *int) *SysCardUpdate {
func (_u *SysCardUpdate) SetNillableStatus(v *syscard.Status) *SysCardUpdate {
if v != nil {
_u.SetStatus(*v)
}
return _u
}
// AddStatus adds value to the "status" field.
func (_u *SysCardUpdate) AddStatus(v int) *SysCardUpdate {
_u.mutation.AddStatus(v)
return _u
}
// SetValue sets the "value" field.
func (_u *SysCardUpdate) SetValue(v uint64) *SysCardUpdate {
_u.mutation.ResetValue()
@@ -243,6 +236,11 @@ func (_u *SysCardUpdate) ExecX(ctx context.Context) {
// check runs all checks and user-defined validators on the builder.
func (_u *SysCardUpdate) check() error {
if v, ok := _u.mutation.Status(); ok {
if err := syscard.StatusValidator(v); err != nil {
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "SysCard.status": %w`, err)}
}
}
if _u.mutation.CreatorCleared() && len(_u.mutation.CreatorIDs()) > 0 {
return errors.New(`ent: clearing a required unique edge "SysCard.creator"`)
}
@@ -274,10 +272,7 @@ func (_u *SysCardUpdate) sqlSave(ctx context.Context) (_node int, err error) {
_spec.SetField(syscard.FieldContent, field.TypeString, value)
}
if value, ok := _u.mutation.Status(); ok {
_spec.SetField(syscard.FieldStatus, field.TypeInt, value)
}
if value, ok := _u.mutation.AddedStatus(); ok {
_spec.AddField(syscard.FieldStatus, field.TypeInt, value)
_spec.SetField(syscard.FieldStatus, field.TypeEnum, value)
}
if value, ok := _u.mutation.Value(); ok {
_spec.SetField(syscard.FieldValue, field.TypeUint64, value)
@@ -426,26 +421,19 @@ func (_u *SysCardUpdateOne) SetNillableContent(v *string) *SysCardUpdateOne {
}
// SetStatus sets the "status" field.
func (_u *SysCardUpdateOne) SetStatus(v int) *SysCardUpdateOne {
_u.mutation.ResetStatus()
func (_u *SysCardUpdateOne) SetStatus(v syscard.Status) *SysCardUpdateOne {
_u.mutation.SetStatus(v)
return _u
}
// SetNillableStatus sets the "status" field if the given value is not nil.
func (_u *SysCardUpdateOne) SetNillableStatus(v *int) *SysCardUpdateOne {
func (_u *SysCardUpdateOne) SetNillableStatus(v *syscard.Status) *SysCardUpdateOne {
if v != nil {
_u.SetStatus(*v)
}
return _u
}
// AddStatus adds value to the "status" field.
func (_u *SysCardUpdateOne) AddStatus(v int) *SysCardUpdateOne {
_u.mutation.AddStatus(v)
return _u
}
// SetValue sets the "value" field.
func (_u *SysCardUpdateOne) SetValue(v uint64) *SysCardUpdateOne {
_u.mutation.ResetValue()
@@ -629,6 +617,11 @@ func (_u *SysCardUpdateOne) ExecX(ctx context.Context) {
// check runs all checks and user-defined validators on the builder.
func (_u *SysCardUpdateOne) check() error {
if v, ok := _u.mutation.Status(); ok {
if err := syscard.StatusValidator(v); err != nil {
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "SysCard.status": %w`, err)}
}
}
if _u.mutation.CreatorCleared() && len(_u.mutation.CreatorIDs()) > 0 {
return errors.New(`ent: clearing a required unique edge "SysCard.creator"`)
}
@@ -677,10 +670,7 @@ func (_u *SysCardUpdateOne) sqlSave(ctx context.Context) (_node *SysCard, err er
_spec.SetField(syscard.FieldContent, field.TypeString, value)
}
if value, ok := _u.mutation.Status(); ok {
_spec.SetField(syscard.FieldStatus, field.TypeInt, value)
}
if value, ok := _u.mutation.AddedStatus(); ok {
_spec.AddField(syscard.FieldStatus, field.TypeInt, value)
_spec.SetField(syscard.FieldStatus, field.TypeEnum, value)
}
if value, ok := _u.mutation.Value(); ok {
_spec.SetField(syscard.FieldValue, field.TypeUint64, value)
@@ -15,7 +15,7 @@ import (
"likedream-goframe/internal/ent/sysuser"
"likedream-goframe/internal/framework/errors"
"likedream-goframe/internal/framework/model/email"
"likedream-goframe/internal/service"
email2 "likedream-goframe/internal/service/email"
"likedream-goframe/internal/utils"
"time"
@@ -25,6 +25,8 @@ import (
"github.com/samber/oops"
)
var emailService = email2.NewV1()
type CpdailyTaskHandler struct{}
func (c *CpdailyTaskHandler) ProcessTask(ctx context.Context, task *asynq.Task) (err error) {
@@ -205,5 +207,5 @@ func (c *CpdailyTaskHandler) sendTaskNotificationEmail(ctx context.Context, task
return // 没有邮箱地址,不发送邮件
}
service.Global.Email.SendTaskNotificationEmail(ctx, emailAddr, taskName, status, details)
emailService.SendTaskNotificationEmail(ctx, emailAddr, taskName, status, details)
}
+3 -1
View File
@@ -74,6 +74,7 @@ func (s *AgentServiceV1) Add(ctx context.Context, req *v1.AgentAddReq) *utils.Re
With("创建事务失败").
Wrap(err)
})
defer tx.Rollback()
user := tx.SysUser.Query().Where(sysuser.IDEQ(currentUser.ID)).OnlyX(ctx)
user.Balance = utils.CalculateBalance(user.Balance, req.Rate, req.Balance, req.Rate)
if user.Balance.LessThan(decimal.NewFromInt(0)) {
@@ -95,13 +96,14 @@ func (s *AgentServiceV1) Add(ctx context.Context, req *v1.AgentAddReq) *utils.Re
SetParent(user)
save := tmp.SaveX(ctx)
// 关联角色
role := tx.SysRole.Query().Where(sysrole.NameEQ("agent")).AllX(ctx)
role := tx.SysRole.Query().Where(sysrole.NameEQ(cst.KeyRoleAgent)).AllX(ctx)
tx.SysUser.UpdateOne(save).AddRoles(role...).ExecX(ctx)
// 创建代理
tx.SysAgent.Create().
SetLevel(req.Level).
SetRate(req.Rate).
SaveX(ctx)
err = tx.Commit()
return utils.SuccessWithMsg("")
}
@@ -0,0 +1,33 @@
package balance
import (
"context"
"likedream-goframe/internal/common/errors"
"likedream-goframe/internal/db"
"likedream-goframe/internal/ent/sysuser"
"likedream-goframe/internal/utils"
"github.com/samber/oops"
"github.com/shopspring/decimal"
)
var BalanceService = &BalanceServiceV1{}
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()
user := tx.SysUser.Query().Where(sysuser.ID(userId)).WithRoles().ForUpdate().OnlyX(ctx)
newBalance := user.Balance.Add(balance)
if newBalance.LessThan(decimal.Zero) {
utils.OkOrPanic(errors.NewBusinessError(400, "余额不足"))
}
tx.SysUser.Update().Where(sysuser.ID(userId)).SetBalance(newBalance).SaveX(ctx)
tx.Commit()
}
+74
View File
@@ -0,0 +1,74 @@
package card
import (
"context"
v1 "likedream-goframe/internal/api/v1"
"likedream-goframe/internal/db"
"likedream-goframe/internal/ent"
"likedream-goframe/internal/ent/syscard"
"likedream-goframe/internal/ent/sysuser"
"likedream-goframe/internal/service/balance"
"likedream-goframe/internal/utils"
"github.com/shopspring/decimal"
)
type CardServiceV1 struct{}
func (v CardServiceV1) List(ctx context.Context, req *v1.ListCardReq) *utils.Response[[]*ent.SysCard] {
user := utils.GetUserInfoFromCtx(ctx)
query := db.Global.SysCard.Query().Where(syscard.HasCreatorWith(sysuser.IDEQ(user.ID))).WithUser().WithCashUser()
if req.Content != "" {
query.Where(syscard.ContentEQ(req.Content))
}
if req.Status != "" {
query.Where(syscard.StatusEQ(req.Status))
}
query.Order(ent.Desc(syscard.FieldCreateTime))
//查询总数
total := query.CountX(ctx)
var data []*ent.SysCard
if total > 0 {
query.Limit(req.Size).Offset((req.Page - 1) * req.Size)
data = query.AllX(ctx)
} else {
data = nil
}
return utils.SuccessWithTotal[[]*ent.SysCard](data, total)
}
func (v CardServiceV1) Ban(ctx context.Context, req *v1.CardBanReq) *utils.Response[any] {
user := utils.GetUserInfoFromCtx(ctx)
card := db.Global.SysCard.Query().Where(syscard.IDEQ(req.Id), syscard.HasCreatorWith(sysuser.ID(user.ID))).OnlyX(ctx)
if card == nil {
return utils.FailParam("卡密不存在")
}
db.Global.SysCard.UpdateOne(card).SetStatus(syscard.StatusDisable).ExecX(ctx)
return utils.SuccessWithMsg("禁用成功")
}
func (v CardServiceV1) Add(ctx context.Context, req *v1.CardAddReq) *utils.Response[any] {
user := utils.GetUserInfoFromCtx(ctx)
// 总积分
pointTotal := decimal.NewFromUint64(req.Value).Mul(decimal.NewFromInt(req.Length))
// 消费积分
consumeBalance := decimal.Zero.Sub(utils.ConsumeBalance(user.Edges.Agent.Rate, pointTotal))
// 扣除余额
balance.BalanceService.ChangeUserBalance(ctx, user.ID, consumeBalance)
// 添加卡密
var cards []*ent.SysCardCreate
for range req.Length {
cards = append(cards, db.Global.SysCard.Create().
SetContent(utils.GenerateRandomString(32)).
SetValue(req.Value).
SetStatus(syscard.StatusEnable).
SetCreator(user))
}
data := db.Global.SysCard.CreateBulk(cards...).SaveX(ctx)
return utils.SuccessWithData[any](data)
}
func NewCardServiceV1() *CardServiceV1 {
return &CardServiceV1{}
}
+3
View File
@@ -2,6 +2,7 @@ package service
import (
"likedream-goframe/internal/service/agent"
"likedream-goframe/internal/service/card"
"likedream-goframe/internal/service/cpdaily"
"likedream-goframe/internal/service/email"
"likedream-goframe/internal/service/menu"
@@ -20,6 +21,7 @@ type globalService struct {
User *user.UserServiceV1
CpUser *cpdaily.CpUserServiceV1
CpTask *cpdaily.CpTaskServiceV1
Card *card.CardServiceV1
}
var Global = globalService{
@@ -32,4 +34,5 @@ var Global = globalService{
User: user.NewV1(),
CpUser: cpdaily.NewCpUserServiceV1(),
CpTask: cpdaily.NewCpTaskServiceV1(),
Card: card.NewCardServiceV1(),
}
@@ -54,8 +54,12 @@ func (s *UserInfoServiceV1) PermissionList(ctx context.Context) *utils.Response[
func (s *UserInfoServiceV1) UserInfo(ctx context.Context) *utils.Response[any] {
user := utils.GetUserInfoFromCtx(ctx)
userInfo := db.Global.SysUser.Query().Where(sysuser.ID(user.ID)).WithParent().WithAgent().WithRoles().FirstX(ctx)
userInfo := db.Global.SysUser.Query().Where(sysuser.ID(user.ID)).WithParent().WithAgent(func(query *ent.SysAgentQuery) {
}).WithRoles().FirstX(ctx)
userInfo.Password = ""
if userInfo.Edges.Agent != nil {
userInfo.Edges.Agent.Edges.Users = nil
}
return utils.SuccessWithData[any](userInfo)
}
@@ -119,7 +123,7 @@ func (s *UserInfoServiceV1) CardRecharge(ctx context.Context, req *v1.CardRechar
if ent.IsNotFound(err) {
return utils.FailParam("卡密错误")
}
if card.Status != cst.CardStatusEnable {
if card.Status != syscard.StatusEnable {
return utils.FailParam("卡密错误")
}
if utils.HasRole(user.Edges.Roles, cst.KeyRoleAgent) {
@@ -137,9 +141,10 @@ func (s *UserInfoServiceV1) CardRecharge(ctx context.Context, req *v1.CardRechar
cashbackValue = cashbackValue.Mul(parent.Edges.Agent.Rate)
}
tx.SysUser.UpdateOneID(user.Edges.Parent.ID).SetBalance(parent.Balance.Add(cashbackValue)).SetInviteCashback(parent.InviteCashback.Add(cashbackValue)).ExecX(ctx)
tx.SysCard.UpdateOneID(card.ID).SetStatus(cst.CardStatusCashback).SetUsedID(user.ID).SetCashUserID(user.Edges.Parent.ID).SetCashValue(cashbackValue).ExecX(ctx)
tx.SysCard.UpdateOneID(card.ID).SetStatus(syscard.StatusCashback).SetUsedID(user.ID).SetCashUserID(user.Edges.Parent.ID).SetCashValue(cashbackValue).ExecX(ctx)
} else {
tx.SysCard.UpdateOneID(card.ID).SetStatus(cst.CardStatusUsed).SetUsedID(user.ID).ExecX(ctx)
//tx.SysCard.UpdateOneID(card.ID).SetStatus(cst.CardStatusUsed).SetUsedID(user.ID).ExecX(ctx)
tx.SysCard.UpdateOneID(card.ID).SetStatus(syscard.StatusUsed).SetUsedID(user.ID).ExecX(ctx)
}
tx.SysUser.UpdateOneID(user.ID).SetBalance(user.Balance.Add(decimal.NewFromUint64(card.Value))).ExecX(ctx)
err = tx.Commit()
+5
View File
@@ -28,6 +28,11 @@ func CalculateBalance(balance decimal.Decimal, rate decimal.Decimal, amount deci
return balance.Sub(amount.Div(amountRate).Mul(rate)).Truncate(2)
}
// ConsumeBalance 消费余额
func ConsumeBalance(balance decimal.Decimal, rate decimal.Decimal) decimal.Decimal {
return balance.Mul(rate)
}
// TransformBalance 将用户余额转换成代理余额
func TransformBalance(balance decimal.Decimal, rate decimal.Decimal) decimal.Decimal {
return balance.Mul(rate).Truncate(2)