refactor(pricing): entity/DTO 换 subject_type+subject_id(含 subject_dto 枚举 DTO)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
|
||||
pricingConsts "shop-user-trade/consts/pricing"
|
||||
)
|
||||
|
||||
// ====================== 建单(不动钱) ======================
|
||||
|
||||
// OpenOrderReq 建单请求(执行开始调用,只建单不动钱),幂等键 subjectType+subjectId+bizOrderNo
|
||||
type OpenOrderReq struct {
|
||||
g.Meta `path:"/open_order" method:"post" tags:"计价扣费" summary:"建单" dc:"执行开始建计费单(不动钱),幂等键 subjectType+subjectId+bizOrderNo"`
|
||||
|
||||
UserId int64 `json:"userId" v:"required|min:1" dc:"用户ID"`
|
||||
SubjectType string `json:"subjectType" v:"required|in:workflow,model,business" dc:"计价对象类型"`
|
||||
SubjectID string `json:"subjectId" v:"required" dc:"计价对象ID"`
|
||||
ChargeMode string `json:"chargeMode" dc:"计费方式:workflow 必填(rules 已配三模式之一);model/business 可空(默认取 unit/per_period)"`
|
||||
BizOrderNo string `json:"bizOrderNo" v:"required" dc:"业务单据号(幂等键,如工作流 execId)"`
|
||||
}
|
||||
|
||||
// ====================== 结算(成功:按最终产出) ======================
|
||||
|
||||
// SettleReq 结算请求(按实际用量计价实收,余额不足允许为负)
|
||||
type SettleReq struct {
|
||||
g.Meta `path:"/settle" method:"post" tags:"计价扣费" summary:"结算" dc:"按实际用量计价实收(允许负余额),幂等"`
|
||||
|
||||
OrderId int64 `json:"orderId" dc:"计费单ID(与 subjectType+subjectId+bizOrderNo 二选一)"`
|
||||
SubjectType string `json:"subjectType" dc:"计价对象类型(orderId 为空时必填)"`
|
||||
SubjectID string `json:"subjectId" dc:"计价对象ID(orderId 为空时必填)"`
|
||||
BizOrderNo string `json:"bizOrderNo" dc:"业务单据号(orderId 为空时必填)"`
|
||||
Usage string `json:"usage" v:"required" dc:"用量JSON:{durationSec,itemCount,tokensByModel,...}"`
|
||||
}
|
||||
|
||||
// ====================== 取消(按已消耗用量结算) ======================
|
||||
|
||||
// CancelReq 取消请求(中途取消按已消耗用量计价扣费,非退款)
|
||||
type CancelReq struct {
|
||||
g.Meta `path:"/cancel" method:"post" tags:"计价扣费" summary:"取消" dc:"中途取消按已消耗用量计价实收(非退款),幂等"`
|
||||
|
||||
OrderId int64 `json:"orderId" dc:"计费单ID(与 subjectType+subjectId+bizOrderNo 二选一)"`
|
||||
SubjectType string `json:"subjectType" dc:"计价对象类型(orderId 为空时必填)"`
|
||||
SubjectID string `json:"subjectId" dc:"计价对象ID(orderId 为空时必填)"`
|
||||
BizOrderNo string `json:"bizOrderNo" dc:"业务单据号(orderId 为空时必填)"`
|
||||
Usage string `json:"usage" v:"required" dc:"已消耗用量JSON"`
|
||||
}
|
||||
|
||||
// ====================== 失败(不扣费) ======================
|
||||
|
||||
// FailReq 失败请求(执行失败/无产出,不扣费)
|
||||
type FailReq struct {
|
||||
g.Meta `path:"/fail" method:"post" tags:"计价扣费" summary:"失败处理" dc:"执行失败/无产出,不扣费,幂等"`
|
||||
|
||||
OrderId int64 `json:"orderId" dc:"计费单ID(与 subjectType+subjectId+bizOrderNo 二选一)"`
|
||||
SubjectType string `json:"subjectType" dc:"计价对象类型(orderId 为空时必填)"`
|
||||
SubjectID string `json:"subjectId" dc:"计价对象ID(orderId 为空时必填)"`
|
||||
BizOrderNo string `json:"bizOrderNo" dc:"业务单据号(orderId 为空时必填)"`
|
||||
Reason string `json:"reason" dc:"失败原因"`
|
||||
}
|
||||
|
||||
// ====================== 查询 ======================
|
||||
|
||||
// GetOrderReq 查询计费单请求
|
||||
type GetOrderReq struct {
|
||||
g.Meta `path:"/get_order" method:"get" tags:"计价扣费" summary:"查询计费单" dc:"按ID或 subjectType+subjectId+bizOrderNo 查询"`
|
||||
|
||||
OrderId int64 `json:"orderId" dc:"计费单ID(与 subjectType+subjectId+bizOrderNo 二选一)"`
|
||||
SubjectType string `json:"subjectType" dc:"计价对象类型(orderId 为空时必填)"`
|
||||
SubjectID string `json:"subjectId" dc:"计价对象ID(orderId 为空时必填)"`
|
||||
BizOrderNo string `json:"bizOrderNo" dc:"业务单据号(orderId 为空时必填)"`
|
||||
}
|
||||
|
||||
// ListOrdersReq 分页查询计费单请求
|
||||
type ListOrdersReq struct {
|
||||
g.Meta `path:"/orders" method:"get" tags:"计价扣费" summary:"分页查询计费单" dc:"按用户分页查询计费单"`
|
||||
|
||||
UserId int64 `json:"userId" v:"required|min:1" dc:"用户ID"`
|
||||
Page int `json:"page" v:"required|min:1" dc:"页码"`
|
||||
PageSize int `json:"pageSize" v:"required|min:1|max:100" dc:"每页大小"`
|
||||
}
|
||||
|
||||
// ChargeOrderList 计费单列表
|
||||
type ChargeOrderList struct {
|
||||
Orders []ChargeOrderInfo `json:"orders"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// ChargeOrderInfo 计费单信息
|
||||
type ChargeOrderInfo struct {
|
||||
ID int64 `json:"id"`
|
||||
SubjectType string `json:"subjectType"`
|
||||
SubjectID string `json:"subjectId"`
|
||||
BizOrderNo string `json:"bizOrderNo"`
|
||||
UserId int64 `json:"userId"`
|
||||
ChargeMode string `json:"chargeMode"`
|
||||
Status int `json:"status"` // 1已建单 2已结算 3已失败
|
||||
ActualAmount float64 `json:"actualAmount"`
|
||||
Usage string `json:"usage"`
|
||||
RuleSnapshot string `json:"ruleSnapshot"`
|
||||
SettleTime string `json:"settleTime"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
|
||||
// ====================== DAO 入参(统一吃 DTO,同 model-gateway) ======================
|
||||
|
||||
// GetChargeOrderReq DAO 查询计费单:Id 与 SubjectType+SubjectID+BizOrderNo 二选一
|
||||
type GetChargeOrderReq struct {
|
||||
Id int64 `json:"id"`
|
||||
SubjectType string `json:"subjectType"`
|
||||
SubjectID string `json:"subjectId"`
|
||||
BizOrderNo string `json:"bizOrderNo"`
|
||||
}
|
||||
|
||||
// CreateChargeOrderReq DAO 创建计费单
|
||||
type CreateChargeOrderReq struct {
|
||||
SubjectType pricingConsts.SubjectType `json:"subjectType"`
|
||||
SubjectID string `json:"subjectId"`
|
||||
BizOrderNo string `json:"bizOrderNo"`
|
||||
UserId int64 `json:"userId"`
|
||||
ChargeMode pricingConsts.ChargeMode `json:"chargeMode"`
|
||||
Status pricingConsts.ChargeOrderStatus `json:"status"`
|
||||
RuleSnapshot string `json:"ruleSnapshot"`
|
||||
}
|
||||
|
||||
// SettleChargeOrderReq DAO 结算迁移(CREATED→SETTLED,条件更新幂等)
|
||||
type SettleChargeOrderReq struct {
|
||||
Id int64 `json:"id"`
|
||||
ActualAmount float64 `json:"actualAmount"`
|
||||
Usage string `json:"usage"`
|
||||
RuleSnapshot string `json:"ruleSnapshot"`
|
||||
SettleTime *gtime.Time `json:"settleTime"`
|
||||
}
|
||||
|
||||
// FailChargeOrderReq DAO 失败迁移(CREATED→FAILED,条件更新幂等)
|
||||
type FailChargeOrderReq struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// ====================== 配置管理 ======================
|
||||
|
||||
// SaveConfigReq 新增/更新计价配置请求(费率全 DB 配置,改价/加档只改 rules)
|
||||
type SaveConfigReq struct {
|
||||
g.Meta `path:"/config/save" method:"post" tags:"计价配置" summary:"保存计价配置" dc:"新增或更新计价配置(subject_type+subject_id 唯一)"`
|
||||
|
||||
Id int64 `json:"id" dc:"配置ID(>0 更新,0 新增)"`
|
||||
SubjectType string `json:"subjectType" v:"required|in:workflow,model,business" dc:"计价对象类型"`
|
||||
SubjectID string `json:"subjectId" v:"required" dc:"计价对象ID"`
|
||||
Rules string `json:"rules" v:"required" dc:"费率JSON(见设计§4)"`
|
||||
MinBalance float64 `json:"minBalance" dc:"门禁:调用前可用余额须>=该值(元),0=不校验"`
|
||||
Currency string `json:"currency" dc:"货币类型,默认CNY"`
|
||||
Enabled int `json:"enabled" dc:"1启用 0停用"`
|
||||
}
|
||||
|
||||
// SaveConfigData 保存计价配置数据
|
||||
type SaveConfigData struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
|
||||
// GetConfigReq 查询计价配置请求
|
||||
type GetConfigReq struct {
|
||||
g.Meta `path:"/config/get" method:"get" tags:"计价配置" summary:"查询计价配置" dc:"按 subjectType+subjectId 查询计价配置"`
|
||||
|
||||
SubjectType string `json:"subjectType" v:"required" dc:"计价对象类型"`
|
||||
SubjectID string `json:"subjectId" v:"required" dc:"计价对象ID"`
|
||||
}
|
||||
|
||||
// ListConfigsReq 分页查询计价配置请求
|
||||
type ListConfigsReq struct {
|
||||
g.Meta `path:"/config/list" method:"get" tags:"计价配置" summary:"分页查询计价配置" dc:"可按 subjectType/enabled 过滤"`
|
||||
|
||||
SubjectType string `json:"subjectType" dc:"计价对象类型"`
|
||||
Enabled int `json:"enabled" dc:"1启用 0停用,0不过滤"`
|
||||
Page int `json:"page" v:"required|min:1" dc:"页码"`
|
||||
PageSize int `json:"pageSize" v:"required|min:1|max:100" dc:"每页大小"`
|
||||
}
|
||||
|
||||
// PricingConfigList 计价配置列表
|
||||
type PricingConfigList struct {
|
||||
Configs []PricingConfigInfo `json:"configs"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
// PricingConfigInfo 计价配置信息
|
||||
type PricingConfigInfo struct {
|
||||
ID int64 `json:"id"`
|
||||
SubjectType string `json:"subjectType"`
|
||||
SubjectID string `json:"subjectId"`
|
||||
Rules string `json:"rules"`
|
||||
MinBalance float64 `json:"minBalance"`
|
||||
Currency string `json:"currency"`
|
||||
Enabled int `json:"enabled"`
|
||||
Version int64 `json:"version"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// SubjectsReq 计价对象枚举请求
|
||||
type SubjectsReq struct {
|
||||
g.Meta `path:"/subjects" method:"get" tags:"计价配置" summary:"计价对象枚举" dc:"workflow + 实时model-gateway系统模型 + 固定业务模块"`
|
||||
}
|
||||
|
||||
// SubjectInfo 计价对象枚举项
|
||||
type SubjectInfo struct {
|
||||
SubjectType string `json:"subjectType"`
|
||||
SubjectID string `json:"subjectId"`
|
||||
Name string `json:"name"`
|
||||
ModelType string `json:"modelType,omitempty"` // 模型类型名(管理端分组展示,如 推理/视频)
|
||||
ModelTypeCode int `json:"modelTypeCode,omitempty"` // 模型类型编码:100推理/200图片/300音频/600视频
|
||||
ChargeModes []string `json:"chargeModes,omitempty"` // workflow/business 用(可选的计费方式)
|
||||
HasConfig bool `json:"hasConfig"` // 是否已配置价格
|
||||
Enabled int `json:"enabled"` // 已配置时的启用状态
|
||||
}
|
||||
|
||||
// SubjectListRes 计价对象枚举响应
|
||||
type SubjectListRes struct {
|
||||
Subjects []SubjectInfo `json:"subjects"`
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
pricingConsts "shop-user-trade/consts/pricing"
|
||||
|
||||
"gitea.redpowerfuture.com/red-future/common/beans"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type chargeOrderCol struct {
|
||||
beans.SQLBaseCol
|
||||
SubjectType string
|
||||
SubjectID string
|
||||
BizOrderNo string
|
||||
UserId string
|
||||
ChargeMode string
|
||||
Status string
|
||||
ActualAmount string
|
||||
Usage string
|
||||
RuleSnapshot string
|
||||
SettleTime string
|
||||
}
|
||||
|
||||
var ChargeOrderCol = chargeOrderCol{
|
||||
SQLBaseCol: beans.DefSQLBaseCol,
|
||||
SubjectType: "subject_type",
|
||||
SubjectID: "subject_id",
|
||||
BizOrderNo: "biz_order_no",
|
||||
UserId: "user_id",
|
||||
ChargeMode: "charge_mode",
|
||||
Status: "status",
|
||||
ActualAmount: "actual_amount",
|
||||
Usage: "usage",
|
||||
RuleSnapshot: "rule_snapshot",
|
||||
SettleTime: "settle_time",
|
||||
}
|
||||
|
||||
// ChargeOrder 计费单实体:一次计价调用 = 一张计费单(幂等键 subject_type+subject_id+biz_order_no)
|
||||
// 状态机:CREATED(已建单,不动钱) → SETTLED(已结算) / FAILED(已失败,不扣费)
|
||||
type ChargeOrder struct {
|
||||
beans.SQLBaseDO `orm:",inherit"`
|
||||
|
||||
SubjectType pricingConsts.SubjectType `orm:"subject_type" json:"subjectType" description:"计价对象类型"`
|
||||
SubjectID string `orm:"subject_id" json:"subjectId" description:"计价对象ID"`
|
||||
BizOrderNo string `orm:"biz_order_no" json:"bizOrderNo" description:"业务单据号(幂等键,如工作流 execId)"`
|
||||
UserId int64 `orm:"user_id" json:"userId,string" description:"扣费用户ID"`
|
||||
ChargeMode pricingConsts.ChargeMode `orm:"charge_mode" json:"chargeMode" description:"计费方式(建单快照)"`
|
||||
Status pricingConsts.ChargeOrderStatus `orm:"status" json:"status" description:"状态:1已建单 2已结算 3已失败"`
|
||||
ActualAmount float64 `orm:"actual_amount" json:"actualAmount" description:"实收金额(元,保留2位小数)"`
|
||||
Usage string `orm:"usage" json:"usage" description:"实际用量JSON"`
|
||||
RuleSnapshot string `orm:"rule_snapshot" json:"ruleSnapshot" description:"结算用费率快照JSON(防改价影响在途单)"`
|
||||
SettleTime *gtime.Time `orm:"settle_time" json:"settleTime" description:"结算时间"`
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
pricingConsts "shop-user-trade/consts/pricing"
|
||||
|
||||
"gitea.redpowerfuture.com/red-future/common/beans"
|
||||
)
|
||||
|
||||
type pricingConfigCol struct {
|
||||
beans.SQLBaseCol
|
||||
SubjectType string
|
||||
SubjectID string
|
||||
Rules string
|
||||
MinBalance string
|
||||
Currency string
|
||||
Enabled string
|
||||
Version string
|
||||
}
|
||||
|
||||
var PricingConfigCol = pricingConfigCol{
|
||||
SQLBaseCol: beans.DefSQLBaseCol,
|
||||
SubjectType: "subject_type",
|
||||
SubjectID: "subject_id",
|
||||
Rules: "rules",
|
||||
MinBalance: "min_balance",
|
||||
Currency: "currency",
|
||||
Enabled: "enabled",
|
||||
Version: "version",
|
||||
}
|
||||
|
||||
// PricingConfig 计价配置实体(费率全 DB 配置,改价/加档只改 rules,代码不写死金额)
|
||||
type PricingConfig struct {
|
||||
beans.SQLBaseDO `orm:",inherit"`
|
||||
|
||||
SubjectType pricingConsts.SubjectType `orm:"subject_type" json:"subjectType" description:"计价对象类型:workflow/model/business"`
|
||||
SubjectID string `orm:"subject_id" json:"subjectId" description:"计价对象ID(workflow/模型ID/业务模块标识)"`
|
||||
Rules string `orm:"rules" json:"rules" description:"费率JSON(见设计§4,rules 自描述不再有 charge_mode 列)"`
|
||||
MinBalance float64 `orm:"min_balance" json:"minBalance" description:"门禁:调用前可用余额须>=该值(元),0=不校验"`
|
||||
Currency string `orm:"currency" json:"currency" description:"货币类型"`
|
||||
Enabled int `orm:"enabled" json:"enabled" description:"1启用 0停用"`
|
||||
Version int64 `orm:"version" json:"version" description:"乐观锁版本号"`
|
||||
}
|
||||
|
||||
// Unit 从 rules 中解析模型计费单位(仅 subject_type=model 有效,其余返回空)。
|
||||
// service 层 per_token 结算/建单解析计费方式时使用,避免重复解析 rules。
|
||||
func (e *PricingConfig) Unit() pricingConsts.ChargeMode {
|
||||
var cfg struct {
|
||||
Unit pricingConsts.ChargeMode `json:"unit"`
|
||||
}
|
||||
if err := json.Unmarshal([]byte(e.Rules), &cfg); err != nil {
|
||||
return ""
|
||||
}
|
||||
return cfg.Unit
|
||||
}
|
||||
Reference in New Issue
Block a user