Adds the B.4 storefront on top of the VAS credits/grants infrastructure: - `sku` entity: storage-capacity and group-upgrade products with duration, cash price, optional point price, label, and bullets - Atomic `PurchaseSku`: guarded point debit + grant (capacity or group) + purchase ledger entry in one tx - Admin SKU list/upsert/delete + functional product tables in the VAS settings page - User `/shop` page (Memberships / Storage packs / Redeem tabs) with balance chip, point-purchase cards, and shared redeem input - Cash-price SKUs shown as placeholders — payment processors remain out of scope Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>pull/3587/head
parent
8febe344ac
commit
32410b9874
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,52 @@
|
|||||||
|
package schema
|
||||||
|
|
||||||
|
import (
|
||||||
|
"entgo.io/ent"
|
||||||
|
"entgo.io/ent/schema/field"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sku holds the schema definition for purchasable products: a storage
|
||||||
|
// capacity pack (amount = bytes) or a membership upgrade (amount = target
|
||||||
|
// group id). duration is seconds; 0 means the grant never expires. points
|
||||||
|
// is the credit price; NULL means the product cannot be bought with
|
||||||
|
// points. price is the display cash price in the smallest currency unit —
|
||||||
|
// cash payment processors are intentionally out of scope.
|
||||||
|
type Sku struct {
|
||||||
|
ent.Schema
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fields of the Sku.
|
||||||
|
func (Sku) Fields() []ent.Field {
|
||||||
|
return []ent.Field{
|
||||||
|
field.String("name"),
|
||||||
|
field.Enum("type").
|
||||||
|
Values("storage", "group"),
|
||||||
|
field.Int64("amount"),
|
||||||
|
field.Int64("duration").
|
||||||
|
Optional(),
|
||||||
|
field.Int64("price").
|
||||||
|
Optional(),
|
||||||
|
field.Int64("points").
|
||||||
|
Optional().
|
||||||
|
Nillable(),
|
||||||
|
field.String("label").
|
||||||
|
Optional(),
|
||||||
|
field.String("des").
|
||||||
|
Optional(),
|
||||||
|
field.Bool("enabled").
|
||||||
|
Default(true),
|
||||||
|
field.Int("weight").
|
||||||
|
Default(0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edges of the Sku.
|
||||||
|
func (Sku) Edges() []ent.Edge {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Sku) Mixin() []ent.Mixin {
|
||||||
|
return []ent.Mixin{
|
||||||
|
CommonMixin{},
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,246 @@
|
|||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"github.com/cloudreve/Cloudreve/v4/ent/sku"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sku is the model entity for the Sku schema.
|
||||||
|
type Sku struct {
|
||||||
|
config `json:"-"`
|
||||||
|
// ID of the ent.
|
||||||
|
ID int `json:"id,omitempty"`
|
||||||
|
// CreatedAt holds the value of the "created_at" field.
|
||||||
|
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
|
// UpdatedAt holds the value of the "updated_at" field.
|
||||||
|
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
||||||
|
// DeletedAt holds the value of the "deleted_at" field.
|
||||||
|
DeletedAt *time.Time `json:"deleted_at,omitempty"`
|
||||||
|
// Name holds the value of the "name" field.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
// Type holds the value of the "type" field.
|
||||||
|
Type sku.Type `json:"type,omitempty"`
|
||||||
|
// Amount holds the value of the "amount" field.
|
||||||
|
Amount int64 `json:"amount,omitempty"`
|
||||||
|
// Duration holds the value of the "duration" field.
|
||||||
|
Duration int64 `json:"duration,omitempty"`
|
||||||
|
// Price holds the value of the "price" field.
|
||||||
|
Price int64 `json:"price,omitempty"`
|
||||||
|
// Points holds the value of the "points" field.
|
||||||
|
Points *int64 `json:"points,omitempty"`
|
||||||
|
// Label holds the value of the "label" field.
|
||||||
|
Label string `json:"label,omitempty"`
|
||||||
|
// Des holds the value of the "des" field.
|
||||||
|
Des string `json:"des,omitempty"`
|
||||||
|
// Enabled holds the value of the "enabled" field.
|
||||||
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
|
// Weight holds the value of the "weight" field.
|
||||||
|
Weight int `json:"weight,omitempty"`
|
||||||
|
selectValues sql.SelectValues
|
||||||
|
}
|
||||||
|
|
||||||
|
// scanValues returns the types for scanning values from sql.Rows.
|
||||||
|
func (*Sku) scanValues(columns []string) ([]any, error) {
|
||||||
|
values := make([]any, len(columns))
|
||||||
|
for i := range columns {
|
||||||
|
switch columns[i] {
|
||||||
|
case sku.FieldEnabled:
|
||||||
|
values[i] = new(sql.NullBool)
|
||||||
|
case sku.FieldID, sku.FieldAmount, sku.FieldDuration, sku.FieldPrice, sku.FieldPoints, sku.FieldWeight:
|
||||||
|
values[i] = new(sql.NullInt64)
|
||||||
|
case sku.FieldName, sku.FieldType, sku.FieldLabel, sku.FieldDes:
|
||||||
|
values[i] = new(sql.NullString)
|
||||||
|
case sku.FieldCreatedAt, sku.FieldUpdatedAt, sku.FieldDeletedAt:
|
||||||
|
values[i] = new(sql.NullTime)
|
||||||
|
default:
|
||||||
|
values[i] = new(sql.UnknownType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||||
|
// to the Sku fields.
|
||||||
|
func (s *Sku) assignValues(columns []string, values []any) error {
|
||||||
|
if m, n := len(values), len(columns); m < n {
|
||||||
|
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
|
||||||
|
}
|
||||||
|
for i := range columns {
|
||||||
|
switch columns[i] {
|
||||||
|
case sku.FieldID:
|
||||||
|
value, ok := values[i].(*sql.NullInt64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field id", value)
|
||||||
|
}
|
||||||
|
s.ID = int(value.Int64)
|
||||||
|
case sku.FieldCreatedAt:
|
||||||
|
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field created_at", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.CreatedAt = value.Time
|
||||||
|
}
|
||||||
|
case sku.FieldUpdatedAt:
|
||||||
|
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.UpdatedAt = value.Time
|
||||||
|
}
|
||||||
|
case sku.FieldDeletedAt:
|
||||||
|
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.DeletedAt = new(time.Time)
|
||||||
|
*s.DeletedAt = value.Time
|
||||||
|
}
|
||||||
|
case sku.FieldName:
|
||||||
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field name", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Name = value.String
|
||||||
|
}
|
||||||
|
case sku.FieldType:
|
||||||
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field type", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Type = sku.Type(value.String)
|
||||||
|
}
|
||||||
|
case sku.FieldAmount:
|
||||||
|
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field amount", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Amount = value.Int64
|
||||||
|
}
|
||||||
|
case sku.FieldDuration:
|
||||||
|
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field duration", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Duration = value.Int64
|
||||||
|
}
|
||||||
|
case sku.FieldPrice:
|
||||||
|
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field price", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Price = value.Int64
|
||||||
|
}
|
||||||
|
case sku.FieldPoints:
|
||||||
|
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field points", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Points = new(int64)
|
||||||
|
*s.Points = value.Int64
|
||||||
|
}
|
||||||
|
case sku.FieldLabel:
|
||||||
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field label", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Label = value.String
|
||||||
|
}
|
||||||
|
case sku.FieldDes:
|
||||||
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field des", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Des = value.String
|
||||||
|
}
|
||||||
|
case sku.FieldEnabled:
|
||||||
|
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field enabled", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Enabled = value.Bool
|
||||||
|
}
|
||||||
|
case sku.FieldWeight:
|
||||||
|
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field weight", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
s.Weight = int(value.Int64)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
s.selectValues.Set(columns[i], values[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns the ent.Value that was dynamically selected and assigned to the Sku.
|
||||||
|
// This includes values selected through modifiers, order, etc.
|
||||||
|
func (s *Sku) Value(name string) (ent.Value, error) {
|
||||||
|
return s.selectValues.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update returns a builder for updating this Sku.
|
||||||
|
// Note that you need to call Sku.Unwrap() before calling this method if this Sku
|
||||||
|
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||||
|
func (s *Sku) Update() *SkuUpdateOne {
|
||||||
|
return NewSkuClient(s.config).UpdateOne(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps the Sku entity that was returned from a transaction after it was closed,
|
||||||
|
// so that all future queries will be executed through the driver which created the transaction.
|
||||||
|
func (s *Sku) Unwrap() *Sku {
|
||||||
|
_tx, ok := s.config.driver.(*txDriver)
|
||||||
|
if !ok {
|
||||||
|
panic("ent: Sku is not a transactional entity")
|
||||||
|
}
|
||||||
|
s.config.driver = _tx.drv
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements the fmt.Stringer.
|
||||||
|
func (s *Sku) String() string {
|
||||||
|
var builder strings.Builder
|
||||||
|
builder.WriteString("Sku(")
|
||||||
|
builder.WriteString(fmt.Sprintf("id=%v, ", s.ID))
|
||||||
|
builder.WriteString("created_at=")
|
||||||
|
builder.WriteString(s.CreatedAt.Format(time.ANSIC))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("updated_at=")
|
||||||
|
builder.WriteString(s.UpdatedAt.Format(time.ANSIC))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
if v := s.DeletedAt; v != nil {
|
||||||
|
builder.WriteString("deleted_at=")
|
||||||
|
builder.WriteString(v.Format(time.ANSIC))
|
||||||
|
}
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("name=")
|
||||||
|
builder.WriteString(s.Name)
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("type=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", s.Type))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("amount=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", s.Amount))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("duration=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", s.Duration))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("price=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", s.Price))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
if v := s.Points; v != nil {
|
||||||
|
builder.WriteString("points=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||||
|
}
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("label=")
|
||||||
|
builder.WriteString(s.Label)
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("des=")
|
||||||
|
builder.WriteString(s.Des)
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("enabled=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", s.Enabled))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("weight=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", s.Weight))
|
||||||
|
builder.WriteByte(')')
|
||||||
|
return builder.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skus is a parsable slice of Sku.
|
||||||
|
type Skus []*Sku
|
||||||
@ -0,0 +1,190 @@
|
|||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package sku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Label holds the string label denoting the sku type in the database.
|
||||||
|
Label = "sku"
|
||||||
|
// FieldID holds the string denoting the id field in the database.
|
||||||
|
FieldID = "id"
|
||||||
|
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||||
|
FieldCreatedAt = "created_at"
|
||||||
|
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
|
||||||
|
FieldUpdatedAt = "updated_at"
|
||||||
|
// FieldDeletedAt holds the string denoting the deleted_at field in the database.
|
||||||
|
FieldDeletedAt = "deleted_at"
|
||||||
|
// FieldName holds the string denoting the name field in the database.
|
||||||
|
FieldName = "name"
|
||||||
|
// FieldType holds the string denoting the type field in the database.
|
||||||
|
FieldType = "type"
|
||||||
|
// FieldAmount holds the string denoting the amount field in the database.
|
||||||
|
FieldAmount = "amount"
|
||||||
|
// FieldDuration holds the string denoting the duration field in the database.
|
||||||
|
FieldDuration = "duration"
|
||||||
|
// FieldPrice holds the string denoting the price field in the database.
|
||||||
|
FieldPrice = "price"
|
||||||
|
// FieldPoints holds the string denoting the points field in the database.
|
||||||
|
FieldPoints = "points"
|
||||||
|
// FieldLabel holds the string denoting the label field in the database.
|
||||||
|
FieldLabel = "label"
|
||||||
|
// FieldDes holds the string denoting the des field in the database.
|
||||||
|
FieldDes = "des"
|
||||||
|
// FieldEnabled holds the string denoting the enabled field in the database.
|
||||||
|
FieldEnabled = "enabled"
|
||||||
|
// FieldWeight holds the string denoting the weight field in the database.
|
||||||
|
FieldWeight = "weight"
|
||||||
|
// Table holds the table name of the sku in the database.
|
||||||
|
Table = "skus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Columns holds all SQL columns for sku fields.
|
||||||
|
var Columns = []string{
|
||||||
|
FieldID,
|
||||||
|
FieldCreatedAt,
|
||||||
|
FieldUpdatedAt,
|
||||||
|
FieldDeletedAt,
|
||||||
|
FieldName,
|
||||||
|
FieldType,
|
||||||
|
FieldAmount,
|
||||||
|
FieldDuration,
|
||||||
|
FieldPrice,
|
||||||
|
FieldPoints,
|
||||||
|
FieldLabel,
|
||||||
|
FieldDes,
|
||||||
|
FieldEnabled,
|
||||||
|
FieldWeight,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||||
|
func ValidColumn(column string) bool {
|
||||||
|
for i := range Columns {
|
||||||
|
if column == Columns[i] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that the variables below are initialized by the runtime
|
||||||
|
// package on the initialization of the application. Therefore,
|
||||||
|
// it should be imported in the main as follows:
|
||||||
|
//
|
||||||
|
// import _ "github.com/cloudreve/Cloudreve/v4/ent/runtime"
|
||||||
|
var (
|
||||||
|
Hooks [1]ent.Hook
|
||||||
|
Interceptors [1]ent.Interceptor
|
||||||
|
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||||
|
DefaultCreatedAt func() time.Time
|
||||||
|
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
|
||||||
|
DefaultUpdatedAt func() time.Time
|
||||||
|
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
||||||
|
UpdateDefaultUpdatedAt func() time.Time
|
||||||
|
// DefaultEnabled holds the default value on creation for the "enabled" field.
|
||||||
|
DefaultEnabled bool
|
||||||
|
// DefaultWeight holds the default value on creation for the "weight" field.
|
||||||
|
DefaultWeight int
|
||||||
|
)
|
||||||
|
|
||||||
|
// Type defines the type for the "type" enum field.
|
||||||
|
type Type string
|
||||||
|
|
||||||
|
// Type values.
|
||||||
|
const (
|
||||||
|
TypeStorage Type = "storage"
|
||||||
|
TypeGroup Type = "group"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (_type Type) String() string {
|
||||||
|
return string(_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeValidator is a validator for the "type" field enum values. It is called by the builders before save.
|
||||||
|
func TypeValidator(_type Type) error {
|
||||||
|
switch _type {
|
||||||
|
case TypeStorage, TypeGroup:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("sku: invalid enum value for type field: %q", _type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrderOption defines the ordering options for the Sku queries.
|
||||||
|
type OrderOption func(*sql.Selector)
|
||||||
|
|
||||||
|
// ByID orders the results by the id field.
|
||||||
|
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByCreatedAt orders the results by the created_at field.
|
||||||
|
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUpdatedAt orders the results by the updated_at field.
|
||||||
|
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByDeletedAt orders the results by the deleted_at field.
|
||||||
|
func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByName orders the results by the name field.
|
||||||
|
func ByName(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldName, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByType orders the results by the type field.
|
||||||
|
func ByType(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldType, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByAmount orders the results by the amount field.
|
||||||
|
func ByAmount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldAmount, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByDuration orders the results by the duration field.
|
||||||
|
func ByDuration(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldDuration, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByPrice orders the results by the price field.
|
||||||
|
func ByPrice(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldPrice, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByPoints orders the results by the points field.
|
||||||
|
func ByPoints(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldPoints, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByLabel orders the results by the label field.
|
||||||
|
func ByLabel(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldLabel, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByDes orders the results by the des field.
|
||||||
|
func ByDes(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldDes, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByEnabled orders the results by the enabled field.
|
||||||
|
func ByEnabled(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldEnabled, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByWeight orders the results by the weight field.
|
||||||
|
func ByWeight(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldWeight, opts...).ToFunc()
|
||||||
|
}
|
||||||
@ -0,0 +1,730 @@
|
|||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package sku
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ID filters vertices based on their ID field.
|
||||||
|
func ID(id int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDEQ applies the EQ predicate on the ID field.
|
||||||
|
func IDEQ(id int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDNEQ applies the NEQ predicate on the ID field.
|
||||||
|
func IDNEQ(id int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDIn applies the In predicate on the ID field.
|
||||||
|
func IDIn(ids ...int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldID, ids...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDNotIn applies the NotIn predicate on the ID field.
|
||||||
|
func IDNotIn(ids ...int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldID, ids...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDGT applies the GT predicate on the ID field.
|
||||||
|
func IDGT(id int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDGTE applies the GTE predicate on the ID field.
|
||||||
|
func IDGTE(id int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDLT applies the LT predicate on the ID field.
|
||||||
|
func IDLT(id int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDLTE applies the LTE predicate on the ID field.
|
||||||
|
func IDLTE(id int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||||
|
func CreatedAt(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
|
||||||
|
func UpdatedAt(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
|
||||||
|
func DeletedAt(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldDeletedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
|
||||||
|
func Name(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Amount applies equality check predicate on the "amount" field. It's identical to AmountEQ.
|
||||||
|
func Amount(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldAmount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duration applies equality check predicate on the "duration" field. It's identical to DurationEQ.
|
||||||
|
func Duration(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldDuration, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Price applies equality check predicate on the "price" field. It's identical to PriceEQ.
|
||||||
|
func Price(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldPrice, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Points applies equality check predicate on the "points" field. It's identical to PointsEQ.
|
||||||
|
func Points(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldPoints, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Des applies equality check predicate on the "des" field. It's identical to DesEQ.
|
||||||
|
func Des(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enabled applies equality check predicate on the "enabled" field. It's identical to EnabledEQ.
|
||||||
|
func Enabled(v bool) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldEnabled, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Weight applies equality check predicate on the "weight" field. It's identical to WeightEQ.
|
||||||
|
func Weight(v int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldWeight, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||||
|
func CreatedAtEQ(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||||
|
func CreatedAtNEQ(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||||
|
func CreatedAtIn(vs ...time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldCreatedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||||
|
func CreatedAtNotIn(vs ...time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||||
|
func CreatedAtGT(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||||
|
func CreatedAtGTE(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||||
|
func CreatedAtLT(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||||
|
func CreatedAtLTE(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtEQ(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtNEQ(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtIn(vs ...time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtNotIn(vs ...time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtGT(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtGTE(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtLT(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtLTE(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtEQ(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldDeletedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtNEQ(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldDeletedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtIn applies the In predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtIn(vs ...time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldDeletedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtNotIn(vs ...time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldDeletedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtGT applies the GT predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtGT(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldDeletedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtGTE(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldDeletedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtLT applies the LT predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtLT(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldDeletedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtLTE(v time.Time) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldDeletedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtIsNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIsNull(FieldDeletedAt))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
|
||||||
|
func DeletedAtNotNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotNull(FieldDeletedAt))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameEQ applies the EQ predicate on the "name" field.
|
||||||
|
func NameEQ(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameNEQ applies the NEQ predicate on the "name" field.
|
||||||
|
func NameNEQ(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameIn applies the In predicate on the "name" field.
|
||||||
|
func NameIn(vs ...string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldName, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameNotIn applies the NotIn predicate on the "name" field.
|
||||||
|
func NameNotIn(vs ...string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldName, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameGT applies the GT predicate on the "name" field.
|
||||||
|
func NameGT(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameGTE applies the GTE predicate on the "name" field.
|
||||||
|
func NameGTE(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameLT applies the LT predicate on the "name" field.
|
||||||
|
func NameLT(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameLTE applies the LTE predicate on the "name" field.
|
||||||
|
func NameLTE(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameContains applies the Contains predicate on the "name" field.
|
||||||
|
func NameContains(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldContains(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
|
||||||
|
func NameHasPrefix(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldHasPrefix(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
|
||||||
|
func NameHasSuffix(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldHasSuffix(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameEqualFold applies the EqualFold predicate on the "name" field.
|
||||||
|
func NameEqualFold(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEqualFold(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameContainsFold applies the ContainsFold predicate on the "name" field.
|
||||||
|
func NameContainsFold(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldContainsFold(FieldName, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeEQ applies the EQ predicate on the "type" field.
|
||||||
|
func TypeEQ(v Type) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeNEQ applies the NEQ predicate on the "type" field.
|
||||||
|
func TypeNEQ(v Type) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeIn applies the In predicate on the "type" field.
|
||||||
|
func TypeIn(vs ...Type) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldType, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeNotIn applies the NotIn predicate on the "type" field.
|
||||||
|
func TypeNotIn(vs ...Type) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldType, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AmountEQ applies the EQ predicate on the "amount" field.
|
||||||
|
func AmountEQ(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldAmount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AmountNEQ applies the NEQ predicate on the "amount" field.
|
||||||
|
func AmountNEQ(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldAmount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AmountIn applies the In predicate on the "amount" field.
|
||||||
|
func AmountIn(vs ...int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldAmount, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AmountNotIn applies the NotIn predicate on the "amount" field.
|
||||||
|
func AmountNotIn(vs ...int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldAmount, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AmountGT applies the GT predicate on the "amount" field.
|
||||||
|
func AmountGT(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldAmount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AmountGTE applies the GTE predicate on the "amount" field.
|
||||||
|
func AmountGTE(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldAmount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AmountLT applies the LT predicate on the "amount" field.
|
||||||
|
func AmountLT(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldAmount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AmountLTE applies the LTE predicate on the "amount" field.
|
||||||
|
func AmountLTE(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldAmount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationEQ applies the EQ predicate on the "duration" field.
|
||||||
|
func DurationEQ(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldDuration, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationNEQ applies the NEQ predicate on the "duration" field.
|
||||||
|
func DurationNEQ(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldDuration, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationIn applies the In predicate on the "duration" field.
|
||||||
|
func DurationIn(vs ...int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldDuration, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationNotIn applies the NotIn predicate on the "duration" field.
|
||||||
|
func DurationNotIn(vs ...int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldDuration, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationGT applies the GT predicate on the "duration" field.
|
||||||
|
func DurationGT(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldDuration, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationGTE applies the GTE predicate on the "duration" field.
|
||||||
|
func DurationGTE(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldDuration, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationLT applies the LT predicate on the "duration" field.
|
||||||
|
func DurationLT(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldDuration, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationLTE applies the LTE predicate on the "duration" field.
|
||||||
|
func DurationLTE(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldDuration, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationIsNil applies the IsNil predicate on the "duration" field.
|
||||||
|
func DurationIsNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIsNull(FieldDuration))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationNotNil applies the NotNil predicate on the "duration" field.
|
||||||
|
func DurationNotNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotNull(FieldDuration))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceEQ applies the EQ predicate on the "price" field.
|
||||||
|
func PriceEQ(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldPrice, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceNEQ applies the NEQ predicate on the "price" field.
|
||||||
|
func PriceNEQ(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldPrice, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceIn applies the In predicate on the "price" field.
|
||||||
|
func PriceIn(vs ...int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldPrice, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceNotIn applies the NotIn predicate on the "price" field.
|
||||||
|
func PriceNotIn(vs ...int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldPrice, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceGT applies the GT predicate on the "price" field.
|
||||||
|
func PriceGT(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldPrice, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceGTE applies the GTE predicate on the "price" field.
|
||||||
|
func PriceGTE(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldPrice, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceLT applies the LT predicate on the "price" field.
|
||||||
|
func PriceLT(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldPrice, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceLTE applies the LTE predicate on the "price" field.
|
||||||
|
func PriceLTE(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldPrice, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceIsNil applies the IsNil predicate on the "price" field.
|
||||||
|
func PriceIsNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIsNull(FieldPrice))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceNotNil applies the NotNil predicate on the "price" field.
|
||||||
|
func PriceNotNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotNull(FieldPrice))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsEQ applies the EQ predicate on the "points" field.
|
||||||
|
func PointsEQ(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldPoints, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsNEQ applies the NEQ predicate on the "points" field.
|
||||||
|
func PointsNEQ(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldPoints, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsIn applies the In predicate on the "points" field.
|
||||||
|
func PointsIn(vs ...int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldPoints, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsNotIn applies the NotIn predicate on the "points" field.
|
||||||
|
func PointsNotIn(vs ...int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldPoints, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsGT applies the GT predicate on the "points" field.
|
||||||
|
func PointsGT(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldPoints, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsGTE applies the GTE predicate on the "points" field.
|
||||||
|
func PointsGTE(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldPoints, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsLT applies the LT predicate on the "points" field.
|
||||||
|
func PointsLT(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldPoints, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsLTE applies the LTE predicate on the "points" field.
|
||||||
|
func PointsLTE(v int64) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldPoints, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsIsNil applies the IsNil predicate on the "points" field.
|
||||||
|
func PointsIsNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIsNull(FieldPoints))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointsNotNil applies the NotNil predicate on the "points" field.
|
||||||
|
func PointsNotNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotNull(FieldPoints))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelEQ applies the EQ predicate on the "label" field.
|
||||||
|
func LabelEQ(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelNEQ applies the NEQ predicate on the "label" field.
|
||||||
|
func LabelNEQ(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelIn applies the In predicate on the "label" field.
|
||||||
|
func LabelIn(vs ...string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldLabel, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelNotIn applies the NotIn predicate on the "label" field.
|
||||||
|
func LabelNotIn(vs ...string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldLabel, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelGT applies the GT predicate on the "label" field.
|
||||||
|
func LabelGT(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelGTE applies the GTE predicate on the "label" field.
|
||||||
|
func LabelGTE(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelLT applies the LT predicate on the "label" field.
|
||||||
|
func LabelLT(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelLTE applies the LTE predicate on the "label" field.
|
||||||
|
func LabelLTE(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelContains applies the Contains predicate on the "label" field.
|
||||||
|
func LabelContains(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldContains(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelHasPrefix applies the HasPrefix predicate on the "label" field.
|
||||||
|
func LabelHasPrefix(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldHasPrefix(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelHasSuffix applies the HasSuffix predicate on the "label" field.
|
||||||
|
func LabelHasSuffix(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldHasSuffix(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelIsNil applies the IsNil predicate on the "label" field.
|
||||||
|
func LabelIsNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIsNull(FieldLabel))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelNotNil applies the NotNil predicate on the "label" field.
|
||||||
|
func LabelNotNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotNull(FieldLabel))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelEqualFold applies the EqualFold predicate on the "label" field.
|
||||||
|
func LabelEqualFold(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEqualFold(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelContainsFold applies the ContainsFold predicate on the "label" field.
|
||||||
|
func LabelContainsFold(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldContainsFold(FieldLabel, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesEQ applies the EQ predicate on the "des" field.
|
||||||
|
func DesEQ(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesNEQ applies the NEQ predicate on the "des" field.
|
||||||
|
func DesNEQ(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesIn applies the In predicate on the "des" field.
|
||||||
|
func DesIn(vs ...string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldDes, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesNotIn applies the NotIn predicate on the "des" field.
|
||||||
|
func DesNotIn(vs ...string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldDes, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesGT applies the GT predicate on the "des" field.
|
||||||
|
func DesGT(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesGTE applies the GTE predicate on the "des" field.
|
||||||
|
func DesGTE(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesLT applies the LT predicate on the "des" field.
|
||||||
|
func DesLT(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesLTE applies the LTE predicate on the "des" field.
|
||||||
|
func DesLTE(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesContains applies the Contains predicate on the "des" field.
|
||||||
|
func DesContains(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldContains(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesHasPrefix applies the HasPrefix predicate on the "des" field.
|
||||||
|
func DesHasPrefix(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldHasPrefix(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesHasSuffix applies the HasSuffix predicate on the "des" field.
|
||||||
|
func DesHasSuffix(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldHasSuffix(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesIsNil applies the IsNil predicate on the "des" field.
|
||||||
|
func DesIsNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIsNull(FieldDes))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesNotNil applies the NotNil predicate on the "des" field.
|
||||||
|
func DesNotNil() predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotNull(FieldDes))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesEqualFold applies the EqualFold predicate on the "des" field.
|
||||||
|
func DesEqualFold(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEqualFold(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DesContainsFold applies the ContainsFold predicate on the "des" field.
|
||||||
|
func DesContainsFold(v string) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldContainsFold(FieldDes, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnabledEQ applies the EQ predicate on the "enabled" field.
|
||||||
|
func EnabledEQ(v bool) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldEnabled, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnabledNEQ applies the NEQ predicate on the "enabled" field.
|
||||||
|
func EnabledNEQ(v bool) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldEnabled, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeightEQ applies the EQ predicate on the "weight" field.
|
||||||
|
func WeightEQ(v int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldEQ(FieldWeight, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeightNEQ applies the NEQ predicate on the "weight" field.
|
||||||
|
func WeightNEQ(v int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNEQ(FieldWeight, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeightIn applies the In predicate on the "weight" field.
|
||||||
|
func WeightIn(vs ...int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldIn(FieldWeight, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeightNotIn applies the NotIn predicate on the "weight" field.
|
||||||
|
func WeightNotIn(vs ...int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldNotIn(FieldWeight, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeightGT applies the GT predicate on the "weight" field.
|
||||||
|
func WeightGT(v int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGT(FieldWeight, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeightGTE applies the GTE predicate on the "weight" field.
|
||||||
|
func WeightGTE(v int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldGTE(FieldWeight, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeightLT applies the LT predicate on the "weight" field.
|
||||||
|
func WeightLT(v int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLT(FieldWeight, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeightLTE applies the LTE predicate on the "weight" field.
|
||||||
|
func WeightLTE(v int) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.FieldLTE(FieldWeight, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// And groups predicates with the AND operator between them.
|
||||||
|
func And(predicates ...predicate.Sku) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.AndPredicates(predicates...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or groups predicates with the OR operator between them.
|
||||||
|
func Or(predicates ...predicate.Sku) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.OrPredicates(predicates...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not applies the not operator on the given predicate.
|
||||||
|
func Not(p predicate.Sku) predicate.Sku {
|
||||||
|
return predicate.Sku(sql.NotPredicates(p))
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,88 @@
|
|||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"entgo.io/ent/schema/field"
|
||||||
|
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||||
|
"github.com/cloudreve/Cloudreve/v4/ent/sku"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SkuDelete is the builder for deleting a Sku entity.
|
||||||
|
type SkuDelete struct {
|
||||||
|
config
|
||||||
|
hooks []Hook
|
||||||
|
mutation *SkuMutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where appends a list predicates to the SkuDelete builder.
|
||||||
|
func (sd *SkuDelete) Where(ps ...predicate.Sku) *SkuDelete {
|
||||||
|
sd.mutation.Where(ps...)
|
||||||
|
return sd
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||||
|
func (sd *SkuDelete) Exec(ctx context.Context) (int, error) {
|
||||||
|
return withHooks(ctx, sd.sqlExec, sd.mutation, sd.hooks)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (sd *SkuDelete) ExecX(ctx context.Context) int {
|
||||||
|
n, err := sd.Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sd *SkuDelete) sqlExec(ctx context.Context) (int, error) {
|
||||||
|
_spec := sqlgraph.NewDeleteSpec(sku.Table, sqlgraph.NewFieldSpec(sku.FieldID, field.TypeInt))
|
||||||
|
if ps := sd.mutation.predicates; len(ps) > 0 {
|
||||||
|
_spec.Predicate = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
affected, err := sqlgraph.DeleteNodes(ctx, sd.driver, _spec)
|
||||||
|
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||||
|
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||||
|
}
|
||||||
|
sd.mutation.done = true
|
||||||
|
return affected, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SkuDeleteOne is the builder for deleting a single Sku entity.
|
||||||
|
type SkuDeleteOne struct {
|
||||||
|
sd *SkuDelete
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where appends a list predicates to the SkuDelete builder.
|
||||||
|
func (sdo *SkuDeleteOne) Where(ps ...predicate.Sku) *SkuDeleteOne {
|
||||||
|
sdo.sd.mutation.Where(ps...)
|
||||||
|
return sdo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the deletion query.
|
||||||
|
func (sdo *SkuDeleteOne) Exec(ctx context.Context) error {
|
||||||
|
n, err := sdo.sd.Exec(ctx)
|
||||||
|
switch {
|
||||||
|
case err != nil:
|
||||||
|
return err
|
||||||
|
case n == 0:
|
||||||
|
return &NotFoundError{sku.Label}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (sdo *SkuDeleteOne) ExecX(ctx context.Context) {
|
||||||
|
if err := sdo.Exec(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,526 @@
|
|||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"entgo.io/ent/schema/field"
|
||||||
|
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||||
|
"github.com/cloudreve/Cloudreve/v4/ent/sku"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SkuQuery is the builder for querying Sku entities.
|
||||||
|
type SkuQuery struct {
|
||||||
|
config
|
||||||
|
ctx *QueryContext
|
||||||
|
order []sku.OrderOption
|
||||||
|
inters []Interceptor
|
||||||
|
predicates []predicate.Sku
|
||||||
|
// intermediate query (i.e. traversal path).
|
||||||
|
sql *sql.Selector
|
||||||
|
path func(context.Context) (*sql.Selector, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where adds a new predicate for the SkuQuery builder.
|
||||||
|
func (sq *SkuQuery) Where(ps ...predicate.Sku) *SkuQuery {
|
||||||
|
sq.predicates = append(sq.predicates, ps...)
|
||||||
|
return sq
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit the number of records to be returned by this query.
|
||||||
|
func (sq *SkuQuery) Limit(limit int) *SkuQuery {
|
||||||
|
sq.ctx.Limit = &limit
|
||||||
|
return sq
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset to start from.
|
||||||
|
func (sq *SkuQuery) Offset(offset int) *SkuQuery {
|
||||||
|
sq.ctx.Offset = &offset
|
||||||
|
return sq
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unique configures the query builder to filter duplicate records on query.
|
||||||
|
// By default, unique is set to true, and can be disabled using this method.
|
||||||
|
func (sq *SkuQuery) Unique(unique bool) *SkuQuery {
|
||||||
|
sq.ctx.Unique = &unique
|
||||||
|
return sq
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order specifies how the records should be ordered.
|
||||||
|
func (sq *SkuQuery) Order(o ...sku.OrderOption) *SkuQuery {
|
||||||
|
sq.order = append(sq.order, o...)
|
||||||
|
return sq
|
||||||
|
}
|
||||||
|
|
||||||
|
// First returns the first Sku entity from the query.
|
||||||
|
// Returns a *NotFoundError when no Sku was found.
|
||||||
|
func (sq *SkuQuery) First(ctx context.Context) (*Sku, error) {
|
||||||
|
nodes, err := sq.Limit(1).All(setContextOp(ctx, sq.ctx, "First"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(nodes) == 0 {
|
||||||
|
return nil, &NotFoundError{sku.Label}
|
||||||
|
}
|
||||||
|
return nodes[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstX is like First, but panics if an error occurs.
|
||||||
|
func (sq *SkuQuery) FirstX(ctx context.Context) *Sku {
|
||||||
|
node, err := sq.First(ctx)
|
||||||
|
if err != nil && !IsNotFound(err) {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstID returns the first Sku ID from the query.
|
||||||
|
// Returns a *NotFoundError when no Sku ID was found.
|
||||||
|
func (sq *SkuQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||||
|
var ids []int
|
||||||
|
if ids, err = sq.Limit(1).IDs(setContextOp(ctx, sq.ctx, "FirstID")); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(ids) == 0 {
|
||||||
|
err = &NotFoundError{sku.Label}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return ids[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||||
|
func (sq *SkuQuery) FirstIDX(ctx context.Context) int {
|
||||||
|
id, err := sq.FirstID(ctx)
|
||||||
|
if err != nil && !IsNotFound(err) {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only returns a single Sku entity found by the query, ensuring it only returns one.
|
||||||
|
// Returns a *NotSingularError when more than one Sku entity is found.
|
||||||
|
// Returns a *NotFoundError when no Sku entities are found.
|
||||||
|
func (sq *SkuQuery) Only(ctx context.Context) (*Sku, error) {
|
||||||
|
nodes, err := sq.Limit(2).All(setContextOp(ctx, sq.ctx, "Only"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch len(nodes) {
|
||||||
|
case 1:
|
||||||
|
return nodes[0], nil
|
||||||
|
case 0:
|
||||||
|
return nil, &NotFoundError{sku.Label}
|
||||||
|
default:
|
||||||
|
return nil, &NotSingularError{sku.Label}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlyX is like Only, but panics if an error occurs.
|
||||||
|
func (sq *SkuQuery) OnlyX(ctx context.Context) *Sku {
|
||||||
|
node, err := sq.Only(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlyID is like Only, but returns the only Sku ID in the query.
|
||||||
|
// Returns a *NotSingularError when more than one Sku ID is found.
|
||||||
|
// Returns a *NotFoundError when no entities are found.
|
||||||
|
func (sq *SkuQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||||
|
var ids []int
|
||||||
|
if ids, err = sq.Limit(2).IDs(setContextOp(ctx, sq.ctx, "OnlyID")); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch len(ids) {
|
||||||
|
case 1:
|
||||||
|
id = ids[0]
|
||||||
|
case 0:
|
||||||
|
err = &NotFoundError{sku.Label}
|
||||||
|
default:
|
||||||
|
err = &NotSingularError{sku.Label}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||||
|
func (sq *SkuQuery) OnlyIDX(ctx context.Context) int {
|
||||||
|
id, err := sq.OnlyID(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
// All executes the query and returns a list of Skus.
|
||||||
|
func (sq *SkuQuery) All(ctx context.Context) ([]*Sku, error) {
|
||||||
|
ctx = setContextOp(ctx, sq.ctx, "All")
|
||||||
|
if err := sq.prepareQuery(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
qr := querierAll[[]*Sku, *SkuQuery]()
|
||||||
|
return withInterceptors[[]*Sku](ctx, sq, qr, sq.inters)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllX is like All, but panics if an error occurs.
|
||||||
|
func (sq *SkuQuery) AllX(ctx context.Context) []*Sku {
|
||||||
|
nodes, err := sq.All(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDs executes the query and returns a list of Sku IDs.
|
||||||
|
func (sq *SkuQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||||
|
if sq.ctx.Unique == nil && sq.path != nil {
|
||||||
|
sq.Unique(true)
|
||||||
|
}
|
||||||
|
ctx = setContextOp(ctx, sq.ctx, "IDs")
|
||||||
|
if err = sq.Select(sku.FieldID).Scan(ctx, &ids); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ids, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDsX is like IDs, but panics if an error occurs.
|
||||||
|
func (sq *SkuQuery) IDsX(ctx context.Context) []int {
|
||||||
|
ids, err := sq.IDs(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count returns the count of the given query.
|
||||||
|
func (sq *SkuQuery) Count(ctx context.Context) (int, error) {
|
||||||
|
ctx = setContextOp(ctx, sq.ctx, "Count")
|
||||||
|
if err := sq.prepareQuery(ctx); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return withInterceptors[int](ctx, sq, querierCount[*SkuQuery](), sq.inters)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountX is like Count, but panics if an error occurs.
|
||||||
|
func (sq *SkuQuery) CountX(ctx context.Context) int {
|
||||||
|
count, err := sq.Count(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exist returns true if the query has elements in the graph.
|
||||||
|
func (sq *SkuQuery) Exist(ctx context.Context) (bool, error) {
|
||||||
|
ctx = setContextOp(ctx, sq.ctx, "Exist")
|
||||||
|
switch _, err := sq.FirstID(ctx); {
|
||||||
|
case IsNotFound(err):
|
||||||
|
return false, nil
|
||||||
|
case err != nil:
|
||||||
|
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||||
|
default:
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExistX is like Exist, but panics if an error occurs.
|
||||||
|
func (sq *SkuQuery) ExistX(ctx context.Context) bool {
|
||||||
|
exist, err := sq.Exist(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return exist
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns a duplicate of the SkuQuery builder, including all associated steps. It can be
|
||||||
|
// used to prepare common query builders and use them differently after the clone is made.
|
||||||
|
func (sq *SkuQuery) Clone() *SkuQuery {
|
||||||
|
if sq == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &SkuQuery{
|
||||||
|
config: sq.config,
|
||||||
|
ctx: sq.ctx.Clone(),
|
||||||
|
order: append([]sku.OrderOption{}, sq.order...),
|
||||||
|
inters: append([]Interceptor{}, sq.inters...),
|
||||||
|
predicates: append([]predicate.Sku{}, sq.predicates...),
|
||||||
|
// clone intermediate query.
|
||||||
|
sql: sq.sql.Clone(),
|
||||||
|
path: sq.path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GroupBy is used to group vertices by one or more fields/columns.
|
||||||
|
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var v []struct {
|
||||||
|
// CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
|
// Count int `json:"count,omitempty"`
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// client.Sku.Query().
|
||||||
|
// GroupBy(sku.FieldCreatedAt).
|
||||||
|
// Aggregate(ent.Count()).
|
||||||
|
// Scan(ctx, &v)
|
||||||
|
func (sq *SkuQuery) GroupBy(field string, fields ...string) *SkuGroupBy {
|
||||||
|
sq.ctx.Fields = append([]string{field}, fields...)
|
||||||
|
grbuild := &SkuGroupBy{build: sq}
|
||||||
|
grbuild.flds = &sq.ctx.Fields
|
||||||
|
grbuild.label = sku.Label
|
||||||
|
grbuild.scan = grbuild.Scan
|
||||||
|
return grbuild
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select allows the selection one or more fields/columns for the given query,
|
||||||
|
// instead of selecting all fields in the entity.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var v []struct {
|
||||||
|
// CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// client.Sku.Query().
|
||||||
|
// Select(sku.FieldCreatedAt).
|
||||||
|
// Scan(ctx, &v)
|
||||||
|
func (sq *SkuQuery) Select(fields ...string) *SkuSelect {
|
||||||
|
sq.ctx.Fields = append(sq.ctx.Fields, fields...)
|
||||||
|
sbuild := &SkuSelect{SkuQuery: sq}
|
||||||
|
sbuild.label = sku.Label
|
||||||
|
sbuild.flds, sbuild.scan = &sq.ctx.Fields, sbuild.Scan
|
||||||
|
return sbuild
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregate returns a SkuSelect configured with the given aggregations.
|
||||||
|
func (sq *SkuQuery) Aggregate(fns ...AggregateFunc) *SkuSelect {
|
||||||
|
return sq.Select().Aggregate(fns...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *SkuQuery) prepareQuery(ctx context.Context) error {
|
||||||
|
for _, inter := range sq.inters {
|
||||||
|
if inter == nil {
|
||||||
|
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||||
|
}
|
||||||
|
if trv, ok := inter.(Traverser); ok {
|
||||||
|
if err := trv.Traverse(ctx, sq); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, f := range sq.ctx.Fields {
|
||||||
|
if !sku.ValidColumn(f) {
|
||||||
|
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sq.path != nil {
|
||||||
|
prev, err := sq.path(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sq.sql = prev
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *SkuQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Sku, error) {
|
||||||
|
var (
|
||||||
|
nodes = []*Sku{}
|
||||||
|
_spec = sq.querySpec()
|
||||||
|
)
|
||||||
|
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||||
|
return (*Sku).scanValues(nil, columns)
|
||||||
|
}
|
||||||
|
_spec.Assign = func(columns []string, values []any) error {
|
||||||
|
node := &Sku{config: sq.config}
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
return node.assignValues(columns, values)
|
||||||
|
}
|
||||||
|
for i := range hooks {
|
||||||
|
hooks[i](ctx, _spec)
|
||||||
|
}
|
||||||
|
if err := sqlgraph.QueryNodes(ctx, sq.driver, _spec); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(nodes) == 0 {
|
||||||
|
return nodes, nil
|
||||||
|
}
|
||||||
|
return nodes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *SkuQuery) sqlCount(ctx context.Context) (int, error) {
|
||||||
|
_spec := sq.querySpec()
|
||||||
|
_spec.Node.Columns = sq.ctx.Fields
|
||||||
|
if len(sq.ctx.Fields) > 0 {
|
||||||
|
_spec.Unique = sq.ctx.Unique != nil && *sq.ctx.Unique
|
||||||
|
}
|
||||||
|
return sqlgraph.CountNodes(ctx, sq.driver, _spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *SkuQuery) querySpec() *sqlgraph.QuerySpec {
|
||||||
|
_spec := sqlgraph.NewQuerySpec(sku.Table, sku.Columns, sqlgraph.NewFieldSpec(sku.FieldID, field.TypeInt))
|
||||||
|
_spec.From = sq.sql
|
||||||
|
if unique := sq.ctx.Unique; unique != nil {
|
||||||
|
_spec.Unique = *unique
|
||||||
|
} else if sq.path != nil {
|
||||||
|
_spec.Unique = true
|
||||||
|
}
|
||||||
|
if fields := sq.ctx.Fields; len(fields) > 0 {
|
||||||
|
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||||
|
_spec.Node.Columns = append(_spec.Node.Columns, sku.FieldID)
|
||||||
|
for i := range fields {
|
||||||
|
if fields[i] != sku.FieldID {
|
||||||
|
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ps := sq.predicates; len(ps) > 0 {
|
||||||
|
_spec.Predicate = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if limit := sq.ctx.Limit; limit != nil {
|
||||||
|
_spec.Limit = *limit
|
||||||
|
}
|
||||||
|
if offset := sq.ctx.Offset; offset != nil {
|
||||||
|
_spec.Offset = *offset
|
||||||
|
}
|
||||||
|
if ps := sq.order; len(ps) > 0 {
|
||||||
|
_spec.Order = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _spec
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sq *SkuQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||||
|
builder := sql.Dialect(sq.driver.Dialect())
|
||||||
|
t1 := builder.Table(sku.Table)
|
||||||
|
columns := sq.ctx.Fields
|
||||||
|
if len(columns) == 0 {
|
||||||
|
columns = sku.Columns
|
||||||
|
}
|
||||||
|
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||||
|
if sq.sql != nil {
|
||||||
|
selector = sq.sql
|
||||||
|
selector.Select(selector.Columns(columns...)...)
|
||||||
|
}
|
||||||
|
if sq.ctx.Unique != nil && *sq.ctx.Unique {
|
||||||
|
selector.Distinct()
|
||||||
|
}
|
||||||
|
for _, p := range sq.predicates {
|
||||||
|
p(selector)
|
||||||
|
}
|
||||||
|
for _, p := range sq.order {
|
||||||
|
p(selector)
|
||||||
|
}
|
||||||
|
if offset := sq.ctx.Offset; offset != nil {
|
||||||
|
// limit is mandatory for offset clause. We start
|
||||||
|
// with default value, and override it below if needed.
|
||||||
|
selector.Offset(*offset).Limit(math.MaxInt32)
|
||||||
|
}
|
||||||
|
if limit := sq.ctx.Limit; limit != nil {
|
||||||
|
selector.Limit(*limit)
|
||||||
|
}
|
||||||
|
return selector
|
||||||
|
}
|
||||||
|
|
||||||
|
// SkuGroupBy is the group-by builder for Sku entities.
|
||||||
|
type SkuGroupBy struct {
|
||||||
|
selector
|
||||||
|
build *SkuQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregate adds the given aggregation functions to the group-by query.
|
||||||
|
func (sgb *SkuGroupBy) Aggregate(fns ...AggregateFunc) *SkuGroupBy {
|
||||||
|
sgb.fns = append(sgb.fns, fns...)
|
||||||
|
return sgb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan applies the selector query and scans the result into the given value.
|
||||||
|
func (sgb *SkuGroupBy) Scan(ctx context.Context, v any) error {
|
||||||
|
ctx = setContextOp(ctx, sgb.build.ctx, "GroupBy")
|
||||||
|
if err := sgb.build.prepareQuery(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return scanWithInterceptors[*SkuQuery, *SkuGroupBy](ctx, sgb.build, sgb, sgb.build.inters, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sgb *SkuGroupBy) sqlScan(ctx context.Context, root *SkuQuery, v any) error {
|
||||||
|
selector := root.sqlQuery(ctx).Select()
|
||||||
|
aggregation := make([]string, 0, len(sgb.fns))
|
||||||
|
for _, fn := range sgb.fns {
|
||||||
|
aggregation = append(aggregation, fn(selector))
|
||||||
|
}
|
||||||
|
if len(selector.SelectedColumns()) == 0 {
|
||||||
|
columns := make([]string, 0, len(*sgb.flds)+len(sgb.fns))
|
||||||
|
for _, f := range *sgb.flds {
|
||||||
|
columns = append(columns, selector.C(f))
|
||||||
|
}
|
||||||
|
columns = append(columns, aggregation...)
|
||||||
|
selector.Select(columns...)
|
||||||
|
}
|
||||||
|
selector.GroupBy(selector.Columns(*sgb.flds...)...)
|
||||||
|
if err := selector.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows := &sql.Rows{}
|
||||||
|
query, args := selector.Query()
|
||||||
|
if err := sgb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
return sql.ScanSlice(rows, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SkuSelect is the builder for selecting fields of Sku entities.
|
||||||
|
type SkuSelect struct {
|
||||||
|
*SkuQuery
|
||||||
|
selector
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregate adds the given aggregation functions to the selector query.
|
||||||
|
func (ss *SkuSelect) Aggregate(fns ...AggregateFunc) *SkuSelect {
|
||||||
|
ss.fns = append(ss.fns, fns...)
|
||||||
|
return ss
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan applies the selector query and scans the result into the given value.
|
||||||
|
func (ss *SkuSelect) Scan(ctx context.Context, v any) error {
|
||||||
|
ctx = setContextOp(ctx, ss.ctx, "Select")
|
||||||
|
if err := ss.prepareQuery(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return scanWithInterceptors[*SkuQuery, *SkuSelect](ctx, ss.SkuQuery, ss, ss.inters, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ss *SkuSelect) sqlScan(ctx context.Context, root *SkuQuery, v any) error {
|
||||||
|
selector := root.sqlQuery(ctx)
|
||||||
|
aggregation := make([]string, 0, len(ss.fns))
|
||||||
|
for _, fn := range ss.fns {
|
||||||
|
aggregation = append(aggregation, fn(selector))
|
||||||
|
}
|
||||||
|
switch n := len(*ss.selector.flds); {
|
||||||
|
case n == 0 && len(aggregation) > 0:
|
||||||
|
selector.Select(aggregation...)
|
||||||
|
case n != 0 && len(aggregation) > 0:
|
||||||
|
selector.AppendSelect(aggregation...)
|
||||||
|
}
|
||||||
|
rows := &sql.Rows{}
|
||||||
|
query, args := selector.Query()
|
||||||
|
if err := ss.driver.Query(ctx, query, args, rows); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
return sql.ScanSlice(rows, v)
|
||||||
|
}
|
||||||
@ -0,0 +1,832 @@
|
|||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"entgo.io/ent/schema/field"
|
||||||
|
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||||
|
"github.com/cloudreve/Cloudreve/v4/ent/sku"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SkuUpdate is the builder for updating Sku entities.
|
||||||
|
type SkuUpdate struct {
|
||||||
|
config
|
||||||
|
hooks []Hook
|
||||||
|
mutation *SkuMutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where appends a list predicates to the SkuUpdate builder.
|
||||||
|
func (su *SkuUpdate) Where(ps ...predicate.Sku) *SkuUpdate {
|
||||||
|
su.mutation.Where(ps...)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUpdatedAt sets the "updated_at" field.
|
||||||
|
func (su *SkuUpdate) SetUpdatedAt(t time.Time) *SkuUpdate {
|
||||||
|
su.mutation.SetUpdatedAt(t)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDeletedAt sets the "deleted_at" field.
|
||||||
|
func (su *SkuUpdate) SetDeletedAt(t time.Time) *SkuUpdate {
|
||||||
|
su.mutation.SetDeletedAt(t)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillableDeletedAt(t *time.Time) *SkuUpdate {
|
||||||
|
if t != nil {
|
||||||
|
su.SetDeletedAt(*t)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||||
|
func (su *SkuUpdate) ClearDeletedAt() *SkuUpdate {
|
||||||
|
su.mutation.ClearDeletedAt()
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName sets the "name" field.
|
||||||
|
func (su *SkuUpdate) SetName(s string) *SkuUpdate {
|
||||||
|
su.mutation.SetName(s)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableName sets the "name" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillableName(s *string) *SkuUpdate {
|
||||||
|
if s != nil {
|
||||||
|
su.SetName(*s)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetType sets the "type" field.
|
||||||
|
func (su *SkuUpdate) SetType(s sku.Type) *SkuUpdate {
|
||||||
|
su.mutation.SetType(s)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableType sets the "type" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillableType(s *sku.Type) *SkuUpdate {
|
||||||
|
if s != nil {
|
||||||
|
su.SetType(*s)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAmount sets the "amount" field.
|
||||||
|
func (su *SkuUpdate) SetAmount(i int64) *SkuUpdate {
|
||||||
|
su.mutation.ResetAmount()
|
||||||
|
su.mutation.SetAmount(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableAmount sets the "amount" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillableAmount(i *int64) *SkuUpdate {
|
||||||
|
if i != nil {
|
||||||
|
su.SetAmount(*i)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddAmount adds i to the "amount" field.
|
||||||
|
func (su *SkuUpdate) AddAmount(i int64) *SkuUpdate {
|
||||||
|
su.mutation.AddAmount(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDuration sets the "duration" field.
|
||||||
|
func (su *SkuUpdate) SetDuration(i int64) *SkuUpdate {
|
||||||
|
su.mutation.ResetDuration()
|
||||||
|
su.mutation.SetDuration(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableDuration sets the "duration" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillableDuration(i *int64) *SkuUpdate {
|
||||||
|
if i != nil {
|
||||||
|
su.SetDuration(*i)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddDuration adds i to the "duration" field.
|
||||||
|
func (su *SkuUpdate) AddDuration(i int64) *SkuUpdate {
|
||||||
|
su.mutation.AddDuration(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearDuration clears the value of the "duration" field.
|
||||||
|
func (su *SkuUpdate) ClearDuration() *SkuUpdate {
|
||||||
|
su.mutation.ClearDuration()
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPrice sets the "price" field.
|
||||||
|
func (su *SkuUpdate) SetPrice(i int64) *SkuUpdate {
|
||||||
|
su.mutation.ResetPrice()
|
||||||
|
su.mutation.SetPrice(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillablePrice sets the "price" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillablePrice(i *int64) *SkuUpdate {
|
||||||
|
if i != nil {
|
||||||
|
su.SetPrice(*i)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPrice adds i to the "price" field.
|
||||||
|
func (su *SkuUpdate) AddPrice(i int64) *SkuUpdate {
|
||||||
|
su.mutation.AddPrice(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearPrice clears the value of the "price" field.
|
||||||
|
func (su *SkuUpdate) ClearPrice() *SkuUpdate {
|
||||||
|
su.mutation.ClearPrice()
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPoints sets the "points" field.
|
||||||
|
func (su *SkuUpdate) SetPoints(i int64) *SkuUpdate {
|
||||||
|
su.mutation.ResetPoints()
|
||||||
|
su.mutation.SetPoints(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillablePoints sets the "points" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillablePoints(i *int64) *SkuUpdate {
|
||||||
|
if i != nil {
|
||||||
|
su.SetPoints(*i)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPoints adds i to the "points" field.
|
||||||
|
func (su *SkuUpdate) AddPoints(i int64) *SkuUpdate {
|
||||||
|
su.mutation.AddPoints(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearPoints clears the value of the "points" field.
|
||||||
|
func (su *SkuUpdate) ClearPoints() *SkuUpdate {
|
||||||
|
su.mutation.ClearPoints()
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLabel sets the "label" field.
|
||||||
|
func (su *SkuUpdate) SetLabel(s string) *SkuUpdate {
|
||||||
|
su.mutation.SetLabel(s)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableLabel sets the "label" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillableLabel(s *string) *SkuUpdate {
|
||||||
|
if s != nil {
|
||||||
|
su.SetLabel(*s)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearLabel clears the value of the "label" field.
|
||||||
|
func (su *SkuUpdate) ClearLabel() *SkuUpdate {
|
||||||
|
su.mutation.ClearLabel()
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDes sets the "des" field.
|
||||||
|
func (su *SkuUpdate) SetDes(s string) *SkuUpdate {
|
||||||
|
su.mutation.SetDes(s)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableDes sets the "des" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillableDes(s *string) *SkuUpdate {
|
||||||
|
if s != nil {
|
||||||
|
su.SetDes(*s)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearDes clears the value of the "des" field.
|
||||||
|
func (su *SkuUpdate) ClearDes() *SkuUpdate {
|
||||||
|
su.mutation.ClearDes()
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEnabled sets the "enabled" field.
|
||||||
|
func (su *SkuUpdate) SetEnabled(b bool) *SkuUpdate {
|
||||||
|
su.mutation.SetEnabled(b)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableEnabled sets the "enabled" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillableEnabled(b *bool) *SkuUpdate {
|
||||||
|
if b != nil {
|
||||||
|
su.SetEnabled(*b)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWeight sets the "weight" field.
|
||||||
|
func (su *SkuUpdate) SetWeight(i int) *SkuUpdate {
|
||||||
|
su.mutation.ResetWeight()
|
||||||
|
su.mutation.SetWeight(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableWeight sets the "weight" field if the given value is not nil.
|
||||||
|
func (su *SkuUpdate) SetNillableWeight(i *int) *SkuUpdate {
|
||||||
|
if i != nil {
|
||||||
|
su.SetWeight(*i)
|
||||||
|
}
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddWeight adds i to the "weight" field.
|
||||||
|
func (su *SkuUpdate) AddWeight(i int) *SkuUpdate {
|
||||||
|
su.mutation.AddWeight(i)
|
||||||
|
return su
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutation returns the SkuMutation object of the builder.
|
||||||
|
func (su *SkuUpdate) Mutation() *SkuMutation {
|
||||||
|
return su.mutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||||
|
func (su *SkuUpdate) Save(ctx context.Context) (int, error) {
|
||||||
|
if err := su.defaults(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return withHooks(ctx, su.sqlSave, su.mutation, su.hooks)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
func (su *SkuUpdate) SaveX(ctx context.Context) int {
|
||||||
|
affected, err := su.Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return affected
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the query.
|
||||||
|
func (su *SkuUpdate) Exec(ctx context.Context) error {
|
||||||
|
_, err := su.Save(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (su *SkuUpdate) ExecX(ctx context.Context) {
|
||||||
|
if err := su.Exec(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaults sets the default values of the builder before save.
|
||||||
|
func (su *SkuUpdate) defaults() error {
|
||||||
|
if _, ok := su.mutation.UpdatedAt(); !ok {
|
||||||
|
if sku.UpdateDefaultUpdatedAt == nil {
|
||||||
|
return fmt.Errorf("ent: uninitialized sku.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||||
|
}
|
||||||
|
v := sku.UpdateDefaultUpdatedAt()
|
||||||
|
su.mutation.SetUpdatedAt(v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// check runs all checks and user-defined validators on the builder.
|
||||||
|
func (su *SkuUpdate) check() error {
|
||||||
|
if v, ok := su.mutation.GetType(); ok {
|
||||||
|
if err := sku.TypeValidator(v); err != nil {
|
||||||
|
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "Sku.type": %w`, err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (su *SkuUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
|
if err := su.check(); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
_spec := sqlgraph.NewUpdateSpec(sku.Table, sku.Columns, sqlgraph.NewFieldSpec(sku.FieldID, field.TypeInt))
|
||||||
|
if ps := su.mutation.predicates; len(ps) > 0 {
|
||||||
|
_spec.Predicate = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.UpdatedAt(); ok {
|
||||||
|
_spec.SetField(sku.FieldUpdatedAt, field.TypeTime, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.DeletedAt(); ok {
|
||||||
|
_spec.SetField(sku.FieldDeletedAt, field.TypeTime, value)
|
||||||
|
}
|
||||||
|
if su.mutation.DeletedAtCleared() {
|
||||||
|
_spec.ClearField(sku.FieldDeletedAt, field.TypeTime)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.Name(); ok {
|
||||||
|
_spec.SetField(sku.FieldName, field.TypeString, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.GetType(); ok {
|
||||||
|
_spec.SetField(sku.FieldType, field.TypeEnum, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.Amount(); ok {
|
||||||
|
_spec.SetField(sku.FieldAmount, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.AddedAmount(); ok {
|
||||||
|
_spec.AddField(sku.FieldAmount, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.Duration(); ok {
|
||||||
|
_spec.SetField(sku.FieldDuration, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.AddedDuration(); ok {
|
||||||
|
_spec.AddField(sku.FieldDuration, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if su.mutation.DurationCleared() {
|
||||||
|
_spec.ClearField(sku.FieldDuration, field.TypeInt64)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.Price(); ok {
|
||||||
|
_spec.SetField(sku.FieldPrice, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.AddedPrice(); ok {
|
||||||
|
_spec.AddField(sku.FieldPrice, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if su.mutation.PriceCleared() {
|
||||||
|
_spec.ClearField(sku.FieldPrice, field.TypeInt64)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.Points(); ok {
|
||||||
|
_spec.SetField(sku.FieldPoints, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.AddedPoints(); ok {
|
||||||
|
_spec.AddField(sku.FieldPoints, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if su.mutation.PointsCleared() {
|
||||||
|
_spec.ClearField(sku.FieldPoints, field.TypeInt64)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.Label(); ok {
|
||||||
|
_spec.SetField(sku.FieldLabel, field.TypeString, value)
|
||||||
|
}
|
||||||
|
if su.mutation.LabelCleared() {
|
||||||
|
_spec.ClearField(sku.FieldLabel, field.TypeString)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.Des(); ok {
|
||||||
|
_spec.SetField(sku.FieldDes, field.TypeString, value)
|
||||||
|
}
|
||||||
|
if su.mutation.DesCleared() {
|
||||||
|
_spec.ClearField(sku.FieldDes, field.TypeString)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.Enabled(); ok {
|
||||||
|
_spec.SetField(sku.FieldEnabled, field.TypeBool, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.Weight(); ok {
|
||||||
|
_spec.SetField(sku.FieldWeight, field.TypeInt, value)
|
||||||
|
}
|
||||||
|
if value, ok := su.mutation.AddedWeight(); ok {
|
||||||
|
_spec.AddField(sku.FieldWeight, field.TypeInt, value)
|
||||||
|
}
|
||||||
|
if n, err = sqlgraph.UpdateNodes(ctx, su.driver, _spec); err != nil {
|
||||||
|
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||||
|
err = &NotFoundError{sku.Label}
|
||||||
|
} else if sqlgraph.IsConstraintError(err) {
|
||||||
|
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
su.mutation.done = true
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SkuUpdateOne is the builder for updating a single Sku entity.
|
||||||
|
type SkuUpdateOne struct {
|
||||||
|
config
|
||||||
|
fields []string
|
||||||
|
hooks []Hook
|
||||||
|
mutation *SkuMutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUpdatedAt sets the "updated_at" field.
|
||||||
|
func (suo *SkuUpdateOne) SetUpdatedAt(t time.Time) *SkuUpdateOne {
|
||||||
|
suo.mutation.SetUpdatedAt(t)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDeletedAt sets the "deleted_at" field.
|
||||||
|
func (suo *SkuUpdateOne) SetDeletedAt(t time.Time) *SkuUpdateOne {
|
||||||
|
suo.mutation.SetDeletedAt(t)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillableDeletedAt(t *time.Time) *SkuUpdateOne {
|
||||||
|
if t != nil {
|
||||||
|
suo.SetDeletedAt(*t)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||||
|
func (suo *SkuUpdateOne) ClearDeletedAt() *SkuUpdateOne {
|
||||||
|
suo.mutation.ClearDeletedAt()
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName sets the "name" field.
|
||||||
|
func (suo *SkuUpdateOne) SetName(s string) *SkuUpdateOne {
|
||||||
|
suo.mutation.SetName(s)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableName sets the "name" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillableName(s *string) *SkuUpdateOne {
|
||||||
|
if s != nil {
|
||||||
|
suo.SetName(*s)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetType sets the "type" field.
|
||||||
|
func (suo *SkuUpdateOne) SetType(s sku.Type) *SkuUpdateOne {
|
||||||
|
suo.mutation.SetType(s)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableType sets the "type" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillableType(s *sku.Type) *SkuUpdateOne {
|
||||||
|
if s != nil {
|
||||||
|
suo.SetType(*s)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAmount sets the "amount" field.
|
||||||
|
func (suo *SkuUpdateOne) SetAmount(i int64) *SkuUpdateOne {
|
||||||
|
suo.mutation.ResetAmount()
|
||||||
|
suo.mutation.SetAmount(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableAmount sets the "amount" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillableAmount(i *int64) *SkuUpdateOne {
|
||||||
|
if i != nil {
|
||||||
|
suo.SetAmount(*i)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddAmount adds i to the "amount" field.
|
||||||
|
func (suo *SkuUpdateOne) AddAmount(i int64) *SkuUpdateOne {
|
||||||
|
suo.mutation.AddAmount(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDuration sets the "duration" field.
|
||||||
|
func (suo *SkuUpdateOne) SetDuration(i int64) *SkuUpdateOne {
|
||||||
|
suo.mutation.ResetDuration()
|
||||||
|
suo.mutation.SetDuration(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableDuration sets the "duration" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillableDuration(i *int64) *SkuUpdateOne {
|
||||||
|
if i != nil {
|
||||||
|
suo.SetDuration(*i)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddDuration adds i to the "duration" field.
|
||||||
|
func (suo *SkuUpdateOne) AddDuration(i int64) *SkuUpdateOne {
|
||||||
|
suo.mutation.AddDuration(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearDuration clears the value of the "duration" field.
|
||||||
|
func (suo *SkuUpdateOne) ClearDuration() *SkuUpdateOne {
|
||||||
|
suo.mutation.ClearDuration()
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPrice sets the "price" field.
|
||||||
|
func (suo *SkuUpdateOne) SetPrice(i int64) *SkuUpdateOne {
|
||||||
|
suo.mutation.ResetPrice()
|
||||||
|
suo.mutation.SetPrice(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillablePrice sets the "price" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillablePrice(i *int64) *SkuUpdateOne {
|
||||||
|
if i != nil {
|
||||||
|
suo.SetPrice(*i)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPrice adds i to the "price" field.
|
||||||
|
func (suo *SkuUpdateOne) AddPrice(i int64) *SkuUpdateOne {
|
||||||
|
suo.mutation.AddPrice(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearPrice clears the value of the "price" field.
|
||||||
|
func (suo *SkuUpdateOne) ClearPrice() *SkuUpdateOne {
|
||||||
|
suo.mutation.ClearPrice()
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPoints sets the "points" field.
|
||||||
|
func (suo *SkuUpdateOne) SetPoints(i int64) *SkuUpdateOne {
|
||||||
|
suo.mutation.ResetPoints()
|
||||||
|
suo.mutation.SetPoints(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillablePoints sets the "points" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillablePoints(i *int64) *SkuUpdateOne {
|
||||||
|
if i != nil {
|
||||||
|
suo.SetPoints(*i)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPoints adds i to the "points" field.
|
||||||
|
func (suo *SkuUpdateOne) AddPoints(i int64) *SkuUpdateOne {
|
||||||
|
suo.mutation.AddPoints(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearPoints clears the value of the "points" field.
|
||||||
|
func (suo *SkuUpdateOne) ClearPoints() *SkuUpdateOne {
|
||||||
|
suo.mutation.ClearPoints()
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLabel sets the "label" field.
|
||||||
|
func (suo *SkuUpdateOne) SetLabel(s string) *SkuUpdateOne {
|
||||||
|
suo.mutation.SetLabel(s)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableLabel sets the "label" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillableLabel(s *string) *SkuUpdateOne {
|
||||||
|
if s != nil {
|
||||||
|
suo.SetLabel(*s)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearLabel clears the value of the "label" field.
|
||||||
|
func (suo *SkuUpdateOne) ClearLabel() *SkuUpdateOne {
|
||||||
|
suo.mutation.ClearLabel()
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDes sets the "des" field.
|
||||||
|
func (suo *SkuUpdateOne) SetDes(s string) *SkuUpdateOne {
|
||||||
|
suo.mutation.SetDes(s)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableDes sets the "des" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillableDes(s *string) *SkuUpdateOne {
|
||||||
|
if s != nil {
|
||||||
|
suo.SetDes(*s)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearDes clears the value of the "des" field.
|
||||||
|
func (suo *SkuUpdateOne) ClearDes() *SkuUpdateOne {
|
||||||
|
suo.mutation.ClearDes()
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEnabled sets the "enabled" field.
|
||||||
|
func (suo *SkuUpdateOne) SetEnabled(b bool) *SkuUpdateOne {
|
||||||
|
suo.mutation.SetEnabled(b)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableEnabled sets the "enabled" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillableEnabled(b *bool) *SkuUpdateOne {
|
||||||
|
if b != nil {
|
||||||
|
suo.SetEnabled(*b)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWeight sets the "weight" field.
|
||||||
|
func (suo *SkuUpdateOne) SetWeight(i int) *SkuUpdateOne {
|
||||||
|
suo.mutation.ResetWeight()
|
||||||
|
suo.mutation.SetWeight(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableWeight sets the "weight" field if the given value is not nil.
|
||||||
|
func (suo *SkuUpdateOne) SetNillableWeight(i *int) *SkuUpdateOne {
|
||||||
|
if i != nil {
|
||||||
|
suo.SetWeight(*i)
|
||||||
|
}
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddWeight adds i to the "weight" field.
|
||||||
|
func (suo *SkuUpdateOne) AddWeight(i int) *SkuUpdateOne {
|
||||||
|
suo.mutation.AddWeight(i)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutation returns the SkuMutation object of the builder.
|
||||||
|
func (suo *SkuUpdateOne) Mutation() *SkuMutation {
|
||||||
|
return suo.mutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where appends a list predicates to the SkuUpdate builder.
|
||||||
|
func (suo *SkuUpdateOne) Where(ps ...predicate.Sku) *SkuUpdateOne {
|
||||||
|
suo.mutation.Where(ps...)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||||
|
// The default is selecting all fields defined in the entity schema.
|
||||||
|
func (suo *SkuUpdateOne) Select(field string, fields ...string) *SkuUpdateOne {
|
||||||
|
suo.fields = append([]string{field}, fields...)
|
||||||
|
return suo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save executes the query and returns the updated Sku entity.
|
||||||
|
func (suo *SkuUpdateOne) Save(ctx context.Context) (*Sku, error) {
|
||||||
|
if err := suo.defaults(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return withHooks(ctx, suo.sqlSave, suo.mutation, suo.hooks)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
func (suo *SkuUpdateOne) SaveX(ctx context.Context) *Sku {
|
||||||
|
node, err := suo.Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the query on the entity.
|
||||||
|
func (suo *SkuUpdateOne) Exec(ctx context.Context) error {
|
||||||
|
_, err := suo.Save(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (suo *SkuUpdateOne) ExecX(ctx context.Context) {
|
||||||
|
if err := suo.Exec(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaults sets the default values of the builder before save.
|
||||||
|
func (suo *SkuUpdateOne) defaults() error {
|
||||||
|
if _, ok := suo.mutation.UpdatedAt(); !ok {
|
||||||
|
if sku.UpdateDefaultUpdatedAt == nil {
|
||||||
|
return fmt.Errorf("ent: uninitialized sku.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||||
|
}
|
||||||
|
v := sku.UpdateDefaultUpdatedAt()
|
||||||
|
suo.mutation.SetUpdatedAt(v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// check runs all checks and user-defined validators on the builder.
|
||||||
|
func (suo *SkuUpdateOne) check() error {
|
||||||
|
if v, ok := suo.mutation.GetType(); ok {
|
||||||
|
if err := sku.TypeValidator(v); err != nil {
|
||||||
|
return &ValidationError{Name: "type", err: fmt.Errorf(`ent: validator failed for field "Sku.type": %w`, err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suo *SkuUpdateOne) sqlSave(ctx context.Context) (_node *Sku, err error) {
|
||||||
|
if err := suo.check(); err != nil {
|
||||||
|
return _node, err
|
||||||
|
}
|
||||||
|
_spec := sqlgraph.NewUpdateSpec(sku.Table, sku.Columns, sqlgraph.NewFieldSpec(sku.FieldID, field.TypeInt))
|
||||||
|
id, ok := suo.mutation.ID()
|
||||||
|
if !ok {
|
||||||
|
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Sku.id" for update`)}
|
||||||
|
}
|
||||||
|
_spec.Node.ID.Value = id
|
||||||
|
if fields := suo.fields; len(fields) > 0 {
|
||||||
|
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||||
|
_spec.Node.Columns = append(_spec.Node.Columns, sku.FieldID)
|
||||||
|
for _, f := range fields {
|
||||||
|
if !sku.ValidColumn(f) {
|
||||||
|
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||||
|
}
|
||||||
|
if f != sku.FieldID {
|
||||||
|
_spec.Node.Columns = append(_spec.Node.Columns, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ps := suo.mutation.predicates; len(ps) > 0 {
|
||||||
|
_spec.Predicate = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.UpdatedAt(); ok {
|
||||||
|
_spec.SetField(sku.FieldUpdatedAt, field.TypeTime, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.DeletedAt(); ok {
|
||||||
|
_spec.SetField(sku.FieldDeletedAt, field.TypeTime, value)
|
||||||
|
}
|
||||||
|
if suo.mutation.DeletedAtCleared() {
|
||||||
|
_spec.ClearField(sku.FieldDeletedAt, field.TypeTime)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.Name(); ok {
|
||||||
|
_spec.SetField(sku.FieldName, field.TypeString, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.GetType(); ok {
|
||||||
|
_spec.SetField(sku.FieldType, field.TypeEnum, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.Amount(); ok {
|
||||||
|
_spec.SetField(sku.FieldAmount, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.AddedAmount(); ok {
|
||||||
|
_spec.AddField(sku.FieldAmount, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.Duration(); ok {
|
||||||
|
_spec.SetField(sku.FieldDuration, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.AddedDuration(); ok {
|
||||||
|
_spec.AddField(sku.FieldDuration, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if suo.mutation.DurationCleared() {
|
||||||
|
_spec.ClearField(sku.FieldDuration, field.TypeInt64)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.Price(); ok {
|
||||||
|
_spec.SetField(sku.FieldPrice, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.AddedPrice(); ok {
|
||||||
|
_spec.AddField(sku.FieldPrice, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if suo.mutation.PriceCleared() {
|
||||||
|
_spec.ClearField(sku.FieldPrice, field.TypeInt64)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.Points(); ok {
|
||||||
|
_spec.SetField(sku.FieldPoints, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.AddedPoints(); ok {
|
||||||
|
_spec.AddField(sku.FieldPoints, field.TypeInt64, value)
|
||||||
|
}
|
||||||
|
if suo.mutation.PointsCleared() {
|
||||||
|
_spec.ClearField(sku.FieldPoints, field.TypeInt64)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.Label(); ok {
|
||||||
|
_spec.SetField(sku.FieldLabel, field.TypeString, value)
|
||||||
|
}
|
||||||
|
if suo.mutation.LabelCleared() {
|
||||||
|
_spec.ClearField(sku.FieldLabel, field.TypeString)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.Des(); ok {
|
||||||
|
_spec.SetField(sku.FieldDes, field.TypeString, value)
|
||||||
|
}
|
||||||
|
if suo.mutation.DesCleared() {
|
||||||
|
_spec.ClearField(sku.FieldDes, field.TypeString)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.Enabled(); ok {
|
||||||
|
_spec.SetField(sku.FieldEnabled, field.TypeBool, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.Weight(); ok {
|
||||||
|
_spec.SetField(sku.FieldWeight, field.TypeInt, value)
|
||||||
|
}
|
||||||
|
if value, ok := suo.mutation.AddedWeight(); ok {
|
||||||
|
_spec.AddField(sku.FieldWeight, field.TypeInt, value)
|
||||||
|
}
|
||||||
|
_node = &Sku{config: suo.config}
|
||||||
|
_spec.Assign = _node.assignValues
|
||||||
|
_spec.ScanValues = _node.scanValues
|
||||||
|
if err = sqlgraph.UpdateNode(ctx, suo.driver, _spec); err != nil {
|
||||||
|
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||||
|
err = &NotFoundError{sku.Label}
|
||||||
|
} else if sqlgraph.IsConstraintError(err) {
|
||||||
|
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
suo.mutation.done = true
|
||||||
|
return _node, nil
|
||||||
|
}
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import { Box, Table, TableBody, TableContainer, TableHead, TableRow, Typography } from "@mui/material";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { NoWrapCell, SecondaryButton, StyledTableContainerPaper } from "../../../Common/StyledComponents.tsx";
|
|
||||||
import Add from "../../../Icons/Add.tsx";
|
|
||||||
|
|
||||||
const GroupProducts = () => {
|
|
||||||
const { t } = useTranslation("dashboard");
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }}>
|
|
||||||
<SecondaryButton variant="contained" startIcon={<Add />}>
|
|
||||||
{t("settings.addGroupProduct")}
|
|
||||||
</SecondaryButton>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<TableContainer component={StyledTableContainerPaper}>
|
|
||||||
<Table sx={{ width: "100%" }} size="small">
|
|
||||||
<TableHead>
|
|
||||||
<TableRow>
|
|
||||||
<NoWrapCell>{t("settings.displayName")}</NoWrapCell>
|
|
||||||
<NoWrapCell>{t("settings.price")}</NoWrapCell>
|
|
||||||
<NoWrapCell>{t("settings.duration")}</NoWrapCell>
|
|
||||||
<NoWrapCell>{t("settings.description")}</NoWrapCell>
|
|
||||||
<NoWrapCell>{t("settings.actions")}</NoWrapCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
<TableRow>
|
|
||||||
<NoWrapCell colSpan={5} align="center">
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
|
||||||
{t("application:setting.listEmpty")}
|
|
||||||
</Typography>
|
|
||||||
</NoWrapCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default GroupProducts;
|
|
||||||
@ -0,0 +1,349 @@
|
|||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Chip,
|
||||||
|
Dialog,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
FormControl,
|
||||||
|
FormControlLabel,
|
||||||
|
IconButton,
|
||||||
|
InputLabel,
|
||||||
|
MenuItem,
|
||||||
|
Select,
|
||||||
|
Stack,
|
||||||
|
Switch,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { adminDeleteSku, adminListSkus, adminUpsertSku, getGroupList } from "../../../../api/api.ts";
|
||||||
|
import { GroupEnt, Sku } from "../../../../api/dashboard.ts";
|
||||||
|
import { useAppDispatch } from "../../../../redux/hooks.ts";
|
||||||
|
import { sizeToString } from "../../../../util/index.ts";
|
||||||
|
import {
|
||||||
|
DenseFilledTextField,
|
||||||
|
NoWrapCell,
|
||||||
|
SecondaryButton,
|
||||||
|
StyledTableContainerPaper,
|
||||||
|
} from "../../../Common/StyledComponents.tsx";
|
||||||
|
import Add from "../../../Icons/Add.tsx";
|
||||||
|
import Dismiss from "../../../Icons/Dismiss.tsx";
|
||||||
|
import Edit from "../../../Icons/Edit.tsx";
|
||||||
|
import SettingForm from "../../../Pages/Setting/SettingForm.tsx";
|
||||||
|
import { NoMarginHelperText } from "../Settings.tsx";
|
||||||
|
|
||||||
|
const DAY_SECONDS = 86400;
|
||||||
|
|
||||||
|
export interface SkuTableProps {
|
||||||
|
type: "storage" | "group";
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SkuForm {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
amount: number;
|
||||||
|
durationDays: number;
|
||||||
|
price: number;
|
||||||
|
allowPoints: boolean;
|
||||||
|
points: number;
|
||||||
|
label: string;
|
||||||
|
des: string;
|
||||||
|
enabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const emptyForm = (type: string): SkuForm => ({
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
amount: 0,
|
||||||
|
durationDays: type === "storage" ? 365 : 30,
|
||||||
|
price: 0,
|
||||||
|
allowPoints: false,
|
||||||
|
points: 0,
|
||||||
|
label: "",
|
||||||
|
des: "",
|
||||||
|
enabled: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const SkuTable = ({ type }: SkuTableProps) => {
|
||||||
|
const { t } = useTranslation("dashboard");
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const [skus, setSkus] = useState<Sku[] | undefined>(undefined);
|
||||||
|
const [groups, setGroups] = useState<GroupEnt[]>([]);
|
||||||
|
const [form, setForm] = useState<SkuForm | undefined>(undefined);
|
||||||
|
const [saving, setSaving] = useState(false);
|
||||||
|
|
||||||
|
const load = useCallback(() => {
|
||||||
|
dispatch(adminListSkus()).then((res) => setSkus(res.filter((s) => s.type === type)));
|
||||||
|
}, [type]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
load();
|
||||||
|
dispatch(getGroupList({ page: 1, page_size: 200, order_by: "id", order_direction: "asc" })).then((res) =>
|
||||||
|
setGroups(res.groups),
|
||||||
|
);
|
||||||
|
}, [load]);
|
||||||
|
|
||||||
|
const groupName = useCallback(
|
||||||
|
(id: number) => groups.find((g) => g.id === id)?.name ?? `#${id}`,
|
||||||
|
[groups],
|
||||||
|
);
|
||||||
|
|
||||||
|
const openEdit = (s?: Sku) => {
|
||||||
|
if (!s) {
|
||||||
|
setForm(emptyForm(type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setForm({
|
||||||
|
id: s.id,
|
||||||
|
name: s.name,
|
||||||
|
amount: s.amount,
|
||||||
|
durationDays: Math.round((s.duration ?? 0) / DAY_SECONDS),
|
||||||
|
price: s.price ?? 0,
|
||||||
|
allowPoints: s.points != null,
|
||||||
|
points: s.points ?? 0,
|
||||||
|
label: s.label ?? "",
|
||||||
|
des: s.des ?? "",
|
||||||
|
enabled: s.enabled,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSave = () => {
|
||||||
|
if (!form) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSaving(true);
|
||||||
|
dispatch(
|
||||||
|
adminUpsertSku({
|
||||||
|
id: form.id,
|
||||||
|
name: form.name,
|
||||||
|
type,
|
||||||
|
amount: form.amount,
|
||||||
|
duration: Math.max(0, form.durationDays) * DAY_SECONDS,
|
||||||
|
price: Math.max(0, form.price),
|
||||||
|
points: form.allowPoints ? Math.max(1, form.points) : undefined,
|
||||||
|
label: form.label || undefined,
|
||||||
|
des: form.des || undefined,
|
||||||
|
enabled: form.enabled,
|
||||||
|
weight: 0,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
setForm(undefined);
|
||||||
|
load();
|
||||||
|
})
|
||||||
|
.finally(() => setSaving(false));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDelete = (id: number) => {
|
||||||
|
dispatch(adminDeleteSku(id)).then(load);
|
||||||
|
};
|
||||||
|
|
||||||
|
const amountLabel = (s: Sku) => (type === "storage" ? sizeToString(s.amount) : groupName(s.amount));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack spacing={2}>
|
||||||
|
<Box>
|
||||||
|
<SecondaryButton variant="contained" startIcon={<Add />} onClick={() => openEdit()}>
|
||||||
|
{type === "storage" ? t("vas.addStoragePack") : t("vas.addMembership")}
|
||||||
|
</SecondaryButton>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<StyledTableContainerPaper>
|
||||||
|
<TableContainer>
|
||||||
|
<Table size="small">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<NoWrapCell>{t("vas.name")}</NoWrapCell>
|
||||||
|
<NoWrapCell>{type === "storage" ? t("vas.size") : t("vas.group")}</NoWrapCell>
|
||||||
|
<NoWrapCell>{t("vas.duration")}</NoWrapCell>
|
||||||
|
<NoWrapCell>{t("vas.price")}</NoWrapCell>
|
||||||
|
<NoWrapCell>{t("vas.priceCredits")}</NoWrapCell>
|
||||||
|
<NoWrapCell>{t("vas.status")}</NoWrapCell>
|
||||||
|
<NoWrapCell align="right">{t("vas.actions")}</NoWrapCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{skus?.map((s) => (
|
||||||
|
<TableRow key={s.id}>
|
||||||
|
<NoWrapCell>
|
||||||
|
{s.name}
|
||||||
|
{s.label && <Chip size="small" color="primary" label={s.label} sx={{ ml: 1 }} />}
|
||||||
|
</NoWrapCell>
|
||||||
|
<NoWrapCell>{amountLabel(s)}</NoWrapCell>
|
||||||
|
<NoWrapCell>
|
||||||
|
{(s.duration ?? 0) > 0
|
||||||
|
? t("application:vas.validDurationDays", { num: Math.round((s.duration ?? 0) / DAY_SECONDS) })
|
||||||
|
: t("application:shop.permanent")}
|
||||||
|
</NoWrapCell>
|
||||||
|
<NoWrapCell>{s.price ?? 0}</NoWrapCell>
|
||||||
|
<NoWrapCell>{s.points != null ? s.points : "-"}</NoWrapCell>
|
||||||
|
<NoWrapCell>
|
||||||
|
<Chip
|
||||||
|
size="small"
|
||||||
|
color={s.enabled ? "success" : "default"}
|
||||||
|
label={s.enabled ? t("vas.enable") : t("vas.no")}
|
||||||
|
/>
|
||||||
|
</NoWrapCell>
|
||||||
|
<NoWrapCell align="right">
|
||||||
|
<IconButton size="small" onClick={() => openEdit(s)}>
|
||||||
|
<Edit fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton size="small" onClick={() => onDelete(s.id)}>
|
||||||
|
<Dismiss fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
</NoWrapCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
{(!skus || skus.length === 0) && (
|
||||||
|
<TableRow>
|
||||||
|
<NoWrapCell colSpan={7} align="center">
|
||||||
|
<Typography variant="caption" color="text.secondary">
|
||||||
|
{t("application:setting.listEmpty")}
|
||||||
|
</Typography>
|
||||||
|
</NoWrapCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</StyledTableContainerPaper>
|
||||||
|
|
||||||
|
<Dialog open={!!form} onClose={() => setForm(undefined)} maxWidth="sm" fullWidth>
|
||||||
|
<DialogTitle>{type === "storage" ? t("vas.editStoragePack") : t("vas.editMembership")}</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
{form && (
|
||||||
|
<Stack spacing={2} sx={{ mt: 1 }}>
|
||||||
|
<SettingForm title={t("vas.productName")}>
|
||||||
|
<DenseFilledTextField
|
||||||
|
fullWidth
|
||||||
|
value={form.name}
|
||||||
|
onChange={(e) => setForm({ ...form, name: e.target.value })}
|
||||||
|
/>
|
||||||
|
<NoMarginHelperText>{t("vas.productNameDes")}</NoMarginHelperText>
|
||||||
|
</SettingForm>
|
||||||
|
|
||||||
|
{type === "storage" ? (
|
||||||
|
<SettingForm title={t("vas.size")}>
|
||||||
|
<DenseFilledTextField
|
||||||
|
fullWidth
|
||||||
|
type="number"
|
||||||
|
value={form.amount}
|
||||||
|
onChange={(e) => setForm({ ...form, amount: parseInt(e.target.value) || 0 })}
|
||||||
|
/>
|
||||||
|
<NoMarginHelperText>{t("vas.packSizeDes")}</NoMarginHelperText>
|
||||||
|
</SettingForm>
|
||||||
|
) : (
|
||||||
|
<SettingForm title={t("vas.purchasableGroups")}>
|
||||||
|
<FormControl fullWidth size="small">
|
||||||
|
<InputLabel>{t("vas.purchasableGroups")}</InputLabel>
|
||||||
|
<Select
|
||||||
|
value={form.amount}
|
||||||
|
label={t("vas.purchasableGroups")}
|
||||||
|
onChange={(e) => setForm({ ...form, amount: e.target.value as number })}
|
||||||
|
>
|
||||||
|
{groups.map((g) => (
|
||||||
|
<MenuItem key={g.id} value={g.id}>
|
||||||
|
{g.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<NoMarginHelperText>{t("vas.groupDes")}</NoMarginHelperText>
|
||||||
|
</SettingForm>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<SettingForm title={t("vas.durationDay")}>
|
||||||
|
<DenseFilledTextField
|
||||||
|
fullWidth
|
||||||
|
type="number"
|
||||||
|
value={form.durationDays}
|
||||||
|
onChange={(e) => setForm({ ...form, durationDays: parseInt(e.target.value) || 0 })}
|
||||||
|
/>
|
||||||
|
<NoMarginHelperText>
|
||||||
|
{type === "storage" ? t("vas.durationDayDes") : t("vas.durationGroupDes")}
|
||||||
|
</NoMarginHelperText>
|
||||||
|
</SettingForm>
|
||||||
|
|
||||||
|
<SettingForm title={t("vas.priceYuan")}>
|
||||||
|
<DenseFilledTextField
|
||||||
|
fullWidth
|
||||||
|
type="number"
|
||||||
|
value={form.price}
|
||||||
|
onChange={(e) => setForm({ ...form, price: parseInt(e.target.value) || 0 })}
|
||||||
|
/>
|
||||||
|
<NoMarginHelperText>{t("vas.packPriceDes")}</NoMarginHelperText>
|
||||||
|
</SettingForm>
|
||||||
|
|
||||||
|
<SettingForm lgWidth={5}>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={form.allowPoints}
|
||||||
|
onChange={(e) => setForm({ ...form, allowPoints: e.target.checked })}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={t("vas.priceCredits")}
|
||||||
|
/>
|
||||||
|
<NoMarginHelperText>{t("vas.priceCreditsDes")}</NoMarginHelperText>
|
||||||
|
</SettingForm>
|
||||||
|
|
||||||
|
{form.allowPoints && (
|
||||||
|
<SettingForm title={t("vas.priceCredits")}>
|
||||||
|
<DenseFilledTextField
|
||||||
|
fullWidth
|
||||||
|
type="number"
|
||||||
|
value={form.points}
|
||||||
|
onChange={(e) => setForm({ ...form, points: parseInt(e.target.value) || 0 })}
|
||||||
|
/>
|
||||||
|
</SettingForm>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<SettingForm title={t("vas.highlight")}>
|
||||||
|
<DenseFilledTextField
|
||||||
|
fullWidth
|
||||||
|
value={form.label}
|
||||||
|
onChange={(e) => setForm({ ...form, label: e.target.value })}
|
||||||
|
/>
|
||||||
|
<NoMarginHelperText>{t("vas.highlightDes")}</NoMarginHelperText>
|
||||||
|
</SettingForm>
|
||||||
|
|
||||||
|
<SettingForm title={t("vas.productDescription")}>
|
||||||
|
<DenseFilledTextField
|
||||||
|
fullWidth
|
||||||
|
multiline
|
||||||
|
minRows={3}
|
||||||
|
value={form.des}
|
||||||
|
onChange={(e) => setForm({ ...form, des: e.target.value })}
|
||||||
|
/>
|
||||||
|
<NoMarginHelperText>{t("vas.productDescriptionDes")}</NoMarginHelperText>
|
||||||
|
</SettingForm>
|
||||||
|
|
||||||
|
<SettingForm lgWidth={5}>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch checked={form.enabled} onChange={(e) => setForm({ ...form, enabled: e.target.checked })} />
|
||||||
|
}
|
||||||
|
label={t("vas.enable")}
|
||||||
|
/>
|
||||||
|
</SettingForm>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<SecondaryButton onClick={() => setForm(undefined)}>{t("common:cancel")}</SecondaryButton>
|
||||||
|
<SecondaryButton variant="contained" onClick={onSave} disabled={saving || !form?.name || !form?.amount}>
|
||||||
|
{t("common:ok")}
|
||||||
|
</SecondaryButton>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SkuTable;
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import { Box, Table, TableBody, TableContainer, TableHead, TableRow, Typography } from "@mui/material";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { NoWrapCell, SecondaryButton, StyledTableContainerPaper } from "../../../Common/StyledComponents.tsx";
|
|
||||||
import Add from "../../../Icons/Add.tsx";
|
|
||||||
|
|
||||||
const StorageProducts = () => {
|
|
||||||
const { t } = useTranslation("dashboard");
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }}>
|
|
||||||
<SecondaryButton variant="contained" startIcon={<Add />}>
|
|
||||||
{t("settings.addStorageProduct")}
|
|
||||||
</SecondaryButton>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<TableContainer component={StyledTableContainerPaper}>
|
|
||||||
<Table sx={{ width: "100%" }} size="small">
|
|
||||||
<TableHead>
|
|
||||||
<TableRow>
|
|
||||||
<NoWrapCell>{t("settings.displayName")}</NoWrapCell>
|
|
||||||
<NoWrapCell>{t("settings.price")}</NoWrapCell>
|
|
||||||
<NoWrapCell>{t("settings.duration")}</NoWrapCell>
|
|
||||||
<NoWrapCell>{t("settings.storageSize")}</NoWrapCell>
|
|
||||||
<NoWrapCell>{t("settings.actions")}</NoWrapCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
<TableRow>
|
|
||||||
<NoWrapCell colSpan={5} align="center">
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
|
||||||
{t("application:setting.listEmpty")}
|
|
||||||
</Typography>
|
|
||||||
</NoWrapCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default StorageProducts;
|
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
import { Button, InputAdornment } from "@mui/material";
|
||||||
|
import { useSnackbar } from "notistack";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { redeemGiftCode } from "../../../api/api.ts";
|
||||||
|
import { useAppDispatch } from "../../../redux/hooks.ts";
|
||||||
|
import { DenseFilledTextField } from "../StyledComponents.tsx";
|
||||||
|
|
||||||
|
export interface RedeemCodeInputProps {
|
||||||
|
onRedeemed?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RedeemCodeInput = ({ onRedeemed }: RedeemCodeInputProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
const [code, setCode] = useState("");
|
||||||
|
const [redeeming, setRedeeming] = useState(false);
|
||||||
|
|
||||||
|
const onRedeem = () => {
|
||||||
|
if (!code.trim()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setRedeeming(true);
|
||||||
|
dispatch(redeemGiftCode(code.trim()))
|
||||||
|
.then(() => {
|
||||||
|
enqueueSnackbar(t("setting.giftCodeRedeemed"), { variant: "success" });
|
||||||
|
setCode("");
|
||||||
|
onRedeemed?.();
|
||||||
|
})
|
||||||
|
.finally(() => setRedeeming(false));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DenseFilledTextField
|
||||||
|
fullWidth
|
||||||
|
value={code}
|
||||||
|
onChange={(e) => setCode(e.target.value)}
|
||||||
|
placeholder={t("setting.giftCodePlaceholder")}
|
||||||
|
slotProps={{
|
||||||
|
input: {
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<Button variant="contained" onClick={onRedeem} disabled={redeeming || !code.trim()}>
|
||||||
|
{t("setting.redeem")}
|
||||||
|
</Button>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RedeemCodeInput;
|
||||||
@ -0,0 +1,152 @@
|
|||||||
|
import { Button, Chip, Container, Grid2, Paper, Stack, Typography } from "@mui/material";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useSnackbar } from "notistack";
|
||||||
|
import { useEffect, useMemo, useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useSearchParams } from "react-router-dom";
|
||||||
|
import { getCredit, getShopSkus, purchaseSku } from "../../../api/api.ts";
|
||||||
|
import { CreditInfo, ShopSku } from "../../../api/user.ts";
|
||||||
|
import { useAppDispatch } from "../../../redux/hooks.ts";
|
||||||
|
import { sizeToString } from "../../../util/index.ts";
|
||||||
|
import { formatDuration } from "../../../util/datetime.ts";
|
||||||
|
import FacebookCircularProgress from "../../Common/CircularProgress.tsx";
|
||||||
|
import RedeemCodeInput from "../../Common/Form/RedeemCodeInput.tsx";
|
||||||
|
import Nothing from "../../Common/Nothing.tsx";
|
||||||
|
import ResponsiveTabs from "../../Common/ResponsiveTabs.tsx";
|
||||||
|
import PageContainer from "../PageContainer.tsx";
|
||||||
|
import PageHeader, { PageTabQuery } from "../PageHeader.tsx";
|
||||||
|
|
||||||
|
export enum ShopPageTab {
|
||||||
|
Membership = "membership",
|
||||||
|
Storage = "storage",
|
||||||
|
Redeem = "redeem",
|
||||||
|
}
|
||||||
|
|
||||||
|
const Shop = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
const [tab, setTab] = useState(searchParams.get(PageTabQuery) ?? ShopPageTab.Membership);
|
||||||
|
const [skus, setSkus] = useState<ShopSku[] | undefined>(undefined);
|
||||||
|
const [info, setInfo] = useState<CreditInfo | undefined>(undefined);
|
||||||
|
const [buying, setBuying] = useState<string | undefined>(undefined);
|
||||||
|
|
||||||
|
const loadInfo = () => {
|
||||||
|
dispatch(getCredit()).then((res) => setInfo(res));
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch(getShopSkus()).then((res) => setSkus(res));
|
||||||
|
loadInfo();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const tabs = useMemo(
|
||||||
|
() => [
|
||||||
|
{ label: t("application:shop.memberships"), value: ShopPageTab.Membership },
|
||||||
|
{ label: t("application:shop.storagePacks"), value: ShopPageTab.Storage },
|
||||||
|
{ label: t("application:shop.redeem"), value: ShopPageTab.Redeem },
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const filtered = useMemo(
|
||||||
|
() =>
|
||||||
|
(skus ?? []).filter((s) =>
|
||||||
|
tab === ShopPageTab.Membership ? s.type === "group" : s.type === "storage",
|
||||||
|
),
|
||||||
|
[skus, tab],
|
||||||
|
);
|
||||||
|
|
||||||
|
const onPurchase = (s: ShopSku) => {
|
||||||
|
setBuying(s.id);
|
||||||
|
dispatch(purchaseSku(s.id))
|
||||||
|
.then((res) => {
|
||||||
|
setInfo(res);
|
||||||
|
enqueueSnackbar(t("shop.purchased", { name: s.name }), { variant: "success" });
|
||||||
|
})
|
||||||
|
.finally(() => setBuying(undefined));
|
||||||
|
};
|
||||||
|
|
||||||
|
const skuSubtitle = (s: ShopSku) => {
|
||||||
|
const parts = [
|
||||||
|
s.type === "storage" ? sizeToString(s.amount) : s.group,
|
||||||
|
s.duration > 0 ? formatDuration(dayjs.duration(s.duration, "seconds")) : t("shop.permanent"),
|
||||||
|
];
|
||||||
|
return parts.filter(Boolean).join(" · ");
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer>
|
||||||
|
<Container maxWidth="lg">
|
||||||
|
<PageHeader
|
||||||
|
title={t("application:navbar.shop")}
|
||||||
|
secondaryAction={
|
||||||
|
info ? <Chip variant="outlined" label={t("shop.balance", { credits: info.credits })} /> : undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<ResponsiveTabs value={tab} onChange={(_e, v) => setTab(v)} tabs={tabs} />
|
||||||
|
{tab === ShopPageTab.Redeem && (
|
||||||
|
<Paper variant="outlined" sx={{ p: 2, maxWidth: 480 }}>
|
||||||
|
<Typography variant="subtitle2" gutterBottom>
|
||||||
|
{t("setting.redeemGiftCode")}
|
||||||
|
</Typography>
|
||||||
|
<RedeemCodeInput onRedeemed={loadInfo} />
|
||||||
|
</Paper>
|
||||||
|
)}
|
||||||
|
{tab !== ShopPageTab.Redeem && skus === undefined && (
|
||||||
|
<Grid2 container sx={{ pt: 10, justifyContent: "center" }}>
|
||||||
|
<FacebookCircularProgress />
|
||||||
|
</Grid2>
|
||||||
|
)}
|
||||||
|
{tab !== ShopPageTab.Redeem && skus !== undefined && filtered.length === 0 && (
|
||||||
|
<Nothing primary={t("shop.noProducts")} />
|
||||||
|
)}
|
||||||
|
{tab !== ShopPageTab.Redeem && skus !== undefined && filtered.length > 0 && (
|
||||||
|
<Grid2 container spacing={2} sx={{ pt: 2 }}>
|
||||||
|
{filtered.map((s) => (
|
||||||
|
<Grid2 key={s.id} size={{ xs: 12, sm: 6, md: 4 }}>
|
||||||
|
<Paper variant="outlined" sx={{ p: 2, height: "100%" }}>
|
||||||
|
<Stack spacing={1.5} sx={{ height: "100%" }}>
|
||||||
|
<Stack direction="row" spacing={1} alignItems="center">
|
||||||
|
<Typography variant="subtitle1" sx={{ flexGrow: 1 }}>
|
||||||
|
{s.name}
|
||||||
|
</Typography>
|
||||||
|
{s.label && <Chip size="small" color="primary" label={s.label} />}
|
||||||
|
</Stack>
|
||||||
|
<Typography variant="body2" color="text.secondary">
|
||||||
|
{skuSubtitle(s)}
|
||||||
|
</Typography>
|
||||||
|
{s.des && (
|
||||||
|
<Stack spacing={0.5} sx={{ flexGrow: 1 }}>
|
||||||
|
{s.des
|
||||||
|
.split("\n")
|
||||||
|
.filter((l) => l.trim())
|
||||||
|
.map((l, i) => (
|
||||||
|
<Typography key={i} variant="body2" color="text.secondary">
|
||||||
|
{l}
|
||||||
|
</Typography>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
disabled={s.points == null || buying === s.id || (info != null && info.credits < s.points)}
|
||||||
|
onClick={() => onPurchase(s)}
|
||||||
|
>
|
||||||
|
{s.points != null
|
||||||
|
? t("shop.buyWithPoints", { points: s.points })
|
||||||
|
: t("shop.pointsUnavailable")}
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
</Grid2>
|
||||||
|
))}
|
||||||
|
</Grid2>
|
||||||
|
)}
|
||||||
|
</Container>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Shop;
|
||||||
Loading…
Reference in new issue