feat: 支付闭环

This commit is contained in:
Blizzard
2026-03-04 17:05:48 +08:00
parent 042c99aa46
commit 7a32f8a351
31 changed files with 902 additions and 503 deletions
+4 -9
View File
@@ -2,20 +2,15 @@ package radio
import (
"sundynix-go/global"
"sundynix-go/model/system"
)
// RadioCategory 电台分类表
type RadioCategory struct {
global.BaseModel
Name string `gorm:"size:50" json:"name"` // 分类名称
Description string `gorm:"size:255" json:"description"` // 分类描述
IconId string `gorm:"size:50" json:"iconId"` // 图标OSS ID
Icon *system.Oss `gorm:"foreignKey:IconId" json:"icon"` // 图标OSS
CoverId string `gorm:"size:50" json:"coverId"` // 封面图OSS ID
Cover *system.Oss `gorm:"foreignKey:CoverId" json:"cover"` // 封面图OSS
Sort int `gorm:"default:0" json:"sort"` // 排序
Status int `gorm:"default:1" json:"status"` // 状态 0:禁用 1:启用
Name string `gorm:"size:50" json:"name"` // 分类名称
Description string `gorm:"size:255" json:"description"` // 分类描述
Sort int `gorm:"default:0" json:"sort"` // 排序
Status int `gorm:"default:1" json:"status"` // 状态 0:禁用 1:启用
Channels []*RadioChannel `gorm:"foreignKey:CategoryId" json:"channels"`
}
+3 -3
View File
@@ -2,7 +2,7 @@ package radio
import (
"sundynix-go/global"
"sundynix-go/model/system"
"time"
)
// RadioChannel 电台频道表
@@ -16,12 +16,12 @@ type RadioChannel struct {
MonthlyPrice int `gorm:"default:0;comment:价格,单位,分 " json:"monthlyPrice"` //包月价格 单位:分
QuarterlyPrice int `gorm:"default:0;comment:价格,单位,分 " json:"quarterlyPrice"` //包季度价格 单位:分
AnnualPrice int `gorm:"default:0;comment:价格,单位,分 " json:"annualPrice"` //包年价格 单位:分
CoverId string `gorm:"size:50" json:"coverId"` // 封面图OSS ID
Cover *system.Oss `gorm:"foreignKey:CoverId" json:"cover"` // 封面图OSS
Cover string `gorm:"size:100" json:"cover"` // 封面emoji
Tags string `gorm:"size:255" json:"tags"` // 标签,逗号分隔
Sort int `gorm:"default:0" json:"sort"` // 排序
Status int `gorm:"default:1" json:"status"` // 状态 0:禁用 1:启用
HasSubscribed int `gorm:"-" json:"hasSubscribed"` // 状态 0:未订阅 1:已订阅
ExpiredAt *time.Time `gorm:"-" json:"expiredAt"` // 新增:过期时间,使用指针方便处理 null
Programs []*RadioProgram `gorm:"foreignKey:ChannelId" json:"programs"` //频道下的节目
}
+22
View File
@@ -0,0 +1,22 @@
package radio
import "sundynix-go/global"
type PayNotify struct {
global.BaseModel
Amount int64 `json:"amount" gorm:"column:amount"`
Currency string `json:"currency" gorm:"column:currency"`
PayerCurrency string `json:"payer_currency" gorm:"column:payer_currency"`
PayerTotal int64 `json:"payer_total" gorm:"column:payer_total"`
Appid string `json:"appId" gorm:"column:app_id"`
Attach string `json:"attach" gorm:"column:attach"`
BankType string `json:"bank_type" gorm:"column:bank_type"`
MchId string `json:"mchId" gorm:"column:mch_id"`
OutTradeNo string `json:"out_trade_no" gorm:"column:out_trade_no"`
Payer string `json:"payer" gorm:"column:out_trade_no"`
SuccessTime string `json:"success_time" gorm:"column:success_time"`
TradeState string `json:"trade_state" gorm:"column:trade_state"`
TradeStateDesc string `json:"trade_state_desc" gorm:"column:trade_state_desc"`
TradeType string `json:"trade_type" gorm:"column:trade_type"`
TransactionId string `json:"transaction_id" gorm:"column:transaction_id"`
}
+1 -2
View File
@@ -12,8 +12,7 @@ type RadioProgram struct {
Title string `gorm:"size:100" json:"title"` // 节目标题
Description string `gorm:"size:500" json:"description"` // 节目描述
Content string `gorm:"type:text" json:"content"`
CoverId string `gorm:"size:50" json:"coverId"` // 封面图OSS ID
Cover *system.Oss `gorm:"foreignKey:CoverId" json:"cover"` // 封面图OSS
Cover string `gorm:"size:100" json:"cover"` // 封面图emoji
AudioId string `gorm:"size:50" json:"audioId"` // 音频OSS ID
Audio *system.Oss `gorm:"foreignKey:AudioId" json:"audio"` // 音频OSS
Duration int `gorm:"default:0" json:"duration"` // 时长(秒)
+5 -3
View File
@@ -2,14 +2,16 @@ package radio
import (
"sundynix-go/global"
"time"
)
// RadioSubscription 用户订阅表
type RadioSubscription struct {
global.BaseModel
UserId string `gorm:"size:50;index;not null;uniqueIndex:idx_user_channel" json:"userId"` // 用户ID
ChannelId string `gorm:"size:50;index;uniqueIndex:idx_user_channel" json:"channelId"` // 频道ID
Status int `gorm:"type:tinyint;default:1"` //1-订阅中,2-已取消
UserId string `gorm:"size:50;index;not null;" json:"userId"` // 用户ID
ChannelId string `gorm:"size:50;index;" json:"channelId"` // 频道ID
ExpiredAt time.Time `gorm:"index"`
Status int `gorm:"type:tinyint;default:1"` //1-订阅中,2-已到期
Channel *RadioChannel `gorm:"foreignKey:ChannelId" json:"channel"`
}
+19
View File
@@ -0,0 +1,19 @@
package radio
import (
"sundynix-go/global"
"sundynix-go/model/system"
)
type Order struct {
global.BaseModel
OutTradeNo string `json:"outTradeNo" gorm:"index;column:out_trade_no;comment:商户订单号"`
UserId string `json:"userId" form:"userId" gorm:"index;column:user_id;comment:用户id"`
ChannelId string `gorm:"column:channel_id"`
SubscriptionType string `gorm:"column:sub_type;comment:1:月,2:季,3:年"`
Name string `json:"name" gorm:"column:name;comment:订单名称"`
Amount int `json:"amount" gorm:"column:amount;comment:金额分"`
Status int `json:"status" gorm:"column:status;comment:订单状态"` // 0:待支付 1:已支付 2:已关闭
PayStatus string `json:"payStatus" gorm:"column:pay_status;comment:支付状态"`
User *system.User `json:"user" gorm:"foreignKey:UserId"`
}
-4
View File
@@ -13,8 +13,6 @@ type GetCategoryList struct {
type SaveCategory struct {
Name string `json:"name" binding:"required"` // 分类名称
Description string `json:"description"` // 分类描述
IconId string `json:"iconId"` // 图标URL
CoverId string `json:"coverId"` // 封面图URL
Sort int `json:"sort"` // 排序
Status int `json:"status"` // 状态
}
@@ -24,8 +22,6 @@ type UpdateCategory struct {
Id string `json:"id" binding:"required"` // 分类ID
Name string `json:"name"` // 分类名称
Description string `json:"description"` // 分类描述
IconId string `json:"iconId"` // 图标URL
CoverId string `json:"coverId"` // 封面图URL
Sort int `json:"sort"` // 排序
Status int `json:"status"` // 状态
}
+7 -2
View File
@@ -15,7 +15,7 @@ type SaveChannel struct {
CategoryId string `json:"categoryId" binding:"required"` // 分类ID
Name string `json:"name" binding:"required"` // 频道名称
Description string `json:"description"` // 频道描述
CoverId string `json:"coverId"` // 封面图URL
Cover string `json:"cover"` // 封面图URL
Tags string `json:"tags"` // 标签
IsFree int `json:"isFree"` //是否永久免费
IsVipOnly int `json:"isVipOnly"` //是否vip专享
@@ -32,7 +32,7 @@ type UpdateChannel struct {
CategoryId string `json:"categoryId"` // 分类ID
Name string `json:"name"` // 频道名称
Description string `json:"description"` // 频道描述
CoverId string `json:"coverId"` // 封面图URL
Cover string `json:"cover"` // 封面图URL
Tags string `json:"tags"` // 标签
IsFree int `json:"isFree"`
IsVipOnly int `json:"isVipOnly"` //是否vip专享
@@ -42,3 +42,8 @@ type UpdateChannel struct {
Sort int `json:"sort"` // 排序
Status int `json:"status"` // 状态
}
type UnlockChannel struct {
ChannelId string `json:"channelId" binding:"required"`
EventType string `json:"type" binding:"required"` // 1 月 2 季 3 年
}
+2 -2
View File
@@ -16,7 +16,7 @@ type SaveProgram struct {
Title string `json:"title" binding:"required"` // 节目标题
Description string `json:"description"` // 节目描述
Content string `json:"content"`
CoverId string `json:"coverId"` // 封面图URL
Cover string `json:"cover"` // 封面图URL
AudioId string `json:"audioId"` // 音频URL
Duration int `json:"duration"` // 时长(秒)
Tags string `json:"tags"` // 标签
@@ -30,7 +30,7 @@ type UpdateProgram struct {
Title string `json:"title"` // 节目标题
Description string `json:"description"` // 节目描述
Content string `json:"content"`
CoverId string `json:"coverId"` // 封面图URL
Cover string `json:"cover"` // 封面图URL
AudioId string `json:"audioId"` // 音频URL
Duration int `json:"duration"` // 时长(秒)
Tags string `json:"tags"` // 标签
-20
View File
@@ -1,7 +1,5 @@
package response
import "sundynix-go/model/radio"
// CategoryResponse 分类响应
type CategoryResponse struct {
Id string `json:"id"`
@@ -23,21 +21,3 @@ type CategoryDetailResponse struct {
Sort int `json:"sort"`
Status int `json:"status"`
}
// ToCategoryResponse 转换为分类响应
func ToCategoryResponse(category *radio.RadioCategory) CategoryResponse {
resp := CategoryResponse{
Id: category.Id,
Name: category.Name,
Description: category.Description,
Sort: category.Sort,
Status: category.Status,
}
if category.Icon != nil {
resp.Icon = category.Icon.Url
}
if category.Cover != nil {
resp.CoverUrl = category.Cover.Url
}
return resp
}
+8
View File
@@ -0,0 +1,8 @@
package response
import "github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
type PrePayResult struct {
Payments *jsapi.PrepayWithRequestPaymentResponse `json:"payments"`
OutTradeNo string `json:"outTradeNo"`
}