feat: 更新用户、订单、媒体资产和租户模型,添加新的字段类型和结构体

This commit is contained in:
2025-12-29 12:01:22 +08:00
parent 0d0aee87b1
commit d648a1e45b
13 changed files with 141 additions and 92 deletions

View File

@@ -48,8 +48,9 @@ func (s *user) LoginWithOTP(ctx context.Context, phone, otp string) (*auth_dto.L
Username: phone, // 默认用户名 = 手机号 Username: phone, // 默认用户名 = 手机号
Password: "", // 免密登录 Password: "", // 免密登录
Nickname: "User_" + phone[len(phone)-4:], Nickname: "User_" + phone[len(phone)-4:],
Status: string(consts.UserStatusVerified), // 默认已审核?需确认业务逻辑 Status: consts.UserStatusVerified, // 默认已审核
Roles: types.Array[consts.Role]{consts.RoleUser}, Roles: types.Array[consts.Role]{consts.RoleUser},
Gender: consts.GenderSecret, // 默认性别
} }
if err := query.Create(u); err != nil { if err := query.Create(u); err != nil {
return nil, errorx.ErrDatabaseError.WithMsg("创建用户失败") return nil, errorx.ErrDatabaseError.WithMsg("创建用户失败")
@@ -60,7 +61,7 @@ func (s *user) LoginWithOTP(ctx context.Context, phone, otp string) (*auth_dto.L
} }
// 3. 检查状态 // 3. 检查状态
if u.Status == string(consts.UserStatusBanned) { if u.Status == consts.UserStatusBanned {
return nil, errorx.ErrAccountDisabled return nil, errorx.ErrAccountDisabled
} }
@@ -182,7 +183,7 @@ func (s *user) toAuthUserDTO(u *models.User) *auth_dto.User {
Phone: u.Phone, Phone: u.Phone,
Nickname: u.Nickname, Nickname: u.Nickname,
Avatar: u.Avatar, Avatar: u.Avatar,
Gender: consts.Gender(u.Gender), Gender: u.Gender, // Direct assignment, types match
Bio: u.Bio, Bio: u.Bio,
Balance: float64(u.Balance) / 100.0, Balance: float64(u.Balance) / 100.0,
Points: u.Points, Points: u.Points,

View File

@@ -14,19 +14,30 @@ field_type:
users: users:
gender: consts.Gender gender: consts.Gender
roles: types.Array[consts.Role] roles: types.Array[consts.Role]
location: types.JSONType[fields.UserLocation]
status: consts.UserStatus
contents: contents:
status: consts.ContentStatus status: consts.ContentStatus
visibility: consts.ContentVisibility visibility: consts.ContentVisibility
genre: string # genre is varchar(64) but no enum defined yet? genre: string
tags: types.JSONSlice[string]
content_prices: content_prices:
currency: consts.Currency currency: consts.Currency
discount_type: consts.DiscountType discount_type: consts.DiscountType
orders: orders:
status: consts.OrderStatus status: consts.OrderStatus
type: consts.OrderType type: consts.OrderType
snapshot: types.JSONType[fields.OrdersSnapshot]
order_items:
snapshot: types.JSONType[fields.OrderItemsSnapshot]
tenants: tenants:
status: consts.TenantStatus status: consts.TenantStatus
config: types.JSONType[fields.TenantConfig]
tenant_users: tenant_users:
role: types.Array[consts.TenantUserRole] role: types.Array[consts.TenantUserRole]
# status: consts.UserStatus # Skipping status for now to avoid mismatch 'active' vs 'verified' without enum update media_assets:
meta: types.JSONType[fields.MediaAssetMeta]
type: consts.MediaAssetType
status: consts.MediaAssetStatus
variant: consts.MediaAssetVariant
field_relate: field_relate:

View File

@@ -0,0 +1,13 @@
package fields
// MediaAssetMeta 媒体资源元数据
type MediaAssetMeta struct {
Hash string `json:"hash,omitempty"`
Duration float64 `json:"duration,omitempty"` // 秒
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
Bitrate int `json:"bitrate,omitempty"` // bps
Codec string `json:"codec,omitempty"`
Format string `json:"format,omitempty"`
Size int64 `json:"size,omitempty"` // 字节
}

View File

@@ -0,0 +1,7 @@
package fields
// TenantConfig 租户配置
type TenantConfig struct {
Theme string `json:"theme,omitempty"`
Features []string `json:"features,omitempty"`
}

View File

@@ -0,0 +1,9 @@
package fields
// UserLocation 用户位置信息
type UserLocation struct {
Province string `json:"province"`
City string `json:"city"`
District string `json:"district,omitempty"`
Address string `json:"address,omitempty"`
}

View File

@@ -30,7 +30,7 @@ type Content struct {
PreviewDownloadable bool `gorm:"column:preview_downloadable;type:boolean" json:"preview_downloadable"` PreviewDownloadable bool `gorm:"column:preview_downloadable;type:boolean" json:"preview_downloadable"`
PublishedAt time.Time `gorm:"column:published_at;type:timestamp with time zone" json:"published_at"` PublishedAt time.Time `gorm:"column:published_at;type:timestamp with time zone" json:"published_at"`
Summary string `gorm:"column:summary;type:character varying(256)" json:"summary"` Summary string `gorm:"column:summary;type:character varying(256)" json:"summary"`
Tags types.JSON `gorm:"column:tags;type:jsonb;default:[]" json:"tags"` Tags types.JSONSlice[string] `gorm:"column:tags;type:jsonb;default:[]" json:"tags"`
Body string `gorm:"column:body;type:text" json:"body"` Body string `gorm:"column:body;type:text" json:"body"`
Genre string `gorm:"column:genre;type:character varying(64)" json:"genre"` Genre string `gorm:"column:genre;type:character varying(64)" json:"genre"`
Views int32 `gorm:"column:views;type:integer" json:"views"` Views int32 `gorm:"column:views;type:integer" json:"views"`

View File

@@ -8,6 +8,9 @@ import (
"context" "context"
"time" "time"
"quyun/v2/database/fields"
"quyun/v2/pkg/consts"
"go.ipao.vip/gen" "go.ipao.vip/gen"
"go.ipao.vip/gen/types" "go.ipao.vip/gen/types"
"gorm.io/gorm" "gorm.io/gorm"
@@ -20,13 +23,13 @@ type MediaAsset struct {
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"` ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null" json:"tenant_id"` TenantID int64 `gorm:"column:tenant_id;type:bigint;not null" json:"tenant_id"`
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"` UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
Type string `gorm:"column:type;type:character varying(32);default:video" json:"type"` Type consts.MediaAssetType `gorm:"column:type;type:character varying(32);default:video" json:"type"`
Status string `gorm:"column:status;type:character varying(32);default:uploaded" json:"status"` Status consts.MediaAssetStatus `gorm:"column:status;type:character varying(32);default:uploaded" json:"status"`
Provider string `gorm:"column:provider;type:character varying(64);not null" json:"provider"` Provider string `gorm:"column:provider;type:character varying(64);not null" json:"provider"`
Bucket string `gorm:"column:bucket;type:character varying(128);not null" json:"bucket"` Bucket string `gorm:"column:bucket;type:character varying(128);not null" json:"bucket"`
ObjectKey string `gorm:"column:object_key;type:character varying(512);not null" json:"object_key"` ObjectKey string `gorm:"column:object_key;type:character varying(512);not null" json:"object_key"`
Meta types.JSON `gorm:"column:meta;type:jsonb;default:{}" json:"meta"` Meta types.JSONType[fields.MediaAssetMeta] `gorm:"column:meta;type:jsonb;default:{}" json:"meta"`
Variant string `gorm:"column:variant;type:character varying(32);default:main" json:"variant"` Variant consts.MediaAssetVariant `gorm:"column:variant;type:character varying(32);default:main" json:"variant"`
SourceAssetID int64 `gorm:"column:source_asset_id;type:bigint" json:"source_asset_id"` SourceAssetID int64 `gorm:"column:source_asset_id;type:bigint" json:"source_asset_id"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;default:now()" json:"created_at"` CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;default:now()" json:"updated_at"` UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;default:now()" json:"updated_at"`

View File

@@ -28,13 +28,13 @@ func newMediaAsset(db *gorm.DB, opts ...gen.DOOption) mediaAssetQuery {
_mediaAssetQuery.ID = field.NewInt64(tableName, "id") _mediaAssetQuery.ID = field.NewInt64(tableName, "id")
_mediaAssetQuery.TenantID = field.NewInt64(tableName, "tenant_id") _mediaAssetQuery.TenantID = field.NewInt64(tableName, "tenant_id")
_mediaAssetQuery.UserID = field.NewInt64(tableName, "user_id") _mediaAssetQuery.UserID = field.NewInt64(tableName, "user_id")
_mediaAssetQuery.Type = field.NewString(tableName, "type") _mediaAssetQuery.Type = field.NewField(tableName, "type")
_mediaAssetQuery.Status = field.NewString(tableName, "status") _mediaAssetQuery.Status = field.NewField(tableName, "status")
_mediaAssetQuery.Provider = field.NewString(tableName, "provider") _mediaAssetQuery.Provider = field.NewString(tableName, "provider")
_mediaAssetQuery.Bucket = field.NewString(tableName, "bucket") _mediaAssetQuery.Bucket = field.NewString(tableName, "bucket")
_mediaAssetQuery.ObjectKey = field.NewString(tableName, "object_key") _mediaAssetQuery.ObjectKey = field.NewString(tableName, "object_key")
_mediaAssetQuery.Meta = field.NewJSONB(tableName, "meta") _mediaAssetQuery.Meta = field.NewJSONB(tableName, "meta")
_mediaAssetQuery.Variant = field.NewString(tableName, "variant") _mediaAssetQuery.Variant = field.NewField(tableName, "variant")
_mediaAssetQuery.SourceAssetID = field.NewInt64(tableName, "source_asset_id") _mediaAssetQuery.SourceAssetID = field.NewInt64(tableName, "source_asset_id")
_mediaAssetQuery.CreatedAt = field.NewTime(tableName, "created_at") _mediaAssetQuery.CreatedAt = field.NewTime(tableName, "created_at")
_mediaAssetQuery.UpdatedAt = field.NewTime(tableName, "updated_at") _mediaAssetQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
@@ -52,13 +52,13 @@ type mediaAssetQuery struct {
ID field.Int64 ID field.Int64
TenantID field.Int64 TenantID field.Int64
UserID field.Int64 UserID field.Int64
Type field.String Type field.Field
Status field.String Status field.Field
Provider field.String Provider field.String
Bucket field.String Bucket field.String
ObjectKey field.String ObjectKey field.String
Meta field.JSONB Meta field.JSONB
Variant field.String Variant field.Field
SourceAssetID field.Int64 SourceAssetID field.Int64
CreatedAt field.Time CreatedAt field.Time
UpdatedAt field.Time UpdatedAt field.Time
@@ -82,13 +82,13 @@ func (m *mediaAssetQuery) updateTableName(table string) *mediaAssetQuery {
m.ID = field.NewInt64(table, "id") m.ID = field.NewInt64(table, "id")
m.TenantID = field.NewInt64(table, "tenant_id") m.TenantID = field.NewInt64(table, "tenant_id")
m.UserID = field.NewInt64(table, "user_id") m.UserID = field.NewInt64(table, "user_id")
m.Type = field.NewString(table, "type") m.Type = field.NewField(table, "type")
m.Status = field.NewString(table, "status") m.Status = field.NewField(table, "status")
m.Provider = field.NewString(table, "provider") m.Provider = field.NewString(table, "provider")
m.Bucket = field.NewString(table, "bucket") m.Bucket = field.NewString(table, "bucket")
m.ObjectKey = field.NewString(table, "object_key") m.ObjectKey = field.NewString(table, "object_key")
m.Meta = field.NewJSONB(table, "meta") m.Meta = field.NewJSONB(table, "meta")
m.Variant = field.NewString(table, "variant") m.Variant = field.NewField(table, "variant")
m.SourceAssetID = field.NewInt64(table, "source_asset_id") m.SourceAssetID = field.NewInt64(table, "source_asset_id")
m.CreatedAt = field.NewTime(table, "created_at") m.CreatedAt = field.NewTime(table, "created_at")
m.UpdatedAt = field.NewTime(table, "updated_at") m.UpdatedAt = field.NewTime(table, "updated_at")

View File

@@ -8,6 +8,8 @@ import (
"context" "context"
"time" "time"
"quyun/v2/database/fields"
"go.ipao.vip/gen" "go.ipao.vip/gen"
"go.ipao.vip/gen/types" "go.ipao.vip/gen/types"
) )
@@ -23,7 +25,7 @@ type OrderItem struct {
ContentID int64 `gorm:"column:content_id;type:bigint;not null" json:"content_id"` ContentID int64 `gorm:"column:content_id;type:bigint;not null" json:"content_id"`
ContentUserID int64 `gorm:"column:content_user_id;type:bigint;not null" json:"content_user_id"` ContentUserID int64 `gorm:"column:content_user_id;type:bigint;not null" json:"content_user_id"`
AmountPaid int64 `gorm:"column:amount_paid;type:bigint;not null" json:"amount_paid"` AmountPaid int64 `gorm:"column:amount_paid;type:bigint;not null" json:"amount_paid"`
Snapshot types.JSON `gorm:"column:snapshot;type:jsonb;default:{}" json:"snapshot"` Snapshot types.JSONType[fields.OrderItemsSnapshot] `gorm:"column:snapshot;type:jsonb;default:{}" json:"snapshot"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;default:now()" json:"created_at"` CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;default:now()" json:"updated_at"` UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;default:now()" json:"updated_at"`
} }

View File

@@ -8,6 +8,7 @@ import (
"context" "context"
"time" "time"
"quyun/v2/database/fields"
"quyun/v2/pkg/consts" "quyun/v2/pkg/consts"
"go.ipao.vip/gen" "go.ipao.vip/gen"
@@ -27,7 +28,7 @@ type Order struct {
AmountOriginal int64 `gorm:"column:amount_original;type:bigint;not null" json:"amount_original"` AmountOriginal int64 `gorm:"column:amount_original;type:bigint;not null" json:"amount_original"`
AmountDiscount int64 `gorm:"column:amount_discount;type:bigint;not null" json:"amount_discount"` AmountDiscount int64 `gorm:"column:amount_discount;type:bigint;not null" json:"amount_discount"`
AmountPaid int64 `gorm:"column:amount_paid;type:bigint;not null" json:"amount_paid"` AmountPaid int64 `gorm:"column:amount_paid;type:bigint;not null" json:"amount_paid"`
Snapshot types.JSON `gorm:"column:snapshot;type:jsonb;default:{}" json:"snapshot"` Snapshot types.JSONType[fields.OrdersSnapshot] `gorm:"column:snapshot;type:jsonb;default:{}" json:"snapshot"`
IdempotencyKey string `gorm:"column:idempotency_key;type:character varying(128);not null" json:"idempotency_key"` IdempotencyKey string `gorm:"column:idempotency_key;type:character varying(128);not null" json:"idempotency_key"`
PaidAt time.Time `gorm:"column:paid_at;type:timestamp with time zone" json:"paid_at"` PaidAt time.Time `gorm:"column:paid_at;type:timestamp with time zone" json:"paid_at"`
RefundedAt time.Time `gorm:"column:refunded_at;type:timestamp with time zone" json:"refunded_at"` RefundedAt time.Time `gorm:"column:refunded_at;type:timestamp with time zone" json:"refunded_at"`

View File

@@ -8,6 +8,7 @@ import (
"context" "context"
"time" "time"
"quyun/v2/database/fields"
"quyun/v2/pkg/consts" "quyun/v2/pkg/consts"
"go.ipao.vip/gen" "go.ipao.vip/gen"
@@ -24,7 +25,7 @@ type Tenant struct {
UUID types.UUID `gorm:"column:uuid;type:uuid;not null" json:"uuid"` UUID types.UUID `gorm:"column:uuid;type:uuid;not null" json:"uuid"`
Name string `gorm:"column:name;type:character varying(128);not null" json:"name"` Name string `gorm:"column:name;type:character varying(128);not null" json:"name"`
Status consts.TenantStatus `gorm:"column:status;type:character varying(64);not null" json:"status"` Status consts.TenantStatus `gorm:"column:status;type:character varying(64);not null" json:"status"`
Config types.JSON `gorm:"column:config;type:jsonb;default:{}" json:"config"` Config types.JSONType[fields.TenantConfig] `gorm:"column:config;type:jsonb;default:{}" json:"config"`
ExpiredAt time.Time `gorm:"column:expired_at;type:timestamp with time zone" json:"expired_at"` ExpiredAt time.Time `gorm:"column:expired_at;type:timestamp with time zone" json:"expired_at"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;default:now()" json:"created_at"` CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;default:now()" json:"updated_at"` UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;default:now()" json:"updated_at"`

View File

@@ -8,6 +8,7 @@ import (
"context" "context"
"time" "time"
"quyun/v2/database/fields"
"quyun/v2/pkg/consts" "quyun/v2/pkg/consts"
"go.ipao.vip/gen" "go.ipao.vip/gen"
@@ -23,7 +24,7 @@ type User struct {
Username string `gorm:"column:username;type:character varying(255);not null" json:"username"` Username string `gorm:"column:username;type:character varying(255);not null" json:"username"`
Password string `gorm:"column:password;type:character varying(255);not null" json:"password"` Password string `gorm:"column:password;type:character varying(255);not null" json:"password"`
Roles types.Array[consts.Role] `gorm:"column:roles;type:text[];default:{user}" json:"roles"` Roles types.Array[consts.Role] `gorm:"column:roles;type:text[];default:{user}" json:"roles"`
Status string `gorm:"column:status;type:character varying(50);default:active" json:"status"` Status consts.UserStatus `gorm:"column:status;type:character varying(50);default:active" json:"status"`
Metas types.JSON `gorm:"column:metas;type:jsonb;default:{}" json:"metas"` Metas types.JSON `gorm:"column:metas;type:jsonb;default:{}" json:"metas"`
Balance int64 `gorm:"column:balance;type:bigint" json:"balance"` Balance int64 `gorm:"column:balance;type:bigint" json:"balance"`
BalanceFrozen int64 `gorm:"column:balance_frozen;type:bigint" json:"balance_frozen"` BalanceFrozen int64 `gorm:"column:balance_frozen;type:bigint" json:"balance_frozen"`
@@ -33,7 +34,7 @@ type User struct {
Gender consts.Gender `gorm:"column:gender;type:character varying(32);default:secret" json:"gender"` Gender consts.Gender `gorm:"column:gender;type:character varying(32);default:secret" json:"gender"`
Bio string `gorm:"column:bio;type:character varying(512)" json:"bio"` Bio string `gorm:"column:bio;type:character varying(512)" json:"bio"`
Birthday types.Date `gorm:"column:birthday;type:date" json:"birthday"` Birthday types.Date `gorm:"column:birthday;type:date" json:"birthday"`
Location types.JSON `gorm:"column:location;type:jsonb;default:{}" json:"location"` Location types.JSONType[fields.UserLocation] `gorm:"column:location;type:jsonb;default:{}" json:"location"`
Points int64 `gorm:"column:points;type:bigint" json:"points"` Points int64 `gorm:"column:points;type:bigint" json:"points"`
Phone string `gorm:"column:phone;type:character varying(32)" json:"phone"` Phone string `gorm:"column:phone;type:character varying(32)" json:"phone"`
IsRealNameVerified bool `gorm:"column:is_real_name_verified;type:boolean" json:"is_real_name_verified"` IsRealNameVerified bool `gorm:"column:is_real_name_verified;type:boolean" json:"is_real_name_verified"`

View File

@@ -29,7 +29,7 @@ func newUser(db *gorm.DB, opts ...gen.DOOption) userQuery {
_userQuery.Username = field.NewString(tableName, "username") _userQuery.Username = field.NewString(tableName, "username")
_userQuery.Password = field.NewString(tableName, "password") _userQuery.Password = field.NewString(tableName, "password")
_userQuery.Roles = field.NewArray(tableName, "roles") _userQuery.Roles = field.NewArray(tableName, "roles")
_userQuery.Status = field.NewString(tableName, "status") _userQuery.Status = field.NewField(tableName, "status")
_userQuery.Metas = field.NewJSONB(tableName, "metas") _userQuery.Metas = field.NewJSONB(tableName, "metas")
_userQuery.Balance = field.NewInt64(tableName, "balance") _userQuery.Balance = field.NewInt64(tableName, "balance")
_userQuery.BalanceFrozen = field.NewInt64(tableName, "balance_frozen") _userQuery.BalanceFrozen = field.NewInt64(tableName, "balance_frozen")
@@ -60,7 +60,7 @@ type userQuery struct {
Username field.String Username field.String
Password field.String Password field.String
Roles field.Array Roles field.Array
Status field.String Status field.Field
Metas field.JSONB Metas field.JSONB
Balance field.Int64 Balance field.Int64
BalanceFrozen field.Int64 BalanceFrozen field.Int64
@@ -97,7 +97,7 @@ func (u *userQuery) updateTableName(table string) *userQuery {
u.Username = field.NewString(table, "username") u.Username = field.NewString(table, "username")
u.Password = field.NewString(table, "password") u.Password = field.NewString(table, "password")
u.Roles = field.NewArray(table, "roles") u.Roles = field.NewArray(table, "roles")
u.Status = field.NewString(table, "status") u.Status = field.NewField(table, "status")
u.Metas = field.NewJSONB(table, "metas") u.Metas = field.NewJSONB(table, "metas")
u.Balance = field.NewInt64(table, "balance") u.Balance = field.NewInt64(table, "balance")
u.BalanceFrozen = field.NewInt64(table, "balance_frozen") u.BalanceFrozen = field.NewInt64(table, "balance_frozen")