feat: 移除“租户管理员为用户充值 / 每租户一套余额”能力:余额统一为全局用户余额
This commit is contained in:
@@ -14,7 +14,7 @@ import (
|
||||
// - 查询/展示时可以先看 kind,再按需解析 data。
|
||||
// - 兼容历史数据:如果旧数据没有 kind/data,则按 legacy 处理(data = 原始 JSON)。
|
||||
type OrdersSnapshot struct {
|
||||
// Kind 快照类型:建议与订单类型对齐(例如 content_purchase / topup)。
|
||||
// Kind 快照类型:建议与订单类型对齐(例如 content_purchase)。
|
||||
Kind string `json:"kind"`
|
||||
// Data 具体快照数据(按 Kind 对应不同结构)。
|
||||
Data json.RawMessage `json:"data"`
|
||||
@@ -78,21 +78,3 @@ type OrdersContentPurchaseSnapshot struct {
|
||||
// PurchasePricingNotes 价格计算补充说明(可选,便于排查争议)。
|
||||
PurchasePricingNotes string `json:"purchase_pricing_notes,omitempty"`
|
||||
}
|
||||
|
||||
// OrdersTopupSnapshot 为“后台充值订单”的快照(用于审计与追责)。
|
||||
type OrdersTopupSnapshot struct {
|
||||
// OperatorUserID 充值操作人用户ID(租户管理员)。
|
||||
OperatorUserID int64 `json:"operator_user_id"`
|
||||
// TargetUserID 充值目标用户ID(租户成员)。
|
||||
TargetUserID int64 `json:"target_user_id"`
|
||||
// Amount 充值金额(分)。
|
||||
Amount int64 `json:"amount"`
|
||||
// Currency 币种:当前固定 CNY(金额单位为分)。
|
||||
Currency consts.Currency `json:"currency"`
|
||||
// Reason 充值原因(可选,强烈建议填写用于审计)。
|
||||
Reason string `json:"reason,omitempty"`
|
||||
// IdempotencyKey 幂等键(可选)。
|
||||
IdempotencyKey string `json:"idempotency_key,omitempty"`
|
||||
// TopupAt 充值时间(逻辑时间)。
|
||||
TopupAt time.Time `json:"topup_at"`
|
||||
}
|
||||
|
||||
@@ -10,9 +10,17 @@ CREATE TABLE IF NOT EXISTS users(
|
||||
roles text[] NOT NULL DEFAULT ARRAY['user'],
|
||||
status varchar(50) NOT NULL DEFAULT 'active',
|
||||
metas jsonb NOT NULL DEFAULT '{}',
|
||||
balance bigint NOT NULL DEFAULT 0,
|
||||
balance_frozen bigint NOT NULL DEFAULT 0,
|
||||
verified_at timestamptz
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN users.balance IS '全局可用余额:分/最小货币单位;用户在所有已加入租户内共享该余额;默认 0';
|
||||
COMMENT ON COLUMN users.balance_frozen IS '全局冻结余额:分/最小货币单位;用于下单冻结等;默认 0';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_users_balance ON users(balance);
|
||||
CREATE INDEX IF NOT EXISTS ix_users_balance_frozen ON users(balance_frozen);
|
||||
|
||||
-- +goose StatementEnd
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
|
||||
@@ -5,7 +5,6 @@ CREATE TABLE IF NOT EXISTS tenant_users(
|
||||
tenant_id bigint NOT NULL,
|
||||
user_id bigint NOT NULL,
|
||||
role TEXT[] NOT NULL DEFAULT ARRAY['member'],
|
||||
balance bigint NOT NULL DEFAULT 0,
|
||||
status varchar(50) NOT NULL DEFAULT 'active',
|
||||
created_at timestamptz NOT NULL DEFAULT NOW(),
|
||||
updated_at timestamptz NOT NULL DEFAULT NOW(),
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE tenant_users
|
||||
ADD COLUMN IF NOT EXISTS balance_frozen bigint NOT NULL DEFAULT 0;
|
||||
|
||||
-- tenant_users.balance_frozen:冻结余额(用于下单冻结、争议期等)
|
||||
COMMENT ON COLUMN tenant_users.balance_frozen IS '冻结余额:分/最小货币单位;下单冻结时从可用余额转入,最终扣款或回滚时转出;默认 0';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_tenant_users_tenant_balance_frozen ON tenant_users(tenant_id, balance_frozen);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS orders(
|
||||
id bigserial PRIMARY KEY,
|
||||
tenant_id bigint NOT NULL,
|
||||
@@ -29,12 +21,12 @@ CREATE TABLE IF NOT EXISTS orders(
|
||||
updated_at timestamptz NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- orders:订单主表(租户内购买/充值等业务单据)
|
||||
-- orders:订单主表(租户内购买等业务单据)
|
||||
COMMENT ON TABLE orders IS '订单:租户内的业务交易单据;记录成交金额快照、状态流转与退款信息;所有查询/写入必须限定 tenant_id';
|
||||
COMMENT ON COLUMN orders.id IS '主键ID:自增;用于关联订单明细、账本流水、权益等';
|
||||
COMMENT ON COLUMN orders.tenant_id IS '租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id';
|
||||
COMMENT ON COLUMN orders.user_id IS '用户ID:下单用户(buyer);余额扣款与权益归属以该 user_id 为准';
|
||||
COMMENT ON COLUMN orders.type IS '订单类型:content_purchase(购买内容)/topup(充值)等;当前默认 content_purchase';
|
||||
COMMENT ON COLUMN orders.type IS '订单类型:content_purchase(购买内容)等;当前默认 content_purchase';
|
||||
COMMENT ON COLUMN orders.status IS '订单状态:created/paid/refunding/refunded/canceled/failed;状态变更需与账本/权益保持一致';
|
||||
COMMENT ON COLUMN orders.currency IS '币种:当前固定 CNY;金额单位为分';
|
||||
COMMENT ON COLUMN orders.amount_original IS '原价金额:分;未折扣前金额(用于展示与对账)';
|
||||
@@ -103,12 +95,12 @@ CREATE TABLE IF NOT EXISTS tenant_ledgers(
|
||||
);
|
||||
|
||||
-- tenant_ledgers:租户内余额账本流水(必须可审计、可幂等)
|
||||
COMMENT ON TABLE tenant_ledgers IS '账本流水:记录租户内用户余额的每一次变化(充值/冻结/扣款/退款等);用于审计与对账回放';
|
||||
COMMENT ON TABLE tenant_ledgers IS '账本流水:记录租户内用户余额的每一次变化(冻结/扣款/退款/调账等);用于审计与对账回放';
|
||||
COMMENT ON COLUMN tenant_ledgers.id IS '主键ID:自增';
|
||||
COMMENT ON COLUMN tenant_ledgers.tenant_id IS '租户ID:多租户隔离关键字段;必须与 tenant_users.tenant_id 一致';
|
||||
COMMENT ON COLUMN tenant_ledgers.user_id IS '用户ID:余额账户归属用户;对应 tenant_users.user_id';
|
||||
COMMENT ON COLUMN tenant_ledgers.order_id IS '关联订单ID:购买/退款类流水应关联 orders.id;非订单类可为空';
|
||||
COMMENT ON COLUMN tenant_ledgers.type IS '流水类型:credit_topup/debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向';
|
||||
COMMENT ON COLUMN tenant_ledgers.type IS '流水类型:debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向';
|
||||
COMMENT ON COLUMN tenant_ledgers.amount IS '流水金额:分/最小货币单位;通常为正数,方向由 type 决定(由业务层约束)';
|
||||
COMMENT ON COLUMN tenant_ledgers.balance_before IS '变更前可用余额:用于审计与对账回放';
|
||||
COMMENT ON COLUMN tenant_ledgers.balance_after IS '变更后可用余额:用于审计与对账回放';
|
||||
@@ -143,8 +135,4 @@ DROP INDEX IF EXISTS ix_orders_tenant_status;
|
||||
DROP INDEX IF EXISTS ix_orders_tenant_user;
|
||||
DROP TABLE IF EXISTS orders;
|
||||
|
||||
DROP INDEX IF EXISTS ix_tenant_users_tenant_balance_frozen;
|
||||
ALTER TABLE tenant_users DROP COLUMN IF EXISTS balance_frozen;
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@ ALTER TABLE tenant_ledgers
|
||||
ADD COLUMN IF NOT EXISTS biz_ref_id bigint;
|
||||
|
||||
-- tenant_ledgers.operator_user_id:操作者(谁触发该流水)
|
||||
-- 用途:用于审计与风控追溯(例如后台代充值/代退款/调账等)。
|
||||
-- 用途:用于审计与风控追溯(例如后台代退款/调账等)。
|
||||
COMMENT ON COLUMN tenant_ledgers.operator_user_id IS '操作者用户ID:谁触发该流水(admin/buyer/system);用于审计与追责;可为空(历史数据或无法识别时)';
|
||||
|
||||
-- tenant_ledgers.biz_ref_type/biz_ref_id:业务引用(幂等与追溯)
|
||||
-- 用途:在 idempotency_key 之外提供结构化引用(例如 order/refund/topup 等),便于报表与按业务对象追溯。
|
||||
COMMENT ON COLUMN tenant_ledgers.biz_ref_type IS '业务引用类型:order/refund/topup/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键';
|
||||
-- 用途:在 idempotency_key 之外提供结构化引用(例如 order/refund 等),便于报表与按业务对象追溯。
|
||||
COMMENT ON COLUMN tenant_ledgers.biz_ref_type IS '业务引用类型:order/refund/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键';
|
||||
COMMENT ON COLUMN tenant_ledgers.biz_ref_id IS '业务引用ID:与 biz_ref_type 配合使用(例如 orders.id);用于对账与审计';
|
||||
|
||||
-- 索引:按操作者检索敏感操作流水(后台审计用)。
|
||||
@@ -38,4 +38,3 @@ ALTER TABLE tenant_ledgers
|
||||
DROP COLUMN IF EXISTS biz_ref_type,
|
||||
DROP COLUMN IF EXISTS operator_user_id;
|
||||
-- +goose StatementEnd
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- 清理“充值”遗留描述:当前项目已移除租户充值与 per-tenant 余额。
|
||||
|
||||
COMMENT ON COLUMN orders.type IS '订单类型:content_purchase(购买内容)等;当前默认 content_purchase';
|
||||
|
||||
COMMENT ON TABLE tenant_ledgers IS '账本流水:记录租户内用户余额的每一次变化(冻结/扣款/退款/调账等);用于审计与对账回放';
|
||||
COMMENT ON COLUMN tenant_ledgers.type IS '流水类型:debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向';
|
||||
|
||||
COMMENT ON COLUMN tenant_ledgers.operator_user_id IS '操作者用户ID:谁触发该流水(admin/buyer/system);用于审计与追责;可为空(历史数据或无法识别时)';
|
||||
COMMENT ON COLUMN tenant_ledgers.biz_ref_type IS '业务引用类型:order/refund/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键';
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
-- 新项目不需要依赖 Down 做历史回滚;保持与 Up 一致,避免引入已移除特性的遗留描述。
|
||||
COMMENT ON COLUMN orders.type IS '订单类型:content_purchase(购买内容)等;当前默认 content_purchase';
|
||||
|
||||
COMMENT ON TABLE tenant_ledgers IS '账本流水:记录租户内用户余额的每一次变化(冻结/扣款/退款/调账等);用于审计与对账回放';
|
||||
COMMENT ON COLUMN tenant_ledgers.type IS '流水类型:debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向';
|
||||
|
||||
COMMENT ON COLUMN tenant_ledgers.operator_user_id IS '操作者用户ID:谁触发该流水(admin/buyer/system);用于审计与追责;可为空(历史数据或无法识别时)';
|
||||
COMMENT ON COLUMN tenant_ledgers.biz_ref_type IS '业务引用类型:order/refund/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键';
|
||||
-- +goose StatementEnd
|
||||
@@ -28,8 +28,8 @@ type OrderItem struct {
|
||||
Snapshot types.JSONType[fields.OrderItemsSnapshot] `gorm:"column:snapshot;type:jsonb;not null;default:{};comment:内容快照:JSON;建议包含 title/price/discount 等,用于历史展示与审计" json:"snapshot"` // 内容快照:JSON;建议包含 title/price/discount 等,用于历史展示与审计
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now();comment:创建时间:默认 now()" json:"created_at"` // 创建时间:默认 now()
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now();comment:更新时间:默认 now()" json:"updated_at"` // 更新时间:默认 now()
|
||||
Content *Content `gorm:"foreignKey:ContentID;references:ID" json:"content,omitempty"`
|
||||
Order *Order `gorm:"foreignKey:OrderID;references:ID" json:"order,omitempty"`
|
||||
Content *Content `gorm:"foreignKey:ContentID;references:ID" json:"content,omitempty"`
|
||||
}
|
||||
|
||||
// Quick operations without importing query package
|
||||
|
||||
@@ -35,18 +35,18 @@ func newOrderItem(db *gorm.DB, opts ...gen.DOOption) orderItemQuery {
|
||||
_orderItemQuery.Snapshot = field.NewJSONB(tableName, "snapshot")
|
||||
_orderItemQuery.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_orderItemQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
_orderItemQuery.Content = orderItemQueryBelongsToContent{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Content", "Content"),
|
||||
}
|
||||
|
||||
_orderItemQuery.Order = orderItemQueryBelongsToOrder{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Order", "Order"),
|
||||
}
|
||||
|
||||
_orderItemQuery.Content = orderItemQueryBelongsToContent{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Content", "Content"),
|
||||
}
|
||||
|
||||
_orderItemQuery.fillFieldMap()
|
||||
|
||||
return _orderItemQuery
|
||||
@@ -66,9 +66,9 @@ type orderItemQuery struct {
|
||||
Snapshot field.JSONB // 内容快照:JSON;建议包含 title/price/discount 等,用于历史展示与审计
|
||||
CreatedAt field.Time // 创建时间:默认 now()
|
||||
UpdatedAt field.Time // 更新时间:默认 now()
|
||||
Content orderItemQueryBelongsToContent
|
||||
Order orderItemQueryBelongsToOrder
|
||||
|
||||
Order orderItemQueryBelongsToOrder
|
||||
Content orderItemQueryBelongsToContent
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@@ -143,101 +143,20 @@ func (o *orderItemQuery) fillFieldMap() {
|
||||
|
||||
func (o orderItemQuery) clone(db *gorm.DB) orderItemQuery {
|
||||
o.orderItemQueryDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
o.Content.db = db.Session(&gorm.Session{Initialized: true})
|
||||
o.Content.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
o.Order.db = db.Session(&gorm.Session{Initialized: true})
|
||||
o.Order.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
o.Content.db = db.Session(&gorm.Session{Initialized: true})
|
||||
o.Content.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
return o
|
||||
}
|
||||
|
||||
func (o orderItemQuery) replaceDB(db *gorm.DB) orderItemQuery {
|
||||
o.orderItemQueryDo.ReplaceDB(db)
|
||||
o.Content.db = db.Session(&gorm.Session{})
|
||||
o.Order.db = db.Session(&gorm.Session{})
|
||||
o.Content.db = db.Session(&gorm.Session{})
|
||||
return o
|
||||
}
|
||||
|
||||
type orderItemQueryBelongsToContent struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) Where(conds ...field.Expr) *orderItemQueryBelongsToContent {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) WithContext(ctx context.Context) *orderItemQueryBelongsToContent {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) Session(session *gorm.Session) *orderItemQueryBelongsToContent {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) Model(m *OrderItem) *orderItemQueryBelongsToContentTx {
|
||||
return &orderItemQueryBelongsToContentTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) Unscoped() *orderItemQueryBelongsToContent {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type orderItemQueryBelongsToContentTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Find() (result *Content, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Append(values ...*Content) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Replace(values ...*Content) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Delete(values ...*Content) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Unscoped() *orderItemQueryBelongsToContentTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type orderItemQueryBelongsToOrder struct {
|
||||
db *gorm.DB
|
||||
|
||||
@@ -319,6 +238,87 @@ func (a orderItemQueryBelongsToOrderTx) Unscoped() *orderItemQueryBelongsToOrder
|
||||
return &a
|
||||
}
|
||||
|
||||
type orderItemQueryBelongsToContent struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) Where(conds ...field.Expr) *orderItemQueryBelongsToContent {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) WithContext(ctx context.Context) *orderItemQueryBelongsToContent {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) Session(session *gorm.Session) *orderItemQueryBelongsToContent {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) Model(m *OrderItem) *orderItemQueryBelongsToContentTx {
|
||||
return &orderItemQueryBelongsToContentTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContent) Unscoped() *orderItemQueryBelongsToContent {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type orderItemQueryBelongsToContentTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Find() (result *Content, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Append(values ...*Content) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Replace(values ...*Content) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Delete(values ...*Content) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a orderItemQueryBelongsToContentTx) Unscoped() *orderItemQueryBelongsToContentTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type orderItemQueryDo struct{ gen.DO }
|
||||
|
||||
func (o orderItemQueryDo) Debug() *orderItemQueryDo {
|
||||
|
||||
@@ -22,7 +22,7 @@ type Order struct {
|
||||
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true;comment:主键ID:自增;用于关联订单明细、账本流水、权益等" json:"id"` // 主键ID:自增;用于关联订单明细、账本流水、权益等
|
||||
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null;comment:租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id" json:"tenant_id"` // 租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id
|
||||
UserID int64 `gorm:"column:user_id;type:bigint;not null;comment:用户ID:下单用户(buyer);余额扣款与权益归属以该 user_id 为准" json:"user_id"` // 用户ID:下单用户(buyer);余额扣款与权益归属以该 user_id 为准
|
||||
Type consts.OrderType `gorm:"column:type;type:character varying(32);not null;default:content_purchase;comment:订单类型:content_purchase(购买内容)/topup(充值)等;当前默认 content_purchase" json:"type"` // 订单类型:content_purchase(购买内容)/topup(充值)等;当前默认 content_purchase
|
||||
Type consts.OrderType `gorm:"column:type;type:character varying(32);not null;default:content_purchase;comment:订单类型:content_purchase(购买内容)等;当前默认 content_purchase" json:"type"` // 订单类型:content_purchase(购买内容)等;当前默认 content_purchase
|
||||
Status consts.OrderStatus `gorm:"column:status;type:character varying(32);not null;default:created;comment:订单状态:created/paid/refunding/refunded/canceled/failed;状态变更需与账本/权益保持一致" json:"status"` // 订单状态:created/paid/refunding/refunded/canceled/failed;状态变更需与账本/权益保持一致
|
||||
Currency consts.Currency `gorm:"column:currency;type:character varying(16);not null;default:CNY;comment:币种:当前固定 CNY;金额单位为分" json:"currency"` // 币种:当前固定 CNY;金额单位为分
|
||||
AmountOriginal int64 `gorm:"column:amount_original;type:bigint;not null;comment:原价金额:分;未折扣前金额(用于展示与对账)" json:"amount_original"` // 原价金额:分;未折扣前金额(用于展示与对账)
|
||||
|
||||
@@ -61,7 +61,7 @@ type orderQuery struct {
|
||||
ID field.Int64 // 主键ID:自增;用于关联订单明细、账本流水、权益等
|
||||
TenantID field.Int64 // 租户ID:多租户隔离关键字段;所有查询/写入必须限定 tenant_id
|
||||
UserID field.Int64 // 用户ID:下单用户(buyer);余额扣款与权益归属以该 user_id 为准
|
||||
Type field.Field // 订单类型:content_purchase(购买内容)/topup(充值)等;当前默认 content_purchase
|
||||
Type field.Field // 订单类型:content_purchase(购买内容)等;当前默认 content_purchase
|
||||
Status field.Field // 订单状态:created/paid/refunding/refunded/canceled/failed;状态变更需与账本/权益保持一致
|
||||
Currency field.Field // 币种:当前固定 CNY;金额单位为分
|
||||
AmountOriginal field.Int64 // 原价金额:分;未折扣前金额(用于展示与对账)
|
||||
|
||||
@@ -17,23 +17,23 @@ const TableNameTenantLedger = "tenant_ledgers"
|
||||
|
||||
// TenantLedger mapped from table <tenant_ledgers>
|
||||
type TenantLedger struct {
|
||||
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true;comment:主键ID:自增" json:"id"` // 主键ID:自增
|
||||
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null;comment:租户ID:多租户隔离关键字段;必须与 tenant_users.tenant_id 一致" json:"tenant_id"` // 租户ID:多租户隔离关键字段;必须与 tenant_users.tenant_id 一致
|
||||
UserID int64 `gorm:"column:user_id;type:bigint;not null;comment:用户ID:余额账户归属用户;对应 tenant_users.user_id" json:"user_id"` // 用户ID:余额账户归属用户;对应 tenant_users.user_id
|
||||
OrderID int64 `gorm:"column:order_id;type:bigint;comment:关联订单ID:购买/退款类流水应关联 orders.id;非订单类可为空" json:"order_id"` // 关联订单ID:购买/退款类流水应关联 orders.id;非订单类可为空
|
||||
Type consts.TenantLedgerType `gorm:"column:type;type:character varying(32);not null;comment:流水类型:credit_topup/debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向" json:"type"` // 流水类型:credit_topup/debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向
|
||||
Amount int64 `gorm:"column:amount;type:bigint;not null;comment:流水金额:分/最小货币单位;通常为正数,方向由 type 决定(由业务层约束)" json:"amount"` // 流水金额:分/最小货币单位;通常为正数,方向由 type 决定(由业务层约束)
|
||||
BalanceBefore int64 `gorm:"column:balance_before;type:bigint;not null;comment:变更前可用余额:用于审计与对账回放" json:"balance_before"` // 变更前可用余额:用于审计与对账回放
|
||||
BalanceAfter int64 `gorm:"column:balance_after;type:bigint;not null;comment:变更后可用余额:用于审计与对账回放" json:"balance_after"` // 变更后可用余额:用于审计与对账回放
|
||||
FrozenBefore int64 `gorm:"column:frozen_before;type:bigint;not null;comment:变更前冻结余额:用于审计与对账回放" json:"frozen_before"` // 变更前冻结余额:用于审计与对账回放
|
||||
FrozenAfter int64 `gorm:"column:frozen_after;type:bigint;not null;comment:变更后冻结余额:用于审计与对账回放" json:"frozen_after"` // 变更后冻结余额:用于审计与对账回放
|
||||
IdempotencyKey string `gorm:"column:idempotency_key;type:character varying(128);not null;comment:幂等键:同一租户同一用户同一业务操作固定;用于防止重复落账(建议由业务层生成)" json:"idempotency_key"` // 幂等键:同一租户同一用户同一业务操作固定;用于防止重复落账(建议由业务层生成)
|
||||
Remark string `gorm:"column:remark;type:character varying(255);not null;comment:备注:业务说明/后台操作原因等;用于审计" json:"remark"` // 备注:业务说明/后台操作原因等;用于审计
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now();comment:创建时间:默认 now()" json:"created_at"` // 创建时间:默认 now()
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now();comment:更新时间:默认 now()" json:"updated_at"` // 更新时间:默认 now()
|
||||
OperatorUserID int64 `gorm:"column:operator_user_id;type:bigint;comment:操作者用户ID:谁触发该流水(admin/buyer/system);用于审计与追责;可为空(历史数据或无法识别时)" json:"operator_user_id"` // 操作者用户ID:谁触发该流水(admin/buyer/system);用于审计与追责;可为空(历史数据或无法识别时)
|
||||
BizRefType string `gorm:"column:biz_ref_type;type:character varying(32);comment:业务引用类型:order/refund/topup/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键" json:"biz_ref_type"` // 业务引用类型:order/refund/topup/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键
|
||||
BizRefID int64 `gorm:"column:biz_ref_id;type:bigint;comment:业务引用ID:与 biz_ref_type 配合使用(例如 orders.id);用于对账与审计" json:"biz_ref_id"` // 业务引用ID:与 biz_ref_type 配合使用(例如 orders.id);用于对账与审计
|
||||
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true;comment:主键ID:自增" json:"id"` // 主键ID:自增
|
||||
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null;comment:租户ID:多租户隔离关键字段;必须与 tenant_users.tenant_id 一致" json:"tenant_id"` // 租户ID:多租户隔离关键字段;必须与 tenant_users.tenant_id 一致
|
||||
UserID int64 `gorm:"column:user_id;type:bigint;not null;comment:用户ID:余额账户归属用户;对应 tenant_users.user_id" json:"user_id"` // 用户ID:余额账户归属用户;对应 tenant_users.user_id
|
||||
OrderID int64 `gorm:"column:order_id;type:bigint;comment:关联订单ID:购买/退款类流水应关联 orders.id;非订单类可为空" json:"order_id"` // 关联订单ID:购买/退款类流水应关联 orders.id;非订单类可为空
|
||||
Type consts.TenantLedgerType `gorm:"column:type;type:character varying(32);not null;comment:流水类型:debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向" json:"type"` // 流水类型:debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向
|
||||
Amount int64 `gorm:"column:amount;type:bigint;not null;comment:流水金额:分/最小货币单位;通常为正数,方向由 type 决定(由业务层约束)" json:"amount"` // 流水金额:分/最小货币单位;通常为正数,方向由 type 决定(由业务层约束)
|
||||
BalanceBefore int64 `gorm:"column:balance_before;type:bigint;not null;comment:变更前可用余额:用于审计与对账回放" json:"balance_before"` // 变更前可用余额:用于审计与对账回放
|
||||
BalanceAfter int64 `gorm:"column:balance_after;type:bigint;not null;comment:变更后可用余额:用于审计与对账回放" json:"balance_after"` // 变更后可用余额:用于审计与对账回放
|
||||
FrozenBefore int64 `gorm:"column:frozen_before;type:bigint;not null;comment:变更前冻结余额:用于审计与对账回放" json:"frozen_before"` // 变更前冻结余额:用于审计与对账回放
|
||||
FrozenAfter int64 `gorm:"column:frozen_after;type:bigint;not null;comment:变更后冻结余额:用于审计与对账回放" json:"frozen_after"` // 变更后冻结余额:用于审计与对账回放
|
||||
IdempotencyKey string `gorm:"column:idempotency_key;type:character varying(128);not null;comment:幂等键:同一租户同一用户同一业务操作固定;用于防止重复落账(建议由业务层生成)" json:"idempotency_key"` // 幂等键:同一租户同一用户同一业务操作固定;用于防止重复落账(建议由业务层生成)
|
||||
Remark string `gorm:"column:remark;type:character varying(255);not null;comment:备注:业务说明/后台操作原因等;用于审计" json:"remark"` // 备注:业务说明/后台操作原因等;用于审计
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now();comment:创建时间:默认 now()" json:"created_at"` // 创建时间:默认 now()
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now();comment:更新时间:默认 now()" json:"updated_at"` // 更新时间:默认 now()
|
||||
OperatorUserID int64 `gorm:"column:operator_user_id;type:bigint;comment:操作者用户ID:谁触发该流水(admin/buyer/system);用于审计与追责;可为空(历史数据或无法识别时)" json:"operator_user_id"` // 操作者用户ID:谁触发该流水(admin/buyer/system);用于审计与追责;可为空(历史数据或无法识别时)
|
||||
BizRefType string `gorm:"column:biz_ref_type;type:character varying(32);comment:业务引用类型:order/refund/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键" json:"biz_ref_type"` // 业务引用类型:order/refund/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键
|
||||
BizRefID int64 `gorm:"column:biz_ref_id;type:bigint;comment:业务引用ID:与 biz_ref_type 配合使用(例如 orders.id);用于对账与审计" json:"biz_ref_id"` // 业务引用ID:与 biz_ref_type 配合使用(例如 orders.id);用于对账与审计
|
||||
Order *Order `gorm:"foreignKey:OrderID;references:ID" json:"order,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ type tenantLedgerQuery struct {
|
||||
TenantID field.Int64 // 租户ID:多租户隔离关键字段;必须与 tenant_users.tenant_id 一致
|
||||
UserID field.Int64 // 用户ID:余额账户归属用户;对应 tenant_users.user_id
|
||||
OrderID field.Int64 // 关联订单ID:购买/退款类流水应关联 orders.id;非订单类可为空
|
||||
Type field.Field // 流水类型:credit_topup/debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向
|
||||
Type field.Field // 流水类型:debit_purchase/credit_refund/freeze/unfreeze/adjustment;不同类型决定余额/冻结余额的变更方向
|
||||
Amount field.Int64 // 流水金额:分/最小货币单位;通常为正数,方向由 type 决定(由业务层约束)
|
||||
BalanceBefore field.Int64 // 变更前可用余额:用于审计与对账回放
|
||||
BalanceAfter field.Int64 // 变更后可用余额:用于审计与对账回放
|
||||
@@ -72,7 +72,7 @@ type tenantLedgerQuery struct {
|
||||
CreatedAt field.Time // 创建时间:默认 now()
|
||||
UpdatedAt field.Time // 更新时间:默认 now()
|
||||
OperatorUserID field.Int64 // 操作者用户ID:谁触发该流水(admin/buyer/system);用于审计与追责;可为空(历史数据或无法识别时)
|
||||
BizRefType field.String // 业务引用类型:order/refund/topup/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键
|
||||
BizRefType field.String // 业务引用类型:order/refund/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键
|
||||
BizRefID field.Int64 // 业务引用ID:与 biz_ref_type 配合使用(例如 orders.id);用于对账与审计
|
||||
Order tenantLedgerQueryBelongsToOrder
|
||||
|
||||
|
||||
@@ -18,15 +18,13 @@ const TableNameTenantUser = "tenant_users"
|
||||
|
||||
// TenantUser mapped from table <tenant_users>
|
||||
type TenantUser struct {
|
||||
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"`
|
||||
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
|
||||
Role types.Array[consts.TenantUserRole] `gorm:"column:role;type:text[];not null;default:ARRAY['member" json:"role"`
|
||||
Balance int64 `gorm:"column:balance;type:bigint;not null" json:"balance"`
|
||||
Status consts.UserStatus `gorm:"column:status;type:character varying(50);not null;default:verified" json:"status"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now()" json:"updated_at"`
|
||||
BalanceFrozen int64 `gorm:"column:balance_frozen;type:bigint;not null;comment:冻结余额:分/最小货币单位;下单冻结时从可用余额转入,最终扣款或回滚时转出;默认 0" json:"balance_frozen"` // 冻结余额:分/最小货币单位;下单冻结时从可用余额转入,最终扣款或回滚时转出;默认 0
|
||||
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"`
|
||||
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
|
||||
Role types.Array[consts.TenantUserRole] `gorm:"column:role;type:text[];not null;default:ARRAY['member" json:"role"`
|
||||
Status consts.UserStatus `gorm:"column:status;type:character varying(50);not null;default:verified" json:"status"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now()" json:"updated_at"`
|
||||
}
|
||||
|
||||
// Quick operations without importing query package
|
||||
|
||||
@@ -29,11 +29,9 @@ func newTenantUser(db *gorm.DB, opts ...gen.DOOption) tenantUserQuery {
|
||||
_tenantUserQuery.TenantID = field.NewInt64(tableName, "tenant_id")
|
||||
_tenantUserQuery.UserID = field.NewInt64(tableName, "user_id")
|
||||
_tenantUserQuery.Role = field.NewArray(tableName, "role")
|
||||
_tenantUserQuery.Balance = field.NewInt64(tableName, "balance")
|
||||
_tenantUserQuery.Status = field.NewField(tableName, "status")
|
||||
_tenantUserQuery.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_tenantUserQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
_tenantUserQuery.BalanceFrozen = field.NewInt64(tableName, "balance_frozen")
|
||||
|
||||
_tenantUserQuery.fillFieldMap()
|
||||
|
||||
@@ -43,16 +41,14 @@ func newTenantUser(db *gorm.DB, opts ...gen.DOOption) tenantUserQuery {
|
||||
type tenantUserQuery struct {
|
||||
tenantUserQueryDo tenantUserQueryDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64
|
||||
TenantID field.Int64
|
||||
UserID field.Int64
|
||||
Role field.Array
|
||||
Balance field.Int64
|
||||
Status field.Field
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
BalanceFrozen field.Int64 // 冻结余额:分/最小货币单位;下单冻结时从可用余额转入,最终扣款或回滚时转出;默认 0
|
||||
ALL field.Asterisk
|
||||
ID field.Int64
|
||||
TenantID field.Int64
|
||||
UserID field.Int64
|
||||
Role field.Array
|
||||
Status field.Field
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@@ -73,11 +69,9 @@ func (t *tenantUserQuery) updateTableName(table string) *tenantUserQuery {
|
||||
t.TenantID = field.NewInt64(table, "tenant_id")
|
||||
t.UserID = field.NewInt64(table, "user_id")
|
||||
t.Role = field.NewArray(table, "role")
|
||||
t.Balance = field.NewInt64(table, "balance")
|
||||
t.Status = field.NewField(table, "status")
|
||||
t.CreatedAt = field.NewTime(table, "created_at")
|
||||
t.UpdatedAt = field.NewTime(table, "updated_at")
|
||||
t.BalanceFrozen = field.NewInt64(table, "balance_frozen")
|
||||
|
||||
t.fillFieldMap()
|
||||
|
||||
@@ -110,16 +104,14 @@ func (t *tenantUserQuery) GetFieldByName(fieldName string) (field.OrderExpr, boo
|
||||
}
|
||||
|
||||
func (t *tenantUserQuery) fillFieldMap() {
|
||||
t.fieldMap = make(map[string]field.Expr, 9)
|
||||
t.fieldMap = make(map[string]field.Expr, 7)
|
||||
t.fieldMap["id"] = t.ID
|
||||
t.fieldMap["tenant_id"] = t.TenantID
|
||||
t.fieldMap["user_id"] = t.UserID
|
||||
t.fieldMap["role"] = t.Role
|
||||
t.fieldMap["balance"] = t.Balance
|
||||
t.fieldMap["status"] = t.Status
|
||||
t.fieldMap["created_at"] = t.CreatedAt
|
||||
t.fieldMap["updated_at"] = t.UpdatedAt
|
||||
t.fieldMap["balance_frozen"] = t.BalanceFrozen
|
||||
}
|
||||
|
||||
func (t tenantUserQuery) clone(db *gorm.DB) tenantUserQuery {
|
||||
|
||||
@@ -19,18 +19,20 @@ const TableNameUser = "users"
|
||||
|
||||
// User mapped from table <users>
|
||||
type User struct {
|
||||
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now()" json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp with time zone" json:"deleted_at"`
|
||||
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"`
|
||||
Roles types.Array[consts.Role] `gorm:"column:roles;type:text[];not null;default:ARRAY['user" json:"roles"`
|
||||
Status consts.UserStatus `gorm:"column:status;type:character varying(50);not null;default:active" json:"status"`
|
||||
Metas types.JSON `gorm:"column:metas;type:jsonb;not null;default:{}" json:"metas"`
|
||||
VerifiedAt time.Time `gorm:"column:verified_at;type:timestamp with time zone" json:"verified_at"`
|
||||
OwnedTenant *Tenant `json:"owned,omitempty"`
|
||||
Tenants []*Tenant `gorm:"joinForeignKey:UserID;joinReferences:TenantID;many2many:tenant_users" json:"tenants,omitempty"`
|
||||
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now()" json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp with time zone" json:"deleted_at"`
|
||||
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"`
|
||||
Roles types.Array[consts.Role] `gorm:"column:roles;type:text[];not null;default:ARRAY['user" json:"roles"`
|
||||
Status consts.UserStatus `gorm:"column:status;type:character varying(50);not null;default:active" json:"status"`
|
||||
Metas types.JSON `gorm:"column:metas;type:jsonb;not null;default:{}" json:"metas"`
|
||||
Balance int64 `gorm:"column:balance;type:bigint;not null;comment:全局可用余额:分/最小货币单位;用户在所有已加入租户内共享该余额;默认 0" json:"balance"` // 全局可用余额:分/最小货币单位;用户在所有已加入租户内共享该余额;默认 0
|
||||
BalanceFrozen int64 `gorm:"column:balance_frozen;type:bigint;not null;comment:全局冻结余额:分/最小货币单位;用于下单冻结等;默认 0" json:"balance_frozen"` // 全局冻结余额:分/最小货币单位;用于下单冻结等;默认 0
|
||||
VerifiedAt time.Time `gorm:"column:verified_at;type:timestamp with time zone" json:"verified_at"`
|
||||
OwnedTenant *Tenant `json:"owned,omitempty"`
|
||||
Tenants []*Tenant `gorm:"joinForeignKey:UserID;joinReferences:TenantID;many2many:tenant_users" json:"tenants,omitempty"`
|
||||
}
|
||||
|
||||
// Quick operations without importing query package
|
||||
|
||||
@@ -34,6 +34,8 @@ func newUser(db *gorm.DB, opts ...gen.DOOption) userQuery {
|
||||
_userQuery.Roles = field.NewArray(tableName, "roles")
|
||||
_userQuery.Status = field.NewField(tableName, "status")
|
||||
_userQuery.Metas = field.NewJSONB(tableName, "metas")
|
||||
_userQuery.Balance = field.NewInt64(tableName, "balance")
|
||||
_userQuery.BalanceFrozen = field.NewInt64(tableName, "balance_frozen")
|
||||
_userQuery.VerifiedAt = field.NewTime(tableName, "verified_at")
|
||||
_userQuery.OwnedTenant = userQueryBelongsToOwnedTenant{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
@@ -55,18 +57,20 @@ func newUser(db *gorm.DB, opts ...gen.DOOption) userQuery {
|
||||
type userQuery struct {
|
||||
userQueryDo userQueryDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Field
|
||||
Username field.String
|
||||
Password field.String
|
||||
Roles field.Array
|
||||
Status field.Field
|
||||
Metas field.JSONB
|
||||
VerifiedAt field.Time
|
||||
OwnedTenant userQueryBelongsToOwnedTenant
|
||||
ALL field.Asterisk
|
||||
ID field.Int64
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Field
|
||||
Username field.String
|
||||
Password field.String
|
||||
Roles field.Array
|
||||
Status field.Field
|
||||
Metas field.JSONB
|
||||
Balance field.Int64 // 全局可用余额:分/最小货币单位;用户在所有已加入租户内共享该余额;默认 0
|
||||
BalanceFrozen field.Int64 // 全局冻结余额:分/最小货币单位;用于下单冻结等;默认 0
|
||||
VerifiedAt field.Time
|
||||
OwnedTenant userQueryBelongsToOwnedTenant
|
||||
|
||||
Tenants userQueryManyToManyTenants
|
||||
|
||||
@@ -94,6 +98,8 @@ func (u *userQuery) updateTableName(table string) *userQuery {
|
||||
u.Roles = field.NewArray(table, "roles")
|
||||
u.Status = field.NewField(table, "status")
|
||||
u.Metas = field.NewJSONB(table, "metas")
|
||||
u.Balance = field.NewInt64(table, "balance")
|
||||
u.BalanceFrozen = field.NewInt64(table, "balance_frozen")
|
||||
u.VerifiedAt = field.NewTime(table, "verified_at")
|
||||
|
||||
u.fillFieldMap()
|
||||
@@ -125,7 +131,7 @@ func (u *userQuery) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (u *userQuery) fillFieldMap() {
|
||||
u.fieldMap = make(map[string]field.Expr, 12)
|
||||
u.fieldMap = make(map[string]field.Expr, 14)
|
||||
u.fieldMap["id"] = u.ID
|
||||
u.fieldMap["created_at"] = u.CreatedAt
|
||||
u.fieldMap["updated_at"] = u.UpdatedAt
|
||||
@@ -135,6 +141,8 @@ func (u *userQuery) fillFieldMap() {
|
||||
u.fieldMap["roles"] = u.Roles
|
||||
u.fieldMap["status"] = u.Status
|
||||
u.fieldMap["metas"] = u.Metas
|
||||
u.fieldMap["balance"] = u.Balance
|
||||
u.fieldMap["balance_frozen"] = u.BalanceFrozen
|
||||
u.fieldMap["verified_at"] = u.VerifiedAt
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user