Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+174
View File
@@ -0,0 +1,174 @@
package exchcodemod
import (
"fmt"
"time"
"91porn-server/common"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"91porn-server/models/commod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const table = models.ExchCode
// initIndex 设置index
func initIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "code", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "batchNum", Value: 1}, {Key: "createdAt", Value: 1}},
},
{
Keys: bson.D{{Key: "app", Value: 1}, {Key: "createdAt", Value: 1}},
},
{
Keys: bson.D{{Key: "channel", Value: 1}, {Key: "createdAt", Value: 1}},
},
{
Keys: bson.D{{Key: "authority", Value: 1}, {Key: "createdAt", Value: 1}},
},
{
Keys: bson.D{{Key: "status", Value: 1}, {Key: "createdAt", Value: 1}},
},
{
Keys: bson.D{{Key: "createdAt", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
func BulkWrite(docs []ExchCode) error {
writeModels := make([]mongo.WriteModel, len(docs))
for i, doc := range docs {
writeModels[i] = mongo.NewInsertOneModel().SetDocument(doc)
}
if _, err := coll(nil).Bulk(writeModels); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "BulkWrite", table, "Bulk", err))
return err
}
return nil
}
func Insert(e ExchCode) error {
if _, err := coll(nil).InsertOne(e); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return err
}
return nil
}
// 获取兑换码
func GetExchangeCodeByCode(code string) (data *ExchCode, err error) {
if err = coll(nil).FindOne(&data, bson.M{"code": code}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetExchangeCodeByCode", table, "FindOne", err),
log.Any("code", code),
)
return
}
return
}
// 获取兑换码
func GetExchangeCodeByID(id ObjectID) (data *ExchCode, err error) {
if err = coll(nil).FindOne(&data, bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetExchangeCodeByCode", table, "FindOne", err),
log.Any("id", id),
)
return
}
return
}
// 兑换
func Exchange(code string) (err error) {
if _, err = coll(nil).UpdateOne(bson.M{"code": code}, bson.M{"$inc": bson.M{"usableNum": -1}, "$set": bson.M{"updatedAt": time.Now()}}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Exchange", table, "UpdateOne", err),
log.Any("code", code),
)
return
}
return
}
// 获取推广码列表
func GetCodeList(filterParams FilterDoc, status *ExchangeStatus, page commod.Page, isSuperAdmin bool) (total int64, data []ExchCode, err error) {
filter, _ := common.ToBsonM(filterParams)
if !isSuperAdmin {
filter["authority"] = bson.M{"$ne": AuthorityGold}
}
if status != nil {
switch *status {
case StatusExpired:
filter["invalidAt"] = bson.M{"$lt": time.Now()}
case StatusUnused:
filter["invalidAt"] = bson.M{"$gte": time.Now()}
filter["status"] = *status
case StatusUsed:
filter["status"] = *status
}
}
var skip = int64((page.PageNumber - 1) * page.PageSize)
var limit = int64(page.PageSize)
var opts = options.Find()
opts.SetSort(bson.D{{Key: "createdAt", Value: -1}}).SetSkip(skip).SetLimit(limit)
if err = coll(nil).Find(&data, filter, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCodeList", table, "Find", err),
log.Any("queryParams", filterParams),
log.Any("page", page),
)
return
}
if total, err = coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCodeList", table, "Count", err),
log.Any("queryParams", filterParams),
log.Any("page", page),
)
return
}
return
}
func UpdateExchangeCode(id ObjectID, doc UpdateDoc) (err error) {
update, _ := common.ToBsonM(doc)
if _, err = coll(nil).UpdateOne(bson.M{"_id": id}, bson.M{"$set": update}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateExchangeCode", table, "UpdateOne", err),
log.Any("id", id),
log.Any("doc", doc),
)
return
}
return
}
// 获取最近的批次号
func GetLatestBatchNumber(app AppType) (data ExchCode, err error) {
var opts = options.FindOne()
opts.SetSort(bson.D{{Key: "createdAt", Value: -1}})
if err = coll(nil).FindOne(&data, bson.M{"app": app}, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetLatestBatchNumber", table, "Find", err),
log.Any("app", app),
)
return
}
return
}
+80
View File
@@ -0,0 +1,80 @@
package exchcodemod
import (
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const (
AppTypeYSVideo AppType = "ysAppVideo" // 音色短视频
AppTypePFVideo AppType = "pfAppVideo" // 泡芙视频
AppTypeLTVpn AppType = "ltAppVpn" // 雷霆加速器
AuthorityShortVideoVip AuthorityType = "shortVideoVip" // 短视频vip
AuthorityFilmVip AuthorityType = "filmVip" // 影视vip(影院)
AuthoritySuper AuthorityType = "superVip" // 超级vip(可以兑换短视频,也可兑换影视)
AuthorityGold AuthorityType = "gold" // 兑换金币
Authority3dPermanentVIP AuthorityType = "3dPermanentVip" // 兑换3天vip
AuthorityVideoCoupon AuthorityType = "videoCoupon" // 观影券
StatusUnused ExchangeStatus = "unused" // 未使用
StatusUsed ExchangeStatus = "used" // 已使用
StatusExpired ExchangeStatus = "expired" // 已过期
SystemOperator = "SystemOperator"
)
type (
ObjectID = primitive.ObjectID
AppType = string // 兑换码所属的app
AuthorityType = string // 兑换权限
ExchangeStatus = string // 状态
ExchCode struct {
ID ObjectID `json:"id" bson:"_id,omitempty"`
BatchNum string `json:"batchNum" bson:"batchNum"` //批次号
App AppType `json:"app" bson:"app"` //app
Channel string `json:"channel" bson:"channel"` //渠道号
Code string `json:"code" bson:"code"` //兑换码
Authority AuthorityType `json:"authority" bson:"authority"` //兑换权限
Status ExchangeStatus `json:"status" bson:"status"` //状态 unused: 未使用,used: 已兑换,expired:已过期
Reward int `json:"reward" bson:"reward"` //奖励值
RewardCount int `json:"rewardCount" bson:"rewardCount"` //奖励量
UsableNum int `json:"usableNum" bson:"usableNum"` //可用次数
Operator string `json:"operator" bson:"operator"` //操作者
Remark string `json:"remark" bson:"remark"` //备注
EffectiveAt time.Time `json:"effectiveAt" bson:"effectiveAt"` //生效时间
InvalidAt time.Time `json:"invalidAt" bson:"invalidAt"` //失效时间
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt,omitempty"` //更新时间
}
// 列表过滤条件
FilterDoc struct {
BatchNum *string `bson:"batchNum,omitempty"`
Channel *string `bson:"channel,omitempty"`
Code *string `bson:"code,omitempty"`
App *AppType `bson:"app,omitempty"`
Authority *AuthorityType `bson:"authority,omitempty"`
}
// 更新条件
UpdateDoc struct {
Status *ExchangeStatus `bson:"status,omitempty"`
Authority *AuthorityType `bson:"authority,omitempty"`
Channel *string `bson:"channel,omitempty"`
Reward *int `bson:"reward,omitempty"`
EffectiveAt *time.Time `bson:"effectiveAt,omitempty"`
InvalidAt *time.Time `bson:"invalidAt,omitempty"`
Remark *string `bson:"remark,omitempty"`
UsableNum *int `bson:"usableNum,omitempty"` //可用次数
}
)
func Init() {
mdb = db.Init(table)
initIndex()
}
+63
View File
@@ -0,0 +1,63 @@
package exchcodemod
import (
"time"
"91porn-server/models/commod"
)
type ListReqParam struct {
BatchNum *string `form:"batchNum" json:"batchNum"`
Channel *string `form:"channel" json:"channel"`
Code *string `form:"code" json:"code"`
App *AppType `form:"app" json:"app"`
Authority *AuthorityType `form:"authority" json:"authority"`
Status *ExchangeStatus `form:"status" json:"status"`
Page commod.Page
Role *string `form:"role" json:"role"`
}
type AddReqParam struct {
App AppType `form:"app" json:"app" binding:"required"`
Channels []string `form:"channels" json:"channels"`
Authority AuthorityType `form:"authority" json:"authority" binding:"required"`
Reward int `form:"reward" json:"reward" binding:"required"`
RewardCount int `form:"rewardCount" json:"rewardCount"`
Count int64 `form:"count" json:"count" binding:"required"`
EffectiveAt time.Time `form:"effectiveAt" json:"effectiveAt" binding:"required"`
InvalidAt time.Time `form:"invalidAt" json:"invalidAt" binding:"required"`
Remark string `form:"remark" json:"remark"`
UsableNum int `form:"usableNum,omitempty" bson:"usableNum,omitempty" binding:"required"` //可用次数
}
type UpdateReqParam struct {
ID ObjectID `form:"id" json:"id" binding:"required"`
Status *ExchangeStatus `form:"status" json:"status"`
Channel *string `form:"channel" json:"channel"`
Authority *AuthorityType `form:"authority" json:"authority"`
Reward *int `form:"reward" json:"reward"`
RewardCount *int `form:"rewardCount" json:"rewardCount"`
EffectiveAt *time.Time `form:"effectiveAt" json:"effectiveAt"`
InvalidAt *time.Time `form:"invalidAt" json:"invalidAt"`
Remark *string `form:"remark" json:"remark"`
UsableNum *int `form:"usableNum,omitempty" bson:"usableNum,omitempty"` //可用次数
}
type RespList struct {
ID ObjectID `json:"id"`
BatchNum string `json:"batchNum" ` //批次号
App AppType `json:"app" ` //app ysAppVideo--音色短视频 pfAppVideo--泡芙视频 ltAppVpn--雷霆加速器
Channel string `json:"channel" ` //渠道号
Code string `json:"code" ` //兑换码
Authority AuthorityType `json:"authority" ` //兑换权限 shortVideoVip--短视频vip filmVip--影视vip(影院) superVip--超级vip(可以兑换短视频,也可兑换影视) gold--兑换金币
Status ExchangeStatus `json:"status" ` //状态 unused: 未使用,used: 已兑换,expired:已过期
Reward int `json:"reward" ` //奖励值
RewardCount int `json:"rewardCount" ` //奖励量
UsableNum int `json:"usableNum" bson:"usableNum"` //可用次数
Operator string `json:"operator" ` //操作者
Remark string `json:"remark" ` //备注
EffectiveAt time.Time `json:"effectiveAt" ` //生效时间
InvalidAt time.Time `json:"invalidAt" ` //失效时间
CreatedAt time.Time `json:"createdAt" ` //创建时间
UpdatedAt time.Time `json:"updatedAt"` //更新时间
}