暂存一下,防止丢失
This commit is contained in:
@@ -14,6 +14,8 @@ type AgentWallet struct {
|
||||
WalletType string `gorm:"column:wallet_type;type:varchar(20);not null;comment:钱包类型(main-主钱包 | commission-分佣钱包)" json:"wallet_type"`
|
||||
Balance int64 `gorm:"column:balance;type:bigint;not null;default:0;comment:余额(单位:分)" json:"balance"`
|
||||
FrozenBalance int64 `gorm:"column:frozen_balance;type:bigint;not null;default:0;comment:冻结余额(单位:分)" json:"frozen_balance"`
|
||||
CreditEnabled bool `gorm:"column:credit_enabled;type:boolean;not null;default:false;comment:是否启用主钱包信用额度" json:"credit_enabled"`
|
||||
CreditLimit int64 `gorm:"column:credit_limit;type:bigint;not null;default:0;comment:主钱包信用额度(单位:分)" json:"credit_limit"`
|
||||
Currency string `gorm:"column:currency;type:varchar(10);not null;default:'CNY';comment:币种" json:"currency"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:钱包状态(1-正常 2-冻结 3-关闭)" json:"status"`
|
||||
Version int `gorm:"column:version;type:int;not null;default:0;comment:版本号(乐观锁)" json:"version"`
|
||||
@@ -29,7 +31,8 @@ func (AgentWallet) TableName() string {
|
||||
return "tb_agent_wallet"
|
||||
}
|
||||
|
||||
// GetAvailableBalance 获取可用余额 = balance - frozen_balance
|
||||
// GetAvailableBalance 获取旧写入口使用的现金可用金额。
|
||||
// Deprecated: 信用钱包完整用例应使用 Wallet Domain 的 AvailableBalance。
|
||||
func (w *AgentWallet) GetAvailableBalance() int64 {
|
||||
return w.Balance - w.FrozenBalance
|
||||
}
|
||||
@@ -41,13 +44,13 @@ type AgentWalletTransaction struct {
|
||||
AgentWalletID uint `gorm:"column:agent_wallet_id;not null;index;comment:代理钱包ID" json:"agent_wallet_id"`
|
||||
ShopID uint `gorm:"column:shop_id;not null;index;comment:店铺ID(冗余字段,便于查询)" json:"shop_id"`
|
||||
UserID uint `gorm:"column:user_id;not null;comment:操作人用户ID" json:"user_id"`
|
||||
TransactionType string `gorm:"column:transaction_type;type:varchar(20);not null;comment:交易类型(recharge-充值 | deduct-扣款 | refund-退款 | commission-分佣 | withdrawal-提现)" json:"transaction_type"`
|
||||
TransactionType string `gorm:"column:transaction_type;type:varchar(20);not null;comment:交易类型(recharge-充值 | adjustment-人工调整 | deduct-扣款 | refund-退款 | commission-分佣 | withdrawal-提现)" json:"transaction_type"`
|
||||
TransactionSubtype *string `gorm:"column:transaction_subtype;type:varchar(50);comment:交易子类型(细分 order_payment 场景)" json:"transaction_subtype,omitempty"`
|
||||
Amount int64 `gorm:"column:amount;type:bigint;not null;comment:变动金额(单位:分,正数为增加,负数为减少)" json:"amount"`
|
||||
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"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:交易状态(1-成功 2-失败 3-处理中)" json:"status"`
|
||||
ReferenceType *string `gorm:"column:reference_type;type:varchar(50);comment:关联业务类型(order | commission | withdrawal | topup)" json:"reference_type,omitempty"`
|
||||
ReferenceType *string `gorm:"column:reference_type;type:varchar(50);comment:关联业务类型(order | commission | withdrawal | topup | refund | exchange | manual_adjustment)" json:"reference_type,omitempty"`
|
||||
ReferenceID *uint `gorm:"column:reference_id;comment:关联业务ID" json:"reference_id,omitempty"`
|
||||
RelatedShopID *uint `gorm:"column:related_shop_id;comment:关联店铺ID(代购时记录下级店铺)" json:"related_shop_id,omitempty"`
|
||||
AssetType string `gorm:"column:asset_type;type:varchar(20);not null;default:'';comment:资产类型(iot_card-物联网卡 | device-设备)" json:"asset_type,omitempty"`
|
||||
@@ -71,27 +74,27 @@ func (AgentWalletTransaction) TableName() string {
|
||||
// AgentRechargeRecord 代理充值记录模型
|
||||
// 记录所有代理充值操作
|
||||
type AgentRechargeRecord struct {
|
||||
ID uint `gorm:"column:id;primaryKey" json:"id"`
|
||||
UserID uint `gorm:"column:user_id;not null;index;comment:操作人用户ID" json:"user_id"`
|
||||
AgentWalletID uint `gorm:"column:agent_wallet_id;not null;comment:代理钱包ID" json:"agent_wallet_id"`
|
||||
ShopID uint `gorm:"column:shop_id;not null;index;comment:店铺ID(冗余字段,便于查询)" json:"shop_id"`
|
||||
RechargeNo string `gorm:"column:recharge_no;type:varchar(50);not null;uniqueIndex;comment:充值订单号(格式:ARCH+时间戳+随机数)" json:"recharge_no"`
|
||||
Amount int64 `gorm:"column:amount;type:bigint;not null;comment:充值金额(单位:分,最小1分)" json:"amount"`
|
||||
PaymentMethod string `gorm:"column:payment_method;type:varchar(20);not null;comment:支付方式(alipay-支付宝 | wechat-微信 | bank-银行转账 | offline-线下)" json:"payment_method"`
|
||||
PaymentChannel *string `gorm:"column:payment_channel;type:varchar(50);comment:支付渠道" json:"payment_channel,omitempty"`
|
||||
PaymentTransactionID *string `gorm:"column:payment_transaction_id;type:varchar(100);comment:第三方支付交易号" json:"payment_transaction_id,omitempty"`
|
||||
PaymentConfigID *uint `gorm:"column:payment_config_id;index;comment:支付配置ID(关联tb_wechat_config.id)" json:"payment_config_id,omitempty"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:充值状态(1-待支付 2-已支付 3-已完成 4-已关闭 5-已退款)" json:"status"`
|
||||
ID uint `gorm:"column:id;primaryKey" json:"id"`
|
||||
UserID uint `gorm:"column:user_id;not null;index;comment:操作人用户ID" json:"user_id"`
|
||||
AgentWalletID uint `gorm:"column:agent_wallet_id;not null;comment:代理钱包ID" json:"agent_wallet_id"`
|
||||
ShopID uint `gorm:"column:shop_id;not null;index;comment:店铺ID(冗余字段,便于查询)" json:"shop_id"`
|
||||
RechargeNo string `gorm:"column:recharge_no;type:varchar(50);not null;uniqueIndex;comment:充值订单号(格式:ARCH+时间戳+随机数)" json:"recharge_no"`
|
||||
Amount int64 `gorm:"column:amount;type:bigint;not null;comment:充值金额(单位:分,最小1分)" json:"amount"`
|
||||
PaymentMethod string `gorm:"column:payment_method;type:varchar(20);not null;comment:支付方式(alipay-支付宝 | wechat-微信 | bank-银行转账 | offline-线下)" json:"payment_method"`
|
||||
PaymentChannel *string `gorm:"column:payment_channel;type:varchar(50);comment:支付渠道" json:"payment_channel,omitempty"`
|
||||
PaymentTransactionID *string `gorm:"column:payment_transaction_id;type:varchar(100);comment:第三方支付交易号" json:"payment_transaction_id,omitempty"`
|
||||
PaymentConfigID *uint `gorm:"column:payment_config_id;index;comment:支付配置ID(关联tb_wechat_config.id)" json:"payment_config_id,omitempty"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:充值状态(1-待支付 2-已支付 3-已完成 4-已关闭 5-已退款)" json:"status"`
|
||||
PaymentVoucherKey StringJSONBArray `gorm:"column:payment_voucher_key;type:jsonb;comment:支付凭证对象存储Key列表(线下支付时必填,最多5个,微信支付时为空)" json:"payment_voucher_key"`
|
||||
Remark string `gorm:"column:remark;type:text;comment:运营备注(创建时填写,不可修改)" json:"remark,omitempty"`
|
||||
RejectionReason *string `gorm:"column:rejection_reason;type:varchar(500);comment:驳回原因,仅驳回时写入" json:"rejection_reason,omitempty"`
|
||||
PaidAt *time.Time `gorm:"column:paid_at;comment:支付时间" json:"paid_at,omitempty"`
|
||||
CompletedAt *time.Time `gorm:"column:completed_at;comment:完成时间" json:"completed_at,omitempty"`
|
||||
ShopIDTag uint `gorm:"column:shop_id_tag;not null;index;comment:店铺ID标签(多租户过滤)" json:"shop_id_tag"`
|
||||
EnterpriseIDTag *uint `gorm:"column:enterprise_id_tag;index;comment:企业ID标签(多租户过滤)" json:"enterprise_id_tag,omitempty"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index" json:"deleted_at,omitempty"`
|
||||
PaidAt *time.Time `gorm:"column:paid_at;comment:支付时间" json:"paid_at,omitempty"`
|
||||
CompletedAt *time.Time `gorm:"column:completed_at;comment:完成时间" json:"completed_at,omitempty"`
|
||||
ShopIDTag uint `gorm:"column:shop_id_tag;not null;index;comment:店铺ID标签(多租户过滤)" json:"shop_id_tag"`
|
||||
EnterpriseIDTag *uint `gorm:"column:enterprise_id_tag;index;comment:企业ID标签(多租户过滤)" json:"enterprise_id_tag,omitempty"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index" json:"deleted_at,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
25
internal/model/agent_wallet_reservation.go
Normal file
25
internal/model/agent_wallet_reservation.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// AgentWalletReservation 记录代理主钱包资金预占及其唯一终态。
|
||||
type AgentWalletReservation struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
AgentWalletID uint `gorm:"column:agent_wallet_id;not null;index:idx_agent_wallet_reservation_wallet" json:"agent_wallet_id"`
|
||||
ShopID uint `gorm:"column:shop_id;not null;index:idx_agent_wallet_reservation_shop" json:"shop_id"`
|
||||
Amount int64 `gorm:"column:amount;type:bigint;not null" json:"amount"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;index:idx_agent_wallet_reservation_status" json:"status"`
|
||||
ReferenceType string `gorm:"column:reference_type;type:varchar(50);not null;uniqueIndex:uq_agent_wallet_reservation_reference" json:"reference_type"`
|
||||
ReferenceID uint `gorm:"column:reference_id;not null;uniqueIndex:uq_agent_wallet_reservation_reference" json:"reference_id"`
|
||||
Creator uint `gorm:"column:creator;not null;default:0" json:"creator"`
|
||||
CompletedAt *time.Time `gorm:"column:completed_at" json:"completed_at,omitempty"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;not null;autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;not null;autoUpdateTime" json:"updated_at"`
|
||||
ShopIDTag uint `gorm:"column:shop_id_tag;not null;index" json:"shop_id_tag"`
|
||||
EnterpriseIDTag *uint `gorm:"column:enterprise_id_tag;index" json:"enterprise_id_tag,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 返回代理主钱包预占事实表名。
|
||||
func (AgentWalletReservation) TableName() string {
|
||||
return "tb_agent_wallet_reservation"
|
||||
}
|
||||
24
internal/model/approval_decision_delivery.go
Normal file
24
internal/model/approval_decision_delivery.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// ApprovalDecisionDelivery 是标准审批决策交给业务消费者的幂等处理事实。
|
||||
type ApprovalDecisionDelivery struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
InstanceID uint `gorm:"column:instance_id;not null;uniqueIndex:uq_approval_decision_delivery,priority:1" json:"instance_id"`
|
||||
Decision string `gorm:"column:decision;type:varchar(32);not null;uniqueIndex:uq_approval_decision_delivery,priority:2" json:"decision"`
|
||||
EventID string `gorm:"column:event_id;type:varchar(64);not null;uniqueIndex" json:"event_id"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:0;index:idx_approval_decision_delivery_claim,priority:1" json:"status"`
|
||||
RetryCount int `gorm:"column:retry_count;type:int;not null;default:0" json:"retry_count"`
|
||||
LeaseOwner *string `gorm:"column:lease_owner;type:varchar(100)" json:"lease_owner,omitempty"`
|
||||
LeaseExpiresAt *time.Time `gorm:"column:lease_expires_at;type:timestamptz;index:idx_approval_decision_delivery_claim,priority:2" json:"lease_expires_at,omitempty"`
|
||||
LastError string `gorm:"column:last_error;type:varchar(500);not null;default:''" json:"last_error,omitempty"`
|
||||
ProcessedAt *time.Time `gorm:"column:processed_at;type:timestamptz" json:"processed_at,omitempty"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamptz;not null;autoUpdateTime" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 返回审批决策投递表名。
|
||||
func (ApprovalDecisionDelivery) TableName() string {
|
||||
return "tb_approval_decision_delivery"
|
||||
}
|
||||
31
internal/model/approval_instance.go
Normal file
31
internal/model/approval_instance.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/datatypes"
|
||||
)
|
||||
|
||||
// ApprovalInstance 是渠道无关的通用审批实例持久化模型。
|
||||
type ApprovalInstance struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
BusinessType string `gorm:"column:business_type;type:varchar(64);not null;uniqueIndex:uq_approval_instance_business,priority:1" json:"business_type"`
|
||||
BusinessID uint `gorm:"column:business_id;not null;uniqueIndex:uq_approval_instance_business,priority:2" json:"business_id"`
|
||||
SubmitterAccountID uint `gorm:"column:submitter_account_id;not null;index" json:"submitter_account_id"`
|
||||
SubmitterSnapshot datatypes.JSON `gorm:"column:submitter_snapshot;type:jsonb;not null" json:"submitter_snapshot"`
|
||||
Provider string `gorm:"column:provider;type:varchar(32);not null" json:"provider"`
|
||||
ExternalRef string `gorm:"column:external_ref;type:varchar(128);not null;default:''" json:"external_ref"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:0;index:idx_approval_instance_status_changed,priority:1" json:"status"`
|
||||
RequestSnapshot datatypes.JSON `gorm:"column:request_snapshot;type:jsonb;not null" json:"request_snapshot"`
|
||||
DecisionSnapshot datatypes.JSON `gorm:"column:decision_snapshot;type:jsonb" json:"decision_snapshot,omitempty"`
|
||||
CorrelationID string `gorm:"column:correlation_id;type:varchar(100);not null;index" json:"correlation_id"`
|
||||
Version int `gorm:"column:version;type:int;not null;default:1" json:"version"`
|
||||
StatusChangedAt time.Time `gorm:"column:status_changed_at;type:timestamptz;not null;index:idx_approval_instance_status_changed,priority:2" json:"status_changed_at"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamptz;not null;autoUpdateTime" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 返回通用审批实例表名。
|
||||
func (ApprovalInstance) TableName() string {
|
||||
return "tb_approval_instance"
|
||||
}
|
||||
18
internal/model/card_observation_effect.go
Normal file
18
internal/model/card_observation_effect.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package model
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
// CardObservationEffect 记录卡观测事件副作用的幂等处理进度。
|
||||
// 处理中的记录代表结果未知,自动重试不得重复执行已提交的套餐扣减。
|
||||
type CardObservationEffect struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
EventID string `gorm:"column:event_id;type:varchar(180);not null;uniqueIndex:uk_card_observation_effect_event;comment:Outbox事件ID" json:"event_id"`
|
||||
EffectType string `gorm:"column:effect_type;type:varchar(50);not null;comment:副作用类型" json:"effect_type"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:0;comment:处理状态 0-待处理 1-处理中或结果未知 2-日流量已记录 3-已扣减 4-已完成" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名。
|
||||
func (CardObservationEffect) TableName() string {
|
||||
return "tb_card_observation_effect"
|
||||
}
|
||||
@@ -89,10 +89,16 @@ type AgentOpenAPIPackageItem struct {
|
||||
|
||||
// AgentOpenAPIWalletBalanceResponse 开放接口预充值钱包余额响应
|
||||
type AgentOpenAPIWalletBalanceResponse struct {
|
||||
Balance int64 `json:"balance" description:"钱包余额(分)"`
|
||||
FrozenBalance int64 `json:"frozen_balance" description:"冻结余额(分)"`
|
||||
AvailableBalance int64 `json:"available_balance" description:"可用余额(分)"`
|
||||
Currency string `json:"currency" description:"币种"`
|
||||
Balance int64 `json:"balance" description:"钱包账面余额(分)"`
|
||||
FrozenBalance int64 `json:"frozen_balance" description:"冻结余额(分)"`
|
||||
CashAvailableBalance int64 `json:"cash_available_balance" description:"现金可用金额(分),等于账面余额减冻结余额"`
|
||||
CreditEnabled bool `json:"credit_enabled" description:"是否启用主钱包信用额度"`
|
||||
CreditLimit int64 `json:"credit_limit" description:"主钱包信用额度(分)"`
|
||||
AvailableBalance int64 `json:"available_balance" description:"总可用金额(分),等于现金可用金额加生效信用额度"`
|
||||
IsInDebt bool `json:"is_in_debt" description:"账面余额是否已形成欠款"`
|
||||
DebtAmount int64 `json:"debt_amount" description:"欠款金额(分),仅取负账面余额绝对值"`
|
||||
Version int `json:"version" description:"钱包乐观锁版本"`
|
||||
Currency string `json:"currency" description:"币种"`
|
||||
}
|
||||
|
||||
// AgentOpenAPIWalletTransactionListRequest 开放接口预充值钱包流水请求
|
||||
|
||||
94
internal/model/dto/notification_dto.go
Normal file
94
internal/model/dto/notification_dto.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
// NotificationUnreadCountResponse 是后台账号未读数投影。
|
||||
type NotificationUnreadCountResponse struct {
|
||||
Count int64 `json:"count" description:"未读通知数量"`
|
||||
DisplayCount string `json:"display_count" description:"徽标显示文本,超过 99 时为 99+"`
|
||||
}
|
||||
|
||||
// NotificationListRequest 是后台通知基础分页参数。
|
||||
type NotificationListRequest struct {
|
||||
Category string `json:"category" query:"category" validate:"omitempty,oneof=approval expiry sync system" enums:"approval,expiry,sync,system" description:"通知类别 (approval:审批, expiry:临期, sync:同步, system:系统)"`
|
||||
Type string `json:"type" query:"type" validate:"omitempty,max=100" maxlength:"100" description:"稳定通知类型"`
|
||||
Severity string `json:"severity" query:"severity" validate:"omitempty,oneof=info warning error critical" enums:"info,warning,error,critical" description:"通知级别 (info:提示, warning:警告, error:错误, critical:严重)"`
|
||||
IsRead *bool `json:"is_read" query:"is_read" description:"已读状态;不传时查询全部"`
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1,max=10000" minimum:"1" maximum:"10000" description:"页码,默认 1,最大 10000"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=50" minimum:"1" maximum:"50" description:"每页数量,默认 20,最大 50"`
|
||||
}
|
||||
|
||||
// NotificationItem 是后台账号可见的站内通知投影。
|
||||
type NotificationItem struct {
|
||||
ID uint `json:"id" description:"通知ID"`
|
||||
Category string `json:"category" description:"通知类别 (approval:审批, expiry:临期, sync:同步, system:系统)"`
|
||||
Type string `json:"type" description:"稳定通知类型"`
|
||||
Severity string `json:"severity" description:"通知级别 (info:提示, warning:警告, error:错误, critical:严重)"`
|
||||
Title string `json:"title" description:"纯文本标题"`
|
||||
Body string `json:"body" description:"纯文本正文"`
|
||||
RefType string `json:"ref_type" description:"受控资源类型"`
|
||||
RefID string `json:"ref_id" description:"受控资源ID"`
|
||||
RefKey string `json:"ref_key" description:"受控资源Key"`
|
||||
IsRead bool `json:"is_read" description:"是否已读"`
|
||||
ReadAt *time.Time `json:"read_at,omitempty" description:"首次已读时间(ISO 8601)"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间(ISO 8601)"`
|
||||
}
|
||||
|
||||
// NotificationListResponse 是后台通知基础分页结果。
|
||||
type NotificationListResponse struct {
|
||||
Items []NotificationItem `json:"items" description:"通知列表"`
|
||||
Total int64 `json:"total" description:"总数量"`
|
||||
Page int `json:"page" description:"页码"`
|
||||
Size int `json:"size" description:"每页数量"`
|
||||
}
|
||||
|
||||
// NotificationIDParams 是单条通知路径参数。
|
||||
type NotificationIDParams struct {
|
||||
ID uint `json:"id" path:"id" required:"true" description:"通知ID"`
|
||||
}
|
||||
|
||||
// NotificationReadResponse 是单条通知幂等已读结果。
|
||||
type NotificationReadResponse struct {
|
||||
Success bool `json:"success" description:"请求是否成功;通知不存在、属于别人或已经已读也返回 true"`
|
||||
}
|
||||
|
||||
// NotificationTargetResponse 是通知受控目标解析结果,不包含任意 URL。
|
||||
type NotificationTargetResponse struct {
|
||||
TargetType string `json:"target_type" description:"前端白名单目标类型;空表示不支持跳转"`
|
||||
TargetID *uint `json:"target_id,omitempty" description:"受控数值目标ID"`
|
||||
TargetKey string `json:"target_key,omitempty" description:"受控稳定目标Key"`
|
||||
Available bool `json:"available" description:"当前账号是否仍可访问目标"`
|
||||
}
|
||||
|
||||
// NotificationUnreadSummaryResponse 是后台账号未读通知的固定分类汇总。
|
||||
type NotificationUnreadSummaryResponse struct {
|
||||
Total int64 `json:"total" description:"未读通知总数"`
|
||||
Approval int64 `json:"approval" description:"审批类未读数量"`
|
||||
Expiry int64 `json:"expiry" description:"临期类未读数量"`
|
||||
Sync int64 `json:"sync" description:"同步类未读数量"`
|
||||
System int64 `json:"system" description:"系统类未读数量"`
|
||||
}
|
||||
|
||||
// NotificationReadAllRequest 是后台批量已读请求。
|
||||
type NotificationReadAllRequest struct {
|
||||
Category string `json:"category" validate:"omitempty,oneof=approval expiry sync system" enums:"approval,expiry,sync,system" description:"可选通知类别 (approval:审批, expiry:临期, sync:同步, system:系统)"`
|
||||
}
|
||||
|
||||
// NotificationReadAllResponse 是后台批量已读结果。
|
||||
type NotificationReadAllResponse struct {
|
||||
UpdatedCount int64 `json:"updated_count" description:"本次实际更新的通知数量"`
|
||||
}
|
||||
|
||||
// PersonalNotificationListRequest 是个人客户通知的简化分页参数。
|
||||
type PersonalNotificationListRequest struct {
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1,max=10000" minimum:"1" maximum:"10000" description:"页码,默认 1,最大 10000"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=50" minimum:"1" maximum:"50" description:"每页数量,默认 20,最大 50"`
|
||||
}
|
||||
|
||||
// PersonalNotificationListResponse 是个人客户通知的简化分页结果。
|
||||
type PersonalNotificationListResponse struct {
|
||||
Items []NotificationItem `json:"items" description:"当前个人客户可见的业务通知列表"`
|
||||
Total int64 `json:"total" description:"总数量"`
|
||||
Page int `json:"page" description:"页码"`
|
||||
Size int `json:"size" description:"每页数量"`
|
||||
}
|
||||
@@ -31,15 +31,39 @@ type RoleListRequest struct {
|
||||
|
||||
// RoleResponse 角色响应
|
||||
type RoleResponse struct {
|
||||
ID uint `json:"id" description:"角色ID"`
|
||||
RoleName string `json:"role_name" description:"角色名称"`
|
||||
RoleDesc string `json:"role_desc" description:"角色描述"`
|
||||
RoleType int `json:"role_type" description:"角色类型 (1:平台角色, 2:客户角色)"`
|
||||
Status int `json:"status" description:"状态 (0:禁用, 1:启用)"`
|
||||
Creator uint `json:"creator" description:"创建人ID"`
|
||||
Updater uint `json:"updater" description:"更新人ID"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
ID uint `json:"id" description:"角色ID"`
|
||||
RoleName string `json:"role_name" description:"角色名称"`
|
||||
RoleDesc string `json:"role_desc" description:"角色描述"`
|
||||
RoleType int `json:"role_type" description:"角色类型 (1:平台角色, 2:客户角色)"`
|
||||
Status int `json:"status" description:"状态 (0:禁用, 1:启用)"`
|
||||
DefaultCreditEnabled bool `json:"default_credit_enabled" description:"是否启用新建代理默认信用;仅客户角色有效"`
|
||||
DefaultCreditLimit int64 `json:"default_credit_limit" description:"新建代理默认信用额度(分);仅影响未来新建店铺"`
|
||||
DefaultCreditScope string `json:"default_credit_scope" description:"模板生效范围,固定为 new_shops_only"`
|
||||
Creator uint `json:"creator" description:"创建人ID"`
|
||||
Updater uint `json:"updater" description:"更新人ID"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
}
|
||||
|
||||
// UpdateRoleDefaultCreditRequest 更新角色默认信用模板请求。
|
||||
type UpdateRoleDefaultCreditRequest struct {
|
||||
CreditEnabled *bool `json:"credit_enabled" validate:"required" required:"true" description:"是否启用新建代理默认信用"`
|
||||
CreditLimit *int64 `json:"credit_limit" validate:"required,min=0" required:"true" minimum:"0" description:"新建代理默认信用额度(分);关闭时必须为0,开启时必须大于0"`
|
||||
}
|
||||
|
||||
// UpdateRoleDefaultCreditParams 更新角色默认信用模板参数。
|
||||
type UpdateRoleDefaultCreditParams struct {
|
||||
IDReq
|
||||
UpdateRoleDefaultCreditRequest
|
||||
}
|
||||
|
||||
// RoleDefaultCreditResponse 角色默认信用模板响应。
|
||||
type RoleDefaultCreditResponse struct {
|
||||
RoleID uint `json:"role_id" description:"客户角色ID"`
|
||||
CreditEnabled bool `json:"credit_enabled" description:"是否启用新建代理默认信用"`
|
||||
CreditLimit int64 `json:"credit_limit" description:"新建代理默认信用额度(分)"`
|
||||
Scope string `json:"scope" description:"模板生效范围,固定为 new_shops_only"`
|
||||
AffectsExistingWallets bool `json:"affects_existing_wallets" description:"是否影响既有钱包,固定为 false"`
|
||||
}
|
||||
|
||||
// RolePageResult 角色分页响应
|
||||
|
||||
@@ -20,7 +20,14 @@ type ShopFundSummaryItem struct {
|
||||
Username string `json:"username" description:"主账号用户名"`
|
||||
Phone string `json:"phone" description:"主账号手机号"`
|
||||
MainBalance int64 `json:"main_balance" description:"预充值钱包余额(分)"`
|
||||
MainFrozenBalance int64 `json:"main_frozen_balance" description:"预充值钱包冻结余额(分,预留字段)"`
|
||||
MainFrozenBalance int64 `json:"main_frozen_balance" description:"预充值钱包冻结余额(分)"`
|
||||
CashAvailableBalance int64 `json:"cash_available_balance" description:"现金可用金额(分),等于主钱包余额减冻结金额"`
|
||||
CreditEnabled bool `json:"credit_enabled" description:"是否启用主钱包信用额度"`
|
||||
CreditLimit int64 `json:"credit_limit" description:"主钱包信用额度(分),关闭信用时为0"`
|
||||
AvailableBalance int64 `json:"available_balance" description:"总可用金额(分),等于现金可用金额加生效信用额度"`
|
||||
IsInDebt bool `json:"is_in_debt" description:"主钱包账面余额是否为负数"`
|
||||
DebtAmount int64 `json:"debt_amount" description:"主钱包欠款金额(分),仅取负账面余额绝对值"`
|
||||
Version int `json:"version" description:"主钱包当前版本号,并发写冲突后应重新查询"`
|
||||
TotalCommission int64 `json:"total_commission" description:"累计佣金总额(分)"`
|
||||
WithdrawnCommission int64 `json:"withdrawn_commission" description:"已提现佣金(分)"`
|
||||
UnwithdrawCommission int64 `json:"unwithdraw_commission" description:"未提现佣金(分)"`
|
||||
|
||||
@@ -1,64 +1,112 @@
|
||||
package dto
|
||||
|
||||
import "github.com/bytedance/sonic"
|
||||
|
||||
type ShopListRequest struct {
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
|
||||
ShopName string `json:"shop_name" query:"shop_name" validate:"omitempty,max=100" maxLength:"100" description:"店铺名称模糊查询"`
|
||||
ShopCode string `json:"shop_code" query:"shop_code" validate:"omitempty,max=50" maxLength:"50" description:"店铺编号精确查询"`
|
||||
ContactPhone string `json:"contact_phone" query:"contact_phone" validate:"omitempty,len=11,numeric,ascii" minLength:"11" maxLength:"11" pattern:"^[0-9]{11}$" description:"联系电话精确查询(11位 ASCII 数字;空值不启用筛选;与其他条件按 AND 组合)"`
|
||||
ParentID *uint `json:"parent_id" query:"parent_id" validate:"omitempty,min=1" minimum:"1" description:"上级店铺ID"`
|
||||
Level *int `json:"level" query:"level" validate:"omitempty,min=1,max=7" minimum:"1" maximum:"7" description:"店铺层级 (1-7级)"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=0 1" description:"状态 (0:禁用, 1:启用)"`
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
|
||||
ShopName string `json:"shop_name" query:"shop_name" validate:"omitempty,max=100" maxLength:"100" description:"店铺名称模糊查询"`
|
||||
ShopCode string `json:"shop_code" query:"shop_code" validate:"omitempty,max=50" maxLength:"50" description:"店铺编号精确查询"`
|
||||
ContactPhone string `json:"contact_phone" query:"contact_phone" validate:"omitempty,len=11,numeric,ascii" minLength:"11" maxLength:"11" pattern:"^[0-9]{11}$" description:"联系电话精确查询(11位 ASCII 数字;空值不启用筛选;与其他条件按 AND 组合)"`
|
||||
BusinessOwnerAccountID *uint `json:"business_owner_account_id" query:"business_owner_account_id" validate:"omitempty,min=1" minimum:"1" description:"平台业务员账号ID精确筛选"`
|
||||
ParentID *uint `json:"parent_id" query:"parent_id" validate:"omitempty,min=1" minimum:"1" description:"上级店铺ID"`
|
||||
Level *int `json:"level" query:"level" validate:"omitempty,min=1,max=7" minimum:"1" maximum:"7" description:"店铺层级 (1-7级)"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=0 1" description:"状态 (0:禁用, 1:启用)"`
|
||||
}
|
||||
|
||||
type CreateShopRequest struct {
|
||||
ShopName string `json:"shop_name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"店铺名称"`
|
||||
ShopCode string `json:"shop_code" validate:"required,min=1,max=50" required:"true" minLength:"1" maxLength:"50" description:"店铺编号"`
|
||||
ParentID *uint `json:"parent_id" validate:"omitempty,min=1" minimum:"1" description:"上级店铺ID(一级店铺可不填)"`
|
||||
ContactName string `json:"contact_name" validate:"omitempty,max=50" maxLength:"50" description:"联系人姓名"`
|
||||
ContactPhone string `json:"contact_phone" validate:"omitempty,len=11" minLength:"11" maxLength:"11" description:"联系人电话"`
|
||||
Province string `json:"province" validate:"omitempty,max=50" maxLength:"50" description:"省份"`
|
||||
City string `json:"city" validate:"omitempty,max=50" maxLength:"50" description:"城市"`
|
||||
District string `json:"district" validate:"omitempty,max=50" maxLength:"50" description:"区县"`
|
||||
Address string `json:"address" validate:"omitempty,max=255" maxLength:"255" description:"详细地址"`
|
||||
DefaultRoleID uint `json:"default_role_id" validate:"required,min=1" required:"true" minimum:"1" description:"店铺默认角色ID(必须是客户角色)"`
|
||||
InitPassword string `json:"init_password" validate:"required,min=8,max=32" required:"true" minLength:"8" maxLength:"32" description:"初始账号密码"`
|
||||
InitUsername string `json:"init_username" validate:"required,min=3,max=50" required:"true" minLength:"3" maxLength:"50" description:"初始账号用户名"`
|
||||
InitPhone string `json:"init_phone" validate:"required,len=11" required:"true" minLength:"11" maxLength:"11" description:"初始账号手机号"`
|
||||
ShopName string `json:"shop_name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"店铺名称"`
|
||||
ShopCode string `json:"shop_code" validate:"required,min=1,max=50" required:"true" minLength:"1" maxLength:"50" description:"店铺编号"`
|
||||
ParentID *uint `json:"parent_id" validate:"omitempty,min=1" minimum:"1" description:"上级店铺ID(一级店铺可不填)"`
|
||||
BusinessOwnerAccountID *uint `json:"business_owner_account_id" nullable:"true" description:"平台业务员账号ID;缺失时继承上级,null 表示空归属"`
|
||||
BusinessOwnerAccountIDSet bool `json:"-"`
|
||||
ContactName string `json:"contact_name" validate:"omitempty,max=50" maxLength:"50" description:"联系人姓名"`
|
||||
ContactPhone string `json:"contact_phone" validate:"omitempty,len=11" minLength:"11" maxLength:"11" description:"联系人电话"`
|
||||
Province string `json:"province" validate:"omitempty,max=50" maxLength:"50" description:"省份"`
|
||||
City string `json:"city" validate:"omitempty,max=50" maxLength:"50" description:"城市"`
|
||||
District string `json:"district" validate:"omitempty,max=50" maxLength:"50" description:"区县"`
|
||||
Address string `json:"address" validate:"omitempty,max=255" maxLength:"255" description:"详细地址"`
|
||||
DefaultRoleID uint `json:"default_role_id" validate:"required,min=1" required:"true" minimum:"1" description:"店铺默认角色ID(必须是客户角色)"`
|
||||
InitPassword string `json:"init_password" validate:"required,min=8,max=32" required:"true" minLength:"8" maxLength:"32" description:"初始账号密码"`
|
||||
InitUsername string `json:"init_username" validate:"required,min=3,max=50" required:"true" minLength:"3" maxLength:"50" description:"初始账号用户名"`
|
||||
InitPhone string `json:"init_phone" validate:"required,len=11" required:"true" minLength:"11" maxLength:"11" description:"初始账号手机号"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON 解析创建店铺请求并保留业务员字段“缺失”和“显式 null”的差异。
|
||||
func (r *CreateShopRequest) UnmarshalJSON(data []byte) error {
|
||||
type plain CreateShopRequest
|
||||
var decoded plain
|
||||
if err := sonic.Unmarshal(data, &decoded); err != nil {
|
||||
return err
|
||||
}
|
||||
var fields map[string]any
|
||||
if err := sonic.Unmarshal(data, &fields); err != nil {
|
||||
return err
|
||||
}
|
||||
decoded.BusinessOwnerAccountIDSet = false
|
||||
if _, exists := fields["business_owner_account_id"]; exists {
|
||||
decoded.BusinessOwnerAccountIDSet = true
|
||||
}
|
||||
*r = CreateShopRequest(decoded)
|
||||
return nil
|
||||
}
|
||||
|
||||
type UpdateShopRequest struct {
|
||||
ShopName string `json:"shop_name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"店铺名称"`
|
||||
ContactName string `json:"contact_name" validate:"omitempty,max=50" maxLength:"50" description:"联系人姓名"`
|
||||
ContactPhone string `json:"contact_phone" validate:"omitempty,len=11" minLength:"11" maxLength:"11" description:"联系人电话"`
|
||||
Province string `json:"province" validate:"omitempty,max=50" maxLength:"50" description:"省份"`
|
||||
City string `json:"city" validate:"omitempty,max=50" maxLength:"50" description:"城市"`
|
||||
District string `json:"district" validate:"omitempty,max=50" maxLength:"50" description:"区县"`
|
||||
Address string `json:"address" validate:"omitempty,max=255" maxLength:"255" description:"详细地址"`
|
||||
Status int `json:"status" validate:"required,oneof=0 1" required:"true" description:"状态 (0:禁用, 1:启用)"`
|
||||
ShopName string `json:"shop_name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"店铺名称"`
|
||||
BusinessOwnerAccountID *uint `json:"business_owner_account_id" nullable:"true" description:"平台业务员账号ID;缺失时保持不变,null 表示清空"`
|
||||
BusinessOwnerAccountIDSet bool `json:"-"`
|
||||
ContactName string `json:"contact_name" validate:"omitempty,max=50" maxLength:"50" description:"联系人姓名"`
|
||||
ContactPhone string `json:"contact_phone" validate:"omitempty,len=11" minLength:"11" maxLength:"11" description:"联系人电话"`
|
||||
Province string `json:"province" validate:"omitempty,max=50" maxLength:"50" description:"省份"`
|
||||
City string `json:"city" validate:"omitempty,max=50" maxLength:"50" description:"城市"`
|
||||
District string `json:"district" validate:"omitempty,max=50" maxLength:"50" description:"区县"`
|
||||
Address string `json:"address" validate:"omitempty,max=255" maxLength:"255" description:"详细地址"`
|
||||
Status int `json:"status" validate:"oneof=0 1" required:"true" description:"状态 (0:禁用, 1:启用)"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON 解析更新店铺请求并保留业务员字段“缺失”和“显式 null”的差异。
|
||||
func (r *UpdateShopRequest) UnmarshalJSON(data []byte) error {
|
||||
type plain UpdateShopRequest
|
||||
var decoded plain
|
||||
if err := sonic.Unmarshal(data, &decoded); err != nil {
|
||||
return err
|
||||
}
|
||||
var fields map[string]any
|
||||
if err := sonic.Unmarshal(data, &fields); err != nil {
|
||||
return err
|
||||
}
|
||||
decoded.BusinessOwnerAccountIDSet = false
|
||||
if _, exists := fields["business_owner_account_id"]; exists {
|
||||
decoded.BusinessOwnerAccountIDSet = true
|
||||
}
|
||||
*r = UpdateShopRequest(decoded)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShopResponse 店铺响应
|
||||
type ShopResponse struct {
|
||||
ID uint `json:"id" description:"店铺ID"`
|
||||
ShopName string `json:"shop_name" description:"店铺名称"`
|
||||
ShopCode string `json:"shop_code" description:"店铺编号"`
|
||||
ParentID *uint `json:"parent_id,omitempty" description:"上级店铺ID"`
|
||||
ParentShopName string `json:"parent_shop_name,omitempty" description:"上级店铺名称"`
|
||||
Level int `json:"level" description:"店铺层级 (1-7级)"`
|
||||
ContactName string `json:"contact_name" description:"联系人姓名"`
|
||||
ContactPhone string `json:"contact_phone" description:"联系人电话"`
|
||||
Province string `json:"province" description:"省份"`
|
||||
City string `json:"city" description:"城市"`
|
||||
District string `json:"district" description:"区县"`
|
||||
Address string `json:"address" description:"详细地址"`
|
||||
Status int `json:"status" description:"状态 (0:禁用, 1:启用)"`
|
||||
StatusName string `json:"status_name" description:"状态名称(中文)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
ID uint `json:"id" description:"店铺ID"`
|
||||
ShopName string `json:"shop_name" description:"店铺名称"`
|
||||
ShopCode string `json:"shop_code" description:"店铺编号"`
|
||||
ParentID *uint `json:"parent_id,omitempty" description:"上级店铺ID"`
|
||||
ParentShopName string `json:"parent_shop_name,omitempty" description:"上级店铺名称"`
|
||||
BusinessOwnerAccountID *uint `json:"business_owner_account_id" description:"平台业务员账号ID,null 表示未归属"`
|
||||
BusinessOwnerUsername string `json:"business_owner_username" description:"平台业务员账号名"`
|
||||
BusinessOwnerPhoneSummary string `json:"business_owner_phone_summary" description:"平台业务员手机号摘要(前三后四)"`
|
||||
BusinessOwnerAvailable bool `json:"business_owner_available" description:"平台业务员当前是否可用于通知接收"`
|
||||
Level int `json:"level" description:"店铺层级 (1-7级)"`
|
||||
ContactName string `json:"contact_name" description:"联系人姓名"`
|
||||
ContactPhone string `json:"contact_phone" description:"联系人电话"`
|
||||
Province string `json:"province" description:"省份"`
|
||||
City string `json:"city" description:"城市"`
|
||||
District string `json:"district" description:"区县"`
|
||||
Address string `json:"address" description:"详细地址"`
|
||||
Status int `json:"status" description:"状态 (0:禁用, 1:启用)"`
|
||||
StatusName string `json:"status_name" description:"状态名称(中文)"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
}
|
||||
|
||||
// ShopPageResult 店铺分页响应
|
||||
// ShopPageResult 店铺分页响应
|
||||
type ShopPageResult struct {
|
||||
Items []ShopResponse `json:"items" description:"店铺列表"`
|
||||
@@ -86,3 +134,50 @@ type ShopCascadeItem struct {
|
||||
ShopName string `json:"shop_name" description:"店铺名称"`
|
||||
HasChildren bool `json:"has_children" description:"是否有下级店铺"`
|
||||
}
|
||||
|
||||
// ShopBusinessOwnerCandidateRequest 是平台业务员候选分页查询。
|
||||
type ShopBusinessOwnerCandidateRequest struct {
|
||||
Keyword string `json:"keyword" query:"keyword" validate:"omitempty,max=50" maxLength:"50" description:"用户名或手机号关键词"`
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1,max=10000" minimum:"1" maximum:"10000" description:"页码,默认 1"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量,默认 20,最大 100"`
|
||||
}
|
||||
|
||||
// ShopBusinessOwnerCandidate 是平台业务员候选最小投影。
|
||||
type ShopBusinessOwnerCandidate struct {
|
||||
ID uint `json:"id" description:"平台业务员账号ID"`
|
||||
Username string `json:"username" description:"平台业务员账号名"`
|
||||
PhoneSummary string `json:"phone_summary" description:"手机号摘要(前三后四)"`
|
||||
}
|
||||
|
||||
// ShopBusinessOwnerCandidatePageResult 是平台业务员候选分页结果。
|
||||
type ShopBusinessOwnerCandidatePageResult struct {
|
||||
Items []ShopBusinessOwnerCandidate `json:"items" description:"候选账号列表"`
|
||||
Total int64 `json:"total" description:"总数量"`
|
||||
Page int `json:"page" description:"当前页码"`
|
||||
Size int `json:"size" description:"每页数量"`
|
||||
}
|
||||
|
||||
// UpdateShopCreditLimitRequest 调整既有店铺实际信用额度请求。
|
||||
type UpdateShopCreditLimitRequest struct {
|
||||
CreditEnabled *bool `json:"credit_enabled" validate:"required" required:"true" description:"是否启用实际信用额度"`
|
||||
CreditLimit *int64 `json:"credit_limit" validate:"required,min=0" required:"true" minimum:"0" description:"实际信用额度(分);关闭时必须为0"`
|
||||
Version *int `json:"version" validate:"required,min=0" required:"true" minimum:"0" description:"主钱包乐观锁版本"`
|
||||
}
|
||||
|
||||
// UpdateShopCreditLimitParams 调整既有店铺实际信用额度参数。
|
||||
type UpdateShopCreditLimitParams struct {
|
||||
IDReq
|
||||
UpdateShopCreditLimitRequest
|
||||
}
|
||||
|
||||
// ShopCreditLimitResponse 店铺实际信用额度调整响应。
|
||||
type ShopCreditLimitResponse struct {
|
||||
ShopID uint `json:"shop_id" description:"店铺ID"`
|
||||
WalletID uint `json:"wallet_id" description:"代理主钱包ID"`
|
||||
Balance int64 `json:"balance" description:"账面余额(分)"`
|
||||
FrozenBalance int64 `json:"frozen_balance" description:"冻结金额(分)"`
|
||||
CreditEnabled bool `json:"credit_enabled" description:"是否启用实际信用额度"`
|
||||
CreditLimit int64 `json:"credit_limit" description:"实际信用额度(分)"`
|
||||
AvailableBalance int64 `json:"available_balance" description:"总可用金额(分)"`
|
||||
Version int `json:"version" description:"更新后的主钱包版本"`
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ type IotCard struct {
|
||||
EnablePolling bool `gorm:"column:enable_polling;type:boolean;default:true;comment:是否参与轮询 true-参与 false-不参与" json:"enable_polling"`
|
||||
LastDataCheckAt *time.Time `gorm:"column:last_data_check_at;comment:最后一次流量检查时间" json:"last_data_check_at"`
|
||||
LastRealNameCheckAt *time.Time `gorm:"column:last_real_name_check_at;comment:最后一次实名检查时间" json:"last_real_name_check_at"`
|
||||
RealnameReversalCount int `gorm:"column:realname_reversal_count;type:int;default:0;not null;comment:实名逆转连续观测次数" json:"realname_reversal_count"`
|
||||
RealnameReversalStartedAt *time.Time `gorm:"column:realname_reversal_started_at;comment:实名逆转当前确认窗口开始时间" json:"realname_reversal_started_at,omitempty"`
|
||||
LastProtectCheckAt *time.Time `gorm:"column:last_protect_check_at;comment:上次保护期一致性检查时间" json:"last_protect_check_at"`
|
||||
LastCardStatusCheckAt *time.Time `gorm:"column:last_card_status_check_at;comment:最后一次卡状态检查时间" json:"last_card_status_check_at"`
|
||||
LastSyncTime *time.Time `gorm:"column:last_sync_time;comment:最后一次与Gateway同步时间" json:"last_sync_time"`
|
||||
@@ -56,8 +58,8 @@ type IotCard struct {
|
||||
LastGatewayReadingMB float64 `gorm:"column:last_gateway_reading_mb;type:float;not null;default:0;comment:运营商当前周期累计流量读数(MB,来自网关)" json:"last_gateway_reading_mb"`
|
||||
GatewayExtend string `gorm:"column:gateway_extend;type:text;not null;default:'';comment:Gateway 卡状态扩展字段,原样保存上游 extend,用于展示运营商侧实际停机原因" json:"gateway_extend"`
|
||||
// GatewayCardIMEI 为插拔卡业务中网关上报的设备 IMEI,非设备自身 IMEI,仅用于数据同步落库
|
||||
GatewayCardIMEI string `gorm:"column:gateway_card_imei;type:varchar(50);not null;default:'';comment:插拔卡业务 IMEI,网关卡状态接口同步,非设备 IMEI" json:"gateway_card_imei"`
|
||||
RealnamePolicy string `gorm:"column:realname_policy;type:varchar(20);default:'after_order';not null;comment:实名认证策略(none=无需实名,before_order=先实名后充值/购买,after_order=先充值/购买后实名)" json:"realname_policy"`
|
||||
GatewayCardIMEI string `gorm:"column:gateway_card_imei;type:varchar(50);not null;default:'';comment:插拔卡业务 IMEI,网关卡状态接口同步,非设备 IMEI" json:"gateway_card_imei"`
|
||||
RealnamePolicy string `gorm:"column:realname_policy;type:varchar(20);default:'after_order';not null;comment:实名认证策略(none=无需实名,before_order=先实名后充值/购买,after_order=先充值/购买后实名)" json:"realname_policy"`
|
||||
|
||||
// ICCID 双列存储,用于支持 19/20 位 ICCID 精确路由查询
|
||||
// 所有卡必须有 ICCID19;仅 20 位运营商卡有 ICCID20(19 位卡为 nil → 数据库 NULL)
|
||||
|
||||
28
internal/model/notification.go
Normal file
28
internal/model/notification.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// Notification 是站内通知的 PostgreSQL 持久化事实。
|
||||
type Notification struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
EventID string `gorm:"column:event_id;type:varchar(64);not null;uniqueIndex:uq_notification_event_recipient,priority:1" json:"event_id"`
|
||||
RecipientKind string `gorm:"column:recipient_kind;type:varchar(32);not null;uniqueIndex:uq_notification_event_recipient,priority:2" json:"recipient_kind"`
|
||||
RecipientID uint `gorm:"column:recipient_id;not null;uniqueIndex:uq_notification_event_recipient,priority:3" json:"recipient_id"`
|
||||
Category string `gorm:"column:category;type:varchar(32);not null" json:"category"`
|
||||
Type string `gorm:"column:type;type:varchar(100);not null" json:"type"`
|
||||
Severity string `gorm:"column:severity;type:varchar(16);not null" json:"severity"`
|
||||
Title string `gorm:"column:title;type:varchar(200);not null" json:"title"`
|
||||
Body string `gorm:"column:body;type:text;not null" json:"body"`
|
||||
RefType string `gorm:"column:ref_type;type:varchar(64);not null;default:''" json:"ref_type"`
|
||||
RefID string `gorm:"column:ref_id;type:varchar(128);not null;default:''" json:"ref_id"`
|
||||
RefKey string `gorm:"column:ref_key;type:varchar(128);not null;default:''" json:"ref_key"`
|
||||
IsRead bool `gorm:"column:is_read;not null;default:false" json:"is_read"`
|
||||
ReadAt *time.Time `gorm:"column:read_at;type:timestamptz" json:"read_at,omitempty"`
|
||||
ExpiresAt *time.Time `gorm:"column:expires_at;type:timestamptz" json:"expires_at,omitempty"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;autoCreateTime" json:"created_at"`
|
||||
}
|
||||
|
||||
// TableName 返回站内通知表名。
|
||||
func (Notification) TableName() string {
|
||||
return "tb_notification"
|
||||
}
|
||||
@@ -16,6 +16,8 @@ type Order struct {
|
||||
// 订单基础信息
|
||||
OrderNo string `gorm:"column:order_no;type:varchar(30);uniqueIndex:idx_order_no,where:deleted_at IS NULL;not null;comment:订单号(ORD+时间戳+6位随机数)" json:"order_no"`
|
||||
OrderType string `gorm:"column:order_type;type:varchar(20);not null;comment:订单类型 single_card-单卡购买 device-设备购买" json:"order_type"`
|
||||
// IdempotencyKey 仅用于订单创建事务防重,不向客户端暴露。
|
||||
IdempotencyKey string `gorm:"column:idempotency_key;type:varchar(64);not null;default:'';index:idx_order_idempotency_key;comment:订单创建幂等指纹(SHA-256)" json:"-"`
|
||||
|
||||
// 买家信息
|
||||
BuyerType string `gorm:"column:buyer_type;type:varchar(20);not null;comment:买家类型 personal-个人客户 agent-代理商" json:"buyer_type"`
|
||||
|
||||
@@ -9,10 +9,12 @@ type Role struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
|
||||
RoleName string `gorm:"column:role_name;not null;size:50;comment:角色名称" json:"role_name"`
|
||||
RoleDesc string `gorm:"column:role_desc;size:255;comment:角色描述" json:"role_desc"`
|
||||
RoleType int `gorm:"column:role_type;not null;index;comment:角色类型 1=平台角色 2=客户角色" json:"role_type"`
|
||||
Status int `gorm:"column:status;not null;default:1;comment:状态 0=禁用 1=启用" json:"status"`
|
||||
RoleName string `gorm:"column:role_name;not null;size:50;comment:角色名称" json:"role_name"`
|
||||
RoleDesc string `gorm:"column:role_desc;size:255;comment:角色描述" json:"role_desc"`
|
||||
RoleType int `gorm:"column:role_type;not null;index;comment:角色类型 1=平台角色 2=客户角色" json:"role_type"`
|
||||
Status int `gorm:"column:status;not null;default:1;comment:状态 0=禁用 1=启用" json:"status"`
|
||||
DefaultCreditEnabled bool `gorm:"column:default_credit_enabled;type:boolean;not null;default:false;comment:是否启用新建代理默认信用" json:"default_credit_enabled"`
|
||||
DefaultCreditLimit int64 `gorm:"column:default_credit_limit;type:bigint;not null;default:0;comment:新建代理默认信用额度(单位:分)" json:"default_credit_limit"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
@@ -7,18 +7,19 @@ import (
|
||||
// Shop 店铺模型
|
||||
type Shop struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
ShopName string `gorm:"column:shop_name;type:varchar(100);not null;comment:店铺名称" json:"shop_name"`
|
||||
ShopCode string `gorm:"column:shop_code;type:varchar(50);uniqueIndex:idx_shop_code,where:deleted_at IS NULL;comment:店铺编号" json:"shop_code"`
|
||||
ParentID *uint `gorm:"column:parent_id;index;comment:上级店铺ID(NULL表示一级代理)" json:"parent_id,omitempty"`
|
||||
Level int `gorm:"column:level;type:int;not null;default:1;comment:层级(1-7)" json:"level"`
|
||||
ContactName string `gorm:"column:contact_name;type:varchar(50);comment:联系人姓名" json:"contact_name"`
|
||||
ContactPhone string `gorm:"column:contact_phone;type:varchar(20);comment:联系人电话" json:"contact_phone"`
|
||||
Province string `gorm:"column:province;type:varchar(50);comment:省份" json:"province"`
|
||||
City string `gorm:"column:city;type:varchar(50);comment:城市" json:"city"`
|
||||
District string `gorm:"column:district;type:varchar(50);comment:区县" json:"district"`
|
||||
Address string `gorm:"column:address;type:varchar(255);comment:详细地址" json:"address"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:状态 0=禁用 1=启用" json:"status"`
|
||||
BaseModel `gorm:"embedded"`
|
||||
ShopName string `gorm:"column:shop_name;type:varchar(100);not null;comment:店铺名称" json:"shop_name"`
|
||||
ShopCode string `gorm:"column:shop_code;type:varchar(50);uniqueIndex:idx_shop_code,where:deleted_at IS NULL;comment:店铺编号" json:"shop_code"`
|
||||
ParentID *uint `gorm:"column:parent_id;index;comment:上级店铺ID(NULL表示一级代理)" json:"parent_id,omitempty"`
|
||||
BusinessOwnerAccountID *uint `gorm:"column:business_owner_account_id;index:idx_shop_business_owner_account_id;comment:平台业务员账号ID" json:"business_owner_account_id,omitempty"`
|
||||
Level int `gorm:"column:level;type:int;not null;default:1;comment:层级(1-7)" json:"level"`
|
||||
ContactName string `gorm:"column:contact_name;type:varchar(50);comment:联系人姓名" json:"contact_name"`
|
||||
ContactPhone string `gorm:"column:contact_phone;type:varchar(20);comment:联系人电话" json:"contact_phone"`
|
||||
Province string `gorm:"column:province;type:varchar(50);comment:省份" json:"province"`
|
||||
City string `gorm:"column:city;type:varchar(50);comment:城市" json:"city"`
|
||||
District string `gorm:"column:district;type:varchar(50);comment:区县" json:"district"`
|
||||
Address string `gorm:"column:address;type:varchar(255);comment:详细地址" json:"address"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:状态 0=禁用 1=启用" json:"status"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
Reference in New Issue
Block a user