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