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
+56
View File
@@ -0,0 +1,56 @@
package active2023mod
import (
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
const active2023LotteryFreeInc = models.Active2023FreeLotteryInc // 用户免费次数新增表
func initFreeIndex() {
coll := active2023LotteryFreeIncColl(nil)
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "uid", Value: 1}},
},
}
if _, err := coll.CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", active2023PrizeTable, err))
}
}
func active2023LotteryFreeIncColl(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(active2023LotteryFreeInc)
}
return t.Coll(active2023LotteryFreeInc)
}
// 添加免费次数
func AddLotteryCountFree(t *db.MongoTool, uid int64, fi FreeLotteryInc) error {
f := bson.M{"uid": uid}
now := time.Now()
update := bson.M{"$inc": bson.M{"lotteryRemain": fi.Count}, "$set": bson.M{"updatedAt": now}}
result, err := active2023UserColl(t).UpdateOne(f, update)
if err != nil {
return err
}
if result.ModifiedCount != 1 {
if _, err := active2023UserColl(t).InsertOne(&UserActive2023{
UID: uid,
LotteryRemain: fi.Count,
CreatedAt: now,
UpdatedAt: now,
}); err != nil {
return err
}
}
_, err = active2023LotteryFreeIncColl(t).InsertOne(fi)
return err
}
+40
View File
@@ -0,0 +1,40 @@
package active2023mod
import (
"fmt"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
const active2023LotteryTable = models.Active2023Lottery // 用户抽奖详情表
func initLotteryIndex() {
coll := active2023LotteryColl(nil)
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "uid", Value: 1}},
},
}
if _, err := coll.CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", active2023LotteryTable, err))
}
}
func active2023LotteryColl(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(active2023LotteryTable)
}
return t.Coll(active2023LotteryTable)
}
func InsertUserLottery(t *db.MongoTool, ul *UserLottery) error {
if ul == nil {
return nil
}
_, err := active2023LotteryColl(t).InsertOne(ul)
return err
}
+52
View File
@@ -0,0 +1,52 @@
package active2023mod
import (
"fmt"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
const active2023PrizeTable = models.Active2023Prize // 用户中奖奖品详情表
func initPrizeIndex() {
coll := active2023PrizeColl(nil)
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "uid", Value: 1}},
},
}
if _, err := coll.CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", active2023PrizeTable, err))
}
}
func active2023PrizeColl(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(active2023PrizeTable)
}
return t.Coll(active2023PrizeTable)
}
func InsertUserPrizes(t *db.MongoTool, ps *[]Prize) ([]primitive.ObjectID, error) {
if ps == nil || len(*ps) == 0 {
return nil, nil
}
result, err := active2023PrizeColl(t).InsertMany(ps)
if err != nil {
return nil, err
}
insertIDsLen := len(result.InsertedIDs)
if insertIDsLen == 0 {
return nil, nil
}
ids := make([]primitive.ObjectID, insertIDsLen)
for i := 0; i < insertIDsLen; i++ {
ids[i], _ = result.InsertedIDs[i].(primitive.ObjectID)
}
return ids, nil
}
+62
View File
@@ -0,0 +1,62 @@
package active2023mod
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const (
PrizeTypeGold = iota + 1 // 金币
PrizeTypeGameGold // 游戏币
PrizeTypeProduct // 现有产品. 目前仅支持会员卡和视频折扣卡
PrizeTypeVIPDate // 会员天数
PrizeTypeGoldCoinBonus // 金币加赠券
PrizeTypeGoldWatch // 金币观影券
PrizeTypeInKind // 实物奖励
)
// 用户抽奖信息
type UserActive2023 struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"id"`
UID int64 `bson:"uid" json:"uid"`
LotteryRemain int64 `bson:"lotteryRemain" json:"lotteryRemain"` // 剩余免费抽奖次数
LotteryFree int64 `bson:"lotteryFree" json:"lotteryFree"` // 已经免费抽奖次数
LotteryRecharge int64 `bson:"lotteryRecharge" json:"lotteryRecharge"` // 已经付费抽奖次数
CreatedAt time.Time `bson:"createdAt" json:"createdAt"` // 创建时间
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"` // 更新时间
}
// 用户抽奖详情
type UserLottery struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"id"`
UID int64 `bson:"uid" json:"uid"`
Count int64 `bson:"count" json:"count"` // 抽奖次数
UseGold int64 `bson:"useGold" json:"useGold"` // 抽奖消耗金币
Prizes []primitive.ObjectID `bson:"prizes" json:"prizes"` // 获得奖品
Desc string `bson:"desc" json:"desc"` // 说明
CreatedAt time.Time `bson:"createdAt" json:"createdAt"` // 创建时间
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"` // 更新时间
}
// 中奖详情
type Prize struct {
UID int64 `bson:"uid" json:"uid"`
Type int64 `bson:"type" json:"type"` // 奖品类型
Name string `bson:"name" json:"name"` // 奖品名字
Unit int64 `bson:"unit" json:"unit"` // 单个奖品包含奖品数量, 配合类型. 金币: 金币数量; 金币加购券: 加购券金币面值; 观影券: 观影券抵扣面值; 会员礼包: 会员延续天数
ProductID *primitive.ObjectID `bson:"productID,omitempty" json:"productID,omitempty"` // 获得奖品的产品id
Amount int64 `bson:"amount" json:"amount"` // 奖品数量
CreatedAt time.Time `bson:"createdAt" json:"createdAt"` // 创建时间
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"` // 更新时间
}
// 免费抽奖次数增加详情
type FreeLotteryInc struct {
UID int64 `bson:"uid" json:"uid"`
Count int64 `bson:"count" json:"count"`
Desc string `bson:"desc" json:"desc"` // 说明
OrderID *primitive.ObjectID `bson:"orderID,omitempty" json:"orderID"` // 对应的订单id
CreatedAt time.Time `bson:"createdAt" json:"createdAt"` // 创建时间
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"` // 更新时间
}
+106
View File
@@ -0,0 +1,106 @@
package active2023mod
import (
"errors"
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const active2023UserTable = models.Active2023User // 用户抽奖信息表
func active2023UserColl(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(active2023UserTable)
}
return t.Coll(active2023UserTable)
}
func Init() {
mdb = db.Init(active2023UserTable)
initIndex()
}
// ActInitIndex 索引设置
func initIndex() {
initUserIndex()
initLotteryIndex()
initPrizeIndex()
initFreeIndex()
}
func initUserIndex() {
coll := active2023UserColl(nil)
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "uid", Value: 1}},
Options: options.Index().SetUnique(true),
},
}
if _, err := coll.CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", active2023UserTable, err))
}
}
func GetActive2023UserInfoByID(t *db.MongoTool, uid int64) (*UserActive2023, error) {
var ua UserActive2023
if err := active2023UserColl(t).FindOne(&ua, bson.M{"uid": uid}); err != nil {
return nil, err
}
if ua.UID == 0 {
now := time.Now()
ua = UserActive2023{
UID: uid,
CreatedAt: now,
UpdatedAt: now,
}
if _, err := active2023UserColl(t).InsertOne(&ua); err != nil {
return nil, err
}
}
return &ua, nil
}
// 使用免费次数
func UseLotteryCountFree(t *db.MongoTool, uid int64, count int64) error {
f := bson.M{"uid": uid, "lotteryRemain": bson.M{"$gte": count}}
update := bson.M{"$inc": bson.M{"lotteryRemain": -int64(count), "lotteryFree": int64(count)}, "$set": bson.M{"updatedAt": time.Now()}}
result, err := active2023UserColl(t).UpdateOne(f, update)
if err != nil {
return err
}
if result.ModifiedCount != 1 {
return errors.New("免费抽奖次数不足")
}
return nil
}
// 付费抽奖
func UserLotteryCountPay(t *db.MongoTool, uid int64, count int64) error {
now := time.Now()
f := bson.M{"uid": uid}
update := bson.M{"$inc": bson.M{"lotteryRecharge": int64(count)}, "$set": bson.M{"updatedAt": time.Now()}}
result, err := active2023UserColl(t).UpdateOne(f, update)
if err != nil {
return err
}
if result.ModifiedCount != 1 {
if _, err := active2023UserColl(t).InsertOne(&UserActive2023{
UID: uid,
LotteryRecharge: int64(count),
CreatedAt: now,
UpdatedAt: now,
}); err != nil {
return err
}
}
return nil
}
+138
View File
@@ -0,0 +1,138 @@
package activitymod
import (
"errors"
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const table = models.Activity
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// ActInitIndex 索引设置
func initIndex() {
coll := coll(nil)
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "status", Value: 1}},
},
{
Keys: bson.D{{Key: "startTime", Value: -1}},
},
{
Keys: bson.D{{Key: "endTime", Value: -1}},
},
{
Keys: bson.D{{Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "updatedAt", Value: -1}},
},
}
if _, err := coll.CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
// 获取活动信息
func Get(id primitive.ObjectID) (*Activity, error) {
var out *Activity
if err := coll(nil).FindOne(&out, bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Get", models.Activity, "FindOne", err),
log.Any("id", id),
)
return nil, err
}
return out, nil
}
// 新增活动
func Add(in AddCond) (interface{}, error) {
result, err := coll(nil).InsertOne(&Activity{
Title: in.Title,
Desc: in.Desc,
Status: false,
StartTime: in.StartTime,
EndTime: in.EndTime,
UpdatedAt: time.Now(),
CreatedAt: time.Now(),
})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Add", models.Activity, "InsertOne", err),
log.Any("in", in),
)
return nil, err
}
return result, nil
}
// 修改活动
func Modify(t *db.MongoTool, filter, update primitive.M) error {
result, err := coll(nil).UpdateOne(filter, update)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Modify", models.Activity, "UpdateOne", err),
log.Any("filter", filter),
log.Any("update", update),
)
return err
}
if result.ModifiedCount == 0 {
err = errors.New("activity UpdateOne ModifiedCount err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Modify", models.Activity, "result.ModifiedCount == 0", err),
log.Any("filter", filter),
log.Any("update", update),
)
return err
}
return nil
}
// 查询活动列表
func QueryAll(filter primitive.M, opts ...*options.FindOptions) ([]*Activity, error) {
var out []*Activity = []*Activity{}
if err := coll(nil).Find(&out, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAll", models.Activity, "Find", err),
log.Any("filter", filter),
)
return nil, err
}
return out, nil
}
// 查询总条数
func Count(filter primitive.M) (int64, error) {
count, err := coll(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Count", models.Activity, "Count", err),
log.Any("filter", filter),
)
return 0, err
}
return count, nil
}
func QueryDropDownBox() ([]*Activity, error) {
var out []*Activity = []*Activity{}
if err := coll(nil).Find(&out, bson.M{"status": true}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryDropDownBox", models.Activity, "Find", err))
return nil, err
}
return out, nil
}
+146
View File
@@ -0,0 +1,146 @@
package activitymod
import (
"errors"
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var prizePoolDB *db.MongoDB
func collPrizePool(t *db.MongoTool) *db.MongoTool {
if t == nil {
return prizePoolDB.Coll(models.ActivityPrizePool)
}
return t.Coll(models.ActivityPrizePool)
}
// initPrizePoolIndex 索引设置
func initPrizePoolIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "activityId", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "createTime", Value: -1}},
},
}
_, err := collPrizePool(nil).CreateIndex(many)
if err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func GetPrizePool(activityID primitive.ObjectID) (*PrizePool, error) {
var out *PrizePool
if err := collPrizePool(nil).FindOne(&out, bson.M{"activityId": activityID}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetPrizePool", models.ActivityPrizePool, "FindOne", err),
log.Any("activityID", activityID),
)
return nil, err
}
return out, nil
}
func UpdatePrizePoolInc(t *db.MongoTool, activityID primitive.ObjectID, reservoir, systemIncome, systemRake int64) error {
result, err := collPrizePool(t).UpdateOne(bson.M{"activityId": activityID}, bson.M{"$inc": bson.M{
"reservoir": reservoir,
"systemIncome": systemIncome,
"systemRake": systemRake,
}})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdatePrizePoolInc", models.ActivityPrizePool, "UpdateOne", err),
log.Any("activityID", activityID),
log.Any("reservoir", reservoir),
log.Any("systemIncome", systemIncome),
log.Any("systemRake", systemRake),
)
return err
}
if result.ModifiedCount == 0 {
err = errors.New("activity UpdateOne ModifiedCount err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdatePrizePoolInc", models.ActivityPrizePool, "result.ModifiedCount == 0", err),
log.Any("activityID", activityID),
log.Any("reservoir", reservoir),
log.Any("systemIncome", systemIncome),
log.Any("systemRake", systemRake),
)
return err
}
return nil
}
// 新增活动奖池
func AddPrizePool(in AddPrizePoolCond) (interface{}, error) {
result, err := collPrizePool(nil).InsertOne(&PrizePool{
ActivityID: in.ActivityID,
Model: in.Model,
EstimatedIncome: in.EstimatedIncome,
Price: in.Price,
FreeCount: in.FreeCount,
UpdateTime: time.Now(),
CreateTime: time.Now(),
})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddPrizePool", models.ActivityPrizePool, "InsertOne", err),
log.Any("in", in),
)
return nil, err
}
return result, nil
}
// 修改活动奖池
func ModifyPrizePool(filter, update primitive.M) error {
result, err := collPrizePool(nil).UpdateOne(filter, update)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "ModifyPrizePool", models.ActivityPrizePool, "UpdateOne", err),
log.Any("filter", filter),
log.Any("update", update),
)
return err
}
if result.ModifiedCount == 0 {
err = errors.New("activity UpdateOne ModifiedCount err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "ModifyPrizePool", models.ActivityPrizePool, "result.ModifiedCount == 0", err),
log.Any("filter", filter),
log.Any("update", update),
)
return err
}
return nil
}
// 查询活动奖池列表
func QueryAllPrizePool(filter primitive.M, opts ...*options.FindOptions) ([]*PrizePool, error) {
var out []*PrizePool = []*PrizePool{}
if err := collPrizePool(nil).Find(&out, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllPrizePool", models.ActivityPrizePool, "Find", err),
log.Any("filter", filter),
)
return nil, err
}
return out, nil
}
// 查询活动奖池总条数
func CountPrizePool(filter primitive.M) (int64, error) {
count, err := collPrizePool(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CountPrizePool", models.ActivityPrizePool, "Count", err),
log.Any("filter", filter),
)
return 0, err
}
return count, nil
}
+28
View File
@@ -0,0 +1,28 @@
package activitymod
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type PrizePoolModel int
const (
Game PrizePoolModel = iota + 1 // 棋牌游戏
Free // 免费
)
type PrizePool struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档ID
ActivityID primitive.ObjectID `json:"activityId" bson:"activityId"` // 活动ID
Model PrizePoolModel `json:"model" bson:"model"` // 奖池模式
Price int64 `json:"price" bson:"price"` // 单次抽奖金额
FreeCount int32 `json:"freeCount" bson:"freeCount"` // 免费次数
EstimatedIncome int64 `json:"estimatedIncome" bson:"estimatedIncome"` // 当日预计收益---杀放概率固定30%
Reservoir int64 `json:"reservoir" bson:"reservoir"` // 蓄水池---固定抽成5%
SystemIncome int64 `json:"systemIncome" bson:"systemIncome"` // 系统收益
SystemRake int64 `json:"systemRake" bson:"systemRake"` // 系统抽成金额---固定抽成5%
UpdateTime time.Time `json:"updateTime" bson:"updateTime"` // 修改时间
CreateTime time.Time `json:"createTimt" bson:"createTimt"` // 创建时间
}
+32
View File
@@ -0,0 +1,32 @@
package activitymod
import (
"time"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type Activity struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档ID
Title string `json:"title" bson:"title"` // 活动名称
Desc string `json:"desc" bson:"desc"` // 活动注意事项
Status bool `json:"status" bson:"status"` // 状态---启用/禁用
StartTime time.Time `json:"startTime" bson:"startTime"` // 活动开始时间
EndTime time.Time `json:"endTime" bson:"endTime"` // 活动结束时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 文档更新时间
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 文档创建时间
}
func Init() {
mdb = db.Init(table)
initIndex()
prizePoolDB = db.Init(models.ActivityPrizePool)
initPrizePoolIndex()
userFreeDB = db.Init(models.ActivityUserFree)
initUserFreeIndex()
userRecordDB = db.Init(models.ActivityUserRecord)
initUserRecordIndex()
}
+117
View File
@@ -0,0 +1,117 @@
package activitymod
import (
"errors"
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var userFreeDB *db.MongoDB
func collUserFree(t *db.MongoTool) *db.MongoTool {
if t == nil {
return userFreeDB.Coll(models.ActivityUserFree)
}
return t.Coll(models.ActivityUserFree)
}
// initUserFreeIndex 索引设置
func initUserFreeIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "activityId", Value: 1}, {Key: "uid", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "createTime", Value: -1}},
},
}
if _, err := collUserFree(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func GetUserFree(activityID primitive.ObjectID, uid uint64) (*UserFree, error) {
var out *UserFree
if err := collUserFree(nil).FindOne(&out, bson.M{"activityId": activityID, "uid": uid}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddUserFree", models.ActivityUserFree, "InsertOne", err),
log.Any("activityID", activityID),
log.Any("uid", uid),
)
return nil, err
}
return out, nil
}
func AddUserFree(activityID primitive.ObjectID, uid uint64, freeCount int32) error {
if _, err := collUserFree(nil).InsertOne(&UserFree{
ActivityID: activityID,
UID: uid,
FreeCount: freeCount,
UpdateTime: time.Now(),
CreateTime: time.Now(),
}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddUserFree", models.ActivityUserFree, "InsertOne", err),
log.Any("activityID", activityID),
log.Any("uid", uid),
log.Any("freeCount", freeCount),
)
return err
}
return nil
}
func UpdateOneUserFreeInc(t *db.MongoTool, activityID primitive.ObjectID, uid uint64, freeCount int32) error {
result, err := collUserFree(t).UpdateOne(bson.M{"activityId": activityID, "uid": uid},
bson.M{"$inc": bson.M{"freeCount": freeCount}, "$set": bson.M{"updateTime": time.Now()}})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateOneInc", models.ActivityUserFree, "UpdateOne", err),
log.Any("activityID", activityID),
log.Any("uid", uid),
log.Any("freeCount", freeCount),
)
return err
}
if result.ModifiedCount == 0 {
err = errors.New("activity UpdateOne ModifiedCount err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateOneInc", models.ActivityUserFree, "result.ModifiedCount == 0", err),
log.Any("activityID", activityID),
log.Any("uid", uid),
log.Any("freeCount", freeCount),
)
return err
}
return nil
}
func UpdateOneSet(activityID primitive.ObjectID, uid uint64, freeCount int32) error {
result, err := collUserFree(nil).UpdateOne(bson.M{"activityId": activityID, "uid": uid},
bson.M{"$set": bson.M{"freeCount": freeCount, "updateTime": time.Now()}})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateOneSet", models.ActivityUserFree, "UpdateOne", err),
log.Any("activityID", activityID),
log.Any("uid", uid),
log.Any("freeCount", freeCount),
)
return err
}
if result.ModifiedCount == 0 {
err = errors.New("activity UpdateOne ModifiedCount err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateOneSet", models.ActivityUserFree, "result.ModifiedCount == 0", err),
log.Any("activityID", activityID),
log.Any("uid", uid),
log.Any("freeCount", freeCount),
)
return err
}
return nil
}
+17
View File
@@ -0,0 +1,17 @@
package activitymod
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// 用户免费次数记录
type UserFree struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档ID
ActivityID primitive.ObjectID `json:"activityId" bson:"activityId"` // 活动ID
UID uint64 `json:"uid" bson:"uid"` // 用户ID
FreeCount int32 `json:"freeCount" bson:"freeCount"` // 剩余免费次数
UpdateTime time.Time `json:"updateTime" bson:"updateTime"` // 修改时间
CreateTime time.Time `json:"createTimt" bson:"createTimt"` // 创建时间
}
+93
View File
@@ -0,0 +1,93 @@
package activitymod
import (
"errors"
"fmt"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"91porn-server/models/v/prizemod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var userRecordDB *db.MongoDB
func collUserRecord(t *db.MongoTool) *db.MongoTool {
if t == nil {
return userRecordDB.Coll(models.ActivityUserRecord)
}
return t.Coll(models.ActivityUserRecord)
}
// initUserFreeIndex 索引设置
func initUserRecordIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "activityId", Value: 1}, {Key: "uid", Value: 1}, {Key: "createTime", Value: -1}},
},
{
Keys: bson.D{{Key: "createTime", Value: -1}},
},
}
if _, err := collUserRecord(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", models.ActivityUserRecord, err))
}
}
func AddMany(records []UserRecord) error {
result, err := collUserRecord(nil).InsertMany(&records)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddMany", models.ActivityUserRecord, "InsertMany", err),
log.Any("records", records),
)
return err
}
if len(result.InsertedIDs) != len(records) {
err = errors.New("activity InsertMany InsertedIDs err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddMany", models.ActivityUserRecord, "len(result.InsertedIDs) != len(records)", err),
log.Any("records", records),
)
return err
}
return nil
}
func QueryAllRecord(filter primitive.M, opts ...*options.FindOptions) ([]*UserRecord, error) {
var out []*UserRecord = []*UserRecord{}
if err := collUserRecord(nil).Find(&out, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllRecord", models.ActivityUserRecord, "Find", err),
log.Any("filter", filter),
)
return nil, err
}
return out, nil
}
// 查询奖品总条数
func CountRecord(filter primitive.M) (int64, error) {
count, err := collUserRecord(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CountRecord", models.ActivityUserRecord, "Count", err),
log.Any("filter", filter),
)
return 0, err
}
return count, nil
}
func GetMarquee(activityId primitive.ObjectID) ([]*UserRecord, error) {
filter := bson.M{"activityId": activityId, "level": prizemod.High}
var out []*UserRecord = []*UserRecord{}
if err := collUserRecord(nil).Find(&out, filter, options.Find().SetLimit(10).SetSort(bson.M{"createTime": -1})); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllRecord", models.ActivityUserRecord, "Find", err),
log.Any("filter", filter),
)
return nil, err
}
return out, nil
}
+26
View File
@@ -0,0 +1,26 @@
package activitymod
import (
"time"
"91porn-server/models/v/prizemod"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// 用户抽奖记录
type UserRecord struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档ID
ActivityID primitive.ObjectID `json:"activityId" bson:"activityId"` // 活动ID
VIPCardID primitive.ObjectID `json:"vipCardId" bson:"vipCardId"` // 会员卡ID
UID uint64 `json:"uid" bson:"uid"` // 用户ID
UserName string `json:"userName" bson:"userName"` // 用户名
Name string `json:"name" bson:"name"` // 奖品名称
Type prizemod.PrizeType `json:"type" bson:"type"` // 奖品类型
Count int32 `json:"count" bson:"count"` // 奖品数量
Price int64 `json:"price" bson:"price"` // 奖品价值
Value int64 `json:"value" bson:"value"` // 折扣率/活跃值
Level prizemod.PrizeLevel `json:"level" bson:"level"` // 奖品等级
DrawPrice int64 `json:"drawPrice" bson:"drawPrice"` // 单次抽奖价格(金币)
CreateTime time.Time `json:"createTime" bson:"createTime"` // 创建时间
}
+171
View File
@@ -0,0 +1,171 @@
package activitymod
import (
"time"
"91porn-server/models/commod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
// ActReq 活动请求,公告跳转到活动页面
type ActReq struct {
Token string `form:"token" json:"token"`
Type string `form:"type" json:"type"`
}
// 新增活动
type AddCond struct {
Title string `json:"title"` // 活动名称
Desc string `json:"desc"` // 活动注意事项
StartTime time.Time `json:"startTime"` // 活动开始时间
EndTime time.Time `json:"endTime"` // 活动结束时间
}
// 修改活动
type ModifyCond struct {
ID primitive.ObjectID `json:"id" binding:"required"` // 文档ID
Title *string `json:"title"` // 活动名称
Desc *string `json:"desc"` // 活动注意事项
Status *bool `json:"status"` // 状态---启用/禁用
StartTime *time.Time `json:"startTime"` // 活动开始时间
EndTime *time.Time `json:"endTime"` // 活动结束时间
}
func (m *ModifyCond) Cond() primitive.M {
return bson.M{"_id": m.ID}
}
func (m *ModifyCond) Bson() primitive.M {
set := bson.M{"updatedAt": time.Now()}
if m.Title != nil {
set["title"] = m.Title
}
if m.Desc != nil {
set["desc"] = m.Desc
}
if m.Status != nil {
set["status"] = m.Status
}
if m.StartTime != nil {
set["startTime"] = m.StartTime
}
if m.EndTime != nil {
set["endTime"] = m.EndTime
}
return bson.M{"$set": set}
}
// 查询活动列表
type QueryAllCond struct {
Status *bool `form:"status"` // 状态---启用/禁用
commod.Page
}
func (q *QueryAllCond) Options() *options.FindOptions {
return options.Find().SetLimit(int64(q.PageSize)).SetSkip(int64((q.PageNumber - 1) * q.PageSize)).SetSort(bson.M{"createdAt": -1})
}
func (q *QueryAllCond) Query() primitive.M {
fliter := bson.M{}
if q.Status != nil {
fliter["status"] = q.Status
}
return fliter
}
// 新增活动奖池
type AddPrizePoolCond struct {
ActivityID primitive.ObjectID `json:"activityId" binding:"required"` // 活动ID
Model PrizePoolModel `json:"model"` // 奖池模式
EstimatedIncome int64 `json:"estimatedIncome"` // 当日预计收益
Price int64 `json:"price"` // 单次抽奖金额
FreeCount int32 `json:"freeCount"` // 免费次数
}
// 修改活动奖池
type ModifyPrizePoolCond struct {
ID primitive.ObjectID `json:"id" binding:"required"` // 文档ID
ActivityID *primitive.ObjectID `json:"activityId"` // 活动ID
Model *PrizePoolModel `json:"model"` // 奖池模式
EstimatedIncome *int64 `json:"estimatedIncome"` // 当日预计收益
Price *int64 `json:"price"` // 单次抽奖金额
FreeCount *int32 `json:"freeCount"` // 免费次数
}
func (m *ModifyPrizePoolCond) Cond() primitive.M {
return bson.M{"_id": m.ID}
}
func (m *ModifyPrizePoolCond) Bson() primitive.M {
set := bson.M{"updatedAt": time.Now()}
if m.ActivityID != nil {
set["activityId"] = m.ActivityID
}
if m.Model != nil {
set["model"] = m.Model
}
if m.EstimatedIncome != nil {
set["estimatedIncome"] = m.EstimatedIncome
}
if m.Price != nil {
set["price"] = m.Price
}
if m.FreeCount != nil {
set["freeCount"] = m.FreeCount
}
return bson.M{"$set": set}
}
// 查询活动奖池列表
type QueryAllPrizePoolCond struct {
Model *PrizePoolModel `form:"model"` // 奖池模式
ActivityID *string `form:"activityId"` // 活动ID
commod.Page
}
func (q *QueryAllPrizePoolCond) Options() *options.FindOptions {
return options.Find().SetLimit(int64(q.PageSize)).SetSkip(int64((q.PageNumber - 1) * q.PageSize)).SetSort(bson.M{"createdAt": -1})
}
func (q *QueryAllPrizePoolCond) Query() primitive.M {
fliter := bson.M{}
if q.Model != nil {
fliter["model"] = q.Model
}
if q.ActivityID != nil {
id, _ := primitive.ObjectIDFromHex(*q.ActivityID)
fliter["activityId"] = id
}
return fliter
}
// 查询活动参与记录列表
type QueryAllRecordCond struct {
ActivityID *string `form:"activityId"` // 活动ID
UID *string `form:"uid"` // 活动ID
commod.Page
}
func (q *QueryAllRecordCond) Options() *options.FindOptions {
return options.Find().SetLimit(int64(q.PageSize)).SetSkip(int64((q.PageNumber - 1) * q.PageSize)).SetSort(bson.M{"createTime": -1})
}
func (q *QueryAllRecordCond) Query() primitive.M {
fliter := bson.M{}
if q.UID != nil {
fliter["uid"] = q.UID
}
if q.ActivityID != nil {
id, _ := primitive.ObjectIDFromHex(*q.ActivityID)
fliter["activityId"] = id
}
return fliter
}
type OpenBotDrawCond struct {
ID primitive.ObjectID `json:"id" binding:"required"` // 活动ID
Status bool
}
+55
View File
@@ -0,0 +1,55 @@
package actmod
import (
"errors"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
func GetActivitiesCount() (int64, error) {
return coll(nil).Count(bson.M{})
}
func GetActivities(skip, limit uint64) ([]Activity, error) {
opts := options.Find().SetSort(bson.D{{Key: "sort", Value: 1}, {Key: "createdAt", Value: -1}})
if skip != 0 {
opts.SetSkip(int64(skip))
}
if limit != 0 {
opts.SetLimit(int64(limit))
}
var activities []Activity
if err := coll(nil).Find(&activities, bson.M{}, opts); err != nil {
return nil, err
}
return activities, nil
}
func GetActivitiesValid(skip, limit uint64) ([]Activity, error) {
opts := options.Find().SetSort(bson.D{{Key: "sort", Value: 1}, {Key: "createdAt", Value: -1}})
if skip != 0 {
opts.SetSkip(int64(skip))
}
if limit != 0 {
opts.SetLimit(int64(limit))
}
var activities []Activity
if err := coll(nil).Find(&activities, bson.M{"status": 1, "expiredIn": bson.M{"$gt": time.Now()}}, opts); err != nil {
return nil, err
}
return activities, nil
}
func GetActivityByActivityID(ActivityID primitive.ObjectID) (*Activity, error) {
var act Activity
if err := coll(nil).FindOne(&act, bson.M{"_id": ActivityID}); err != nil {
return nil, err
}
if act.ID.IsZero() {
return nil, errors.New("active not found")
}
return &act, nil
}
+57
View File
@@ -0,0 +1,57 @@
package actmod
import (
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const table = models.Act
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// initIndex 初始化索引
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "activityName", Value: 1}},
Options: options.Index().SetUnique(true),
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func Init() {
mdb = db.Init(table)
initIndex()
}
type Activity struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // id
ActivityName string `json:"activityName" bson:"activityName"` // 活动名
Desc string `json:"desc" bson:"desc"` // 活动说明
Img string `json:"img" bson:"img"` // 活动图片
Content string `json:"content" bson:"content"` // 富文本内容
Link string `json:"link" bson:"link"` // 链接地址
Sort int `json:"sort" bson:"sort"` // 活动排序
Status int `json:"status" bson:"status"` // 状态 1 有效 0 无效
ExpiredIn time.Time `json:"expiredIn" bson:"expiredIn"` // 过期时间
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 文档创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 文档更新时间
}
+16
View File
@@ -0,0 +1,16 @@
package actmod
import (
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
func AddACtivity(act Activity) error {
_, err := coll(nil).InsertOne(act)
return err
}
func EidtActivity(actID primitive.ObjectID, b bson.M) error {
_, err := coll(nil).UpdateOne(bson.M{"_id": actID}, bson.M{"$set": b})
return err
}
+246
View File
@@ -0,0 +1,246 @@
package adminmod
import (
"fmt"
"time"
"91porn-server/common"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/common/pageopt"
"91porn-server/models"
"91porn-server/models/v/authoritymod"
"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.Admin
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// initIndex 设置index
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "name", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "secret", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "lastLoginAt", Value: -1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func FindOneByName(name string) (doc Admin, err error) {
return findOne(AdminDoc{
Name: &name,
})
}
func FindOneByID(id ObjectID) (doc Admin, err error) {
return findOne(AdminDoc{
ID: &id,
})
}
func findOne(filter AdminDoc) (doc Admin, err error) {
filterM, err := common.ToBsonM(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "findOne", table, "ToBsonM", err))
return
}
if err = coll(nil).FindOne(&doc, filterM); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "findOne", table, "FindOne", err))
return
}
return
}
func ExistsByID(id ObjectID) (existed bool, err error) {
doc, err := FindOneByID(id)
existed = !doc.ID.IsZero()
return
}
func ExistsByName(name string) (existed bool, err error) {
doc, err := FindOneByName(name)
existed = !doc.ID.IsZero()
return
}
// Insert 插入记录
func Insert(tool *db.MongoTool, doc AdminDoc) (err error) {
now := time.Now()
doc.CreatedAt = &now
doc.UpdatedAt = &now
if doc.Role != nil {
authority, err := authoritymod.FindOne(authoritymod.AuthorityDoc{Role: doc.Role})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "FindOne", err))
return err
}
if authority.ID.IsZero() {
return fmt.Errorf("coll:%s update Role is not exist", table)
}
}
if _, err = coll(tool).InsertOne(doc); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return
}
return
}
func Bind(name string) error {
hasBind := true
return update(AdminDoc{Name: &name}, AdminDoc{HasBind: &hasBind})
}
// UpdateTo UpdateTo
func UpdateByID(id ObjectID, updat AdminDoc) error {
return update(AdminDoc{ID: &id}, updat)
}
// UpdateTo UpdateTo
func update(filter AdminDoc, update AdminDoc) error {
filterM, err := common.ToBsonM(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "update", table, "filter ToBsonM", err))
return err
}
now := time.Now()
update.UpdatedAt = &now
if update.Role != nil {
authority, err := authoritymod.FindOne(authoritymod.AuthorityDoc{Role: update.Role})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "update", table, "FindOne", err))
return err
}
if authority.ID.IsZero() {
return fmt.Errorf("coll:%s update Role is not exist", table)
}
}
updateM, err := common.ToBsonM(update)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "update", table, "update ToBsonM", err))
return err
}
if _, err := coll(nil).UpdateOne(filterM, bson.M{"$set": updateM}); err != nil {
log.Error(fmt.Sprintf(
"[METHOD-%s]==> Model %s %s fail error:%+v:", "update", table, "UpdateOne", err),
log.Any("filter", filter),
log.Any("update", update),
)
return err
}
return nil
}
func UnsetPrivilege(id ObjectID) error {
filter := M{"_id": id}
update := M{"$unset": M{
"role": 1,
}}
result, err := coll(nil).UpdateOne(filter, update)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UnsetPrivilege", table, "UpdateOne", err), log.Any("id", id))
return err
}
if result.ModifiedCount+result.UpsertedCount != 1 {
return fmt.Errorf("coll:%s UpdateTo Count error, id:%+v", table, id)
}
return nil
}
// Delete Delete
func Delete(doc AdminDoc) error {
filer, err := common.ToBsonM(doc)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Delete", table, "ToBsonM", err))
return err
}
if _, err := coll(nil).DeleteOne(filer); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Delete", table, "ToBsonM", err), log.Any("filer", filer))
return err
}
return nil
}
// IsUsing
// @return true:角色被使用 否则flase
func IsUsing(role string) (bool, error) {
filter := M{"role": role}
cnt, err := coll(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsUsing", table, "Count", err))
return false, err
}
return cnt > 0, nil
}
func List(skip, limit int64, matcher ...pageopt.Matcher) ([]Admin, error) {
filter := pageopt.MergeM(matcher)
opt := (&options.FindOptions{}).
SetSkip(skip).
SetLimit(limit)
adminList := make([]Admin, 0, limit)
if err := coll(nil).Find(&adminList, filter, opt); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "List", table, "Find", err))
return nil, err
}
return adminList, nil
}
func Count(matcher ...pageopt.Matcher) (int64, error) {
filter := pageopt.MergeM(matcher)
count, err := coll(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Count", table, "Count", err))
return 0, err
}
return count, nil
}
// GetNickByAccount 通过账号获取名称
func GetNickByAccount(accounts []string) (map[string]string, error) {
m := make(map[string]string)
datas := []Admin{}
cond := bson.M{"name": bson.M{"$in": accounts}}
if err := coll(nil).Find(&datas, cond); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetNickByAccount", table, "Find", err), log.Any("accounts", accounts))
return m, err
}
for _, d := range datas {
m[d.Name] = d.Nickname
}
return m, nil
}
// GetNameByNick 通过昵称过去账号名
func GetNameByNick(nick string) (string, error) {
data := Admin{}
cond := bson.M{"nickname": nick}
if err := coll(nil).FindOne(&data, cond); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetNameByNick", table, "FindOne", err), log.Any("nick", nick))
return data.Name, err
}
return data.Name, nil
}
+64
View File
@@ -0,0 +1,64 @@
package adminmod
import (
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type (
// A A from Array
A = bson.A
// D D from Doc
D = bson.D
// M M from Map
M = bson.M
ObjectID = primitive.ObjectID
// Admin Admin
Admin struct {
ID ObjectID `bson:"_id,omitempty"`
Name string `bson:"name"` //账号
Password string `bson:"password"` //密码
Nickname string `bson:"nickname"` //昵称
Email string `bson:"email"` //邮箱
Role string `bson:"role"` //角色
Secret string `bson:"secret"` //两步验证密钥
HasBind bool `bson:"hasBind"` //已绑定 true,曾成功登录,反之false
HasLocked bool `bson:"hasLocked"` //已禁止登陆
LockReason string `bson:"lockReason"` //禁止登陆的原因
CreatedAt time.Time `bson:"createdAt"`
UpdatedAt time.Time `bson:"updatedAt"`
LastLoginAt time.Time `bson:"lastLoginAt"` //最后登陆时间
BindAt time.Time `bson:"bindAt"` //绑定电话时间
}
// AdminDoc AdminDoc
AdminDoc struct {
ID *primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`
PrivilegeID *primitive.ObjectID `json:"privilegeId,omitempty" bson:"privilegeID,omitempty"` //权限ID
Name *string `json:"name,omitempty" bson:"name,omitempty"` //账号
Password *string `json:"password,omitempty" bson:"password,omitempty"` //密码
Nickname *string `json:"nickname,omitempty" bson:"nickname,omitempty"` //昵称
Email *string `json:"email,omitempty" bson:"email,omitempty"` //邮箱
Role *string `json:"role,omitempty" bson:"role,omitempty"` //角色
Secret *string `json:"secret,omitempty" bson:"secret,omitempty"` //两步验证密钥
HasBind *bool `json:"hasBind,omitempty" bson:"hasBind,omitempty"` //已绑定 true,曾成功登录,反之false
HasLocked *bool `json:"hasLocked,omitempty" bson:"hasLocked,omitempty"` //已禁止登陆
LockReason *string `json:"lockReason,omitempty" bson:"lockReason,omitempty"` //禁止登陆的原因
CreatedAt *time.Time `json:"createdAt,omitempty" bson:"createdAt,omitempty"`
UpdatedAt *time.Time `json:"updatedAt,omitempty" bson:"updatedAt,omitempty"`
LastLoginAt *time.Time `json:"lastLoginAt,omitempty" bson:"lastLoginAt,omitempty"`
}
)
func Init() {
mdb = db.Init(table)
initIndex()
}
+169
View File
@@ -0,0 +1,169 @@
package adreviewmod
import (
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/common/pageopt"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
const table = models.AdReview
var mdb *db.MongoDB
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// InitIndex 初始化索引
func initAdsIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "reviewStatus", Value: 1}, {Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "districtCode", Value: 1}, {Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "passAt", Value: -1}},
},
{
Keys: bson.D{{Key: "refussAt", Value: -1}},
},
{
Keys: bson.D{{Key: "optTypeAt", 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))
}
}
// InsertOne 增加广告
func InsertOne(t *db.MongoTool, doc InsertDoc) error {
if doc.CreatedAt.IsZero() {
doc.CreatedAt = time.Now()
}
if doc.ApplyAt.IsZero() {
doc.ApplyAt = time.Now()
}
if _, err := coll(t).InsertOne(doc); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertOne", table, "InsertMany", err))
return err
}
return nil
}
var processong = Processong
func updateOne(doc UpdateDoc, mats ...Matcher) error {
var d struct {
Doc UpdateDoc `bson:",inline"`
ReviewStatus *ReviewStatus `bson:"reviewStatus,omitempty"` //审核状态
}
d.Doc = doc
filter := pageopt.MergeM(mats)
now := time.Now()
if doc.OptType != nil {
doc.ApplyAt = &now
}
if doc.Title != nil || doc.Cover != nil || doc.HrefType != nil || doc.Href != nil || doc.Position != nil || doc.SortCode != nil {
d.ReviewStatus = &processong
}
if doc.UpdatedAt.IsZero() {
doc.UpdatedAt = now
}
res, err := coll(nil).UpdateOne(filter, bson.M{"$set": d})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateAds", table, "UpdateOne", err), log.Any("doc", doc), log.Any("filter", filter))
return err
}
if res.MatchedCount == 0 {
return ADReviewNotExistError{}
}
return nil
}
func UpdateOneByID(id ObjectID, doc UpdateDoc) error {
return updateOne(doc, (&IDMatch{ID: &id}).New())
}
func DeleteOne(t *db.MongoTool, id ObjectID) error {
if _, err := coll(t).DeleteById(id); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteOne", table, "DeleteById", err))
if err == mongo.ErrNoDocuments {
return ADReviewNotExistError{}
}
return err
}
return nil
}
func updateReview(review Review, now time.Time, mats ...Matcher) error {
var doc struct {
Review `bson:",inline"`
UpdatedAt time.Time `bson:"updatedAt"` //更新时间
}
doc.Review = review
if doc.ReviewStatus == Pass {
doc.PassAt = now
}
if doc.ReviewStatus == Refuse {
doc.RefussAt = now
}
doc.UpdatedAt = now
filter := pageopt.MergeM(mats)
res, err := coll(nil).UpdateOne(filter, bson.M{"$set": doc})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateAds", table, "UpdateOne", err), log.Any("doc", doc), log.Any("filter", filter))
return err
}
if res.MatchedCount == 0 {
return ADReviewNotExistError{}
}
return nil
}
func UpdateReviewByID(id ObjectID, curStatus ReviewStatus, targetStatus ReviewStatus, adID *ObjectID, reviewer string, receiptInfo string, now time.Time) error {
review := Review{
Reviewer: reviewer,
ReviewStatus: targetStatus,
ReceiptInfo: receiptInfo,
}
if adID != nil {
review.ADID = *adID
}
mats := []Matcher{
(&IDMatch{ID: &id}).New(),
(&ReviewStatusMatch{&curStatus}).New(),
}
return updateReview(review, now, mats...)
}
func findOne(mats ...Matcher) (AdReview, error) {
filter := pageopt.MergeM(mats)
ads := AdReview{}
if err := coll(nil).FindOne(&ads, filter); err != nil {
return AdReview{}, err
}
if ads.ID.IsZero() {
return AdReview{}, ADReviewNotExistError{}
}
return ads, nil
}
func FindOneByID(id ObjectID) (AdReview, error) {
return findOne((&IDMatch{ID: &id}).New())
}
+9
View File
@@ -0,0 +1,9 @@
package adreviewmod
// ADReviewNotExistError
type ADReviewNotExistError struct {
}
func (ADReviewNotExistError) Error() string {
return "review is not exist"
}
+69
View File
@@ -0,0 +1,69 @@
package adreviewmod
import (
"91porn-server/common/log"
"91porn-server/common/pageopt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
type (
AdsSlice []AdReview
Matcher = pageopt.Matcher
// ReviewStatusMatch
ReviewStatusMatch struct {
ReviewStatus *ReviewStatus
}
// DistrictCodeMatch
DistrictCodeMatch struct {
DistrictCode *string
}
IDMatch = pageopt.IDMatch
Sort = bson.D
)
func (a *ReviewStatusMatch) New() Matcher {
return pageopt.NewAssignMatch("reviewStatus", a.ReviewStatus)
}
func (c *DistrictCodeMatch) New() Matcher {
return pageopt.NewAssignMatch("districtCode", c.DistrictCode)
}
var Sort_createdAt_N1 = Sort{{Key: "createdAt", Value: -1}}
func List(sort Sort, skip, limit *int64, matchers ...Matcher) (AdsSlice, error) {
filter := pageopt.MergeM(matchers)
opt := (&options.FindOptions{})
if len(sort) != 0 {
opt.SetSort(sort)
}
if skip != nil {
opt.SetSkip(*skip)
}
if limit != nil {
opt.SetLimit(*limit)
}
list := AdsSlice{}
if err := coll(nil).Find(&list, filter, opt); err != nil {
log.Error("adsmod List error", log.E(err))
return nil, err
}
return list, nil
}
func Count(matchers ...Matcher) (int64, error) {
filter := pageopt.MergeM(matchers)
count, err := coll(nil).Count(filter)
if err != nil {
log.Error("adsmod List error", log.E(err))
return 0, err
}
return count, nil
}
+105
View File
@@ -0,0 +1,105 @@
package adreviewmod
import (
"time"
"91porn-server/common"
"91porn-server/common/db"
"91porn-server/common/ysurl"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const (
ADD OptType = iota //添加
Modify //修改
Delete //删除
)
const (
Processong ReviewStatus = iota // 审核中
Pass // 通过
Refuse // 拒绝
)
type (
ObjectID = primitive.ObjectID
// 操作类型
OptType int
// RUL跳转类型
URLJumpType = ysurl.URLJumpType
// 审核状态
ReviewStatus int
// Operation 操作信息
Operation struct {
OptType OptType `bson:"optType"` //操作类型
ApplyAt time.Time `bson:"applyAt"` //申请时间
}
Review struct {
ADID ObjectID `bson:"adID,omitempty"` //广告id
PassAt time.Time `bson:"passAt,omitempty"` //通过时间
RefussAt time.Time `bson:"refussAt,omitempty"` //拒绝时间
Reviewer string `bson:"reviewer"` //审核人
ReviewStatus ReviewStatus `bson:"reviewStatus"` //审核状态
ReceiptInfo string `bson:"receiptInfo"` //回执信息
}
CoverProp = common.PictureProp
// Ads 广告审核
AdReview struct {
ID ObjectID `bson:"_id"` //id
Cover string `bson:"cover"` //广告封面图
Title string `bson:"title"` //广告标题
HrefType URLJumpType `bson:"hrefType"` //广告链接类型
Href string `bson:"href"` //广告跳转地址
Position int `bson:"position"` //广告位置
SortCode int `bson:"sortCode"` //排序号
Remark string `bson:"remark"` //备注
DistrictCode string `bson:"districtCode"` //商区码
UpdatedAt time.Time `bson:"updatedAt"` //更新时间
CreatedAt time.Time `bson:"createdAt"` //创建时间
Operation `bson:",inline"` //操作
Review `bson:",inline"` //审核信息
CoverProp `bson:",inline"` //图片属性
}
InsertDoc struct {
Cover string `bson:"cover"` //广告封面图
Title string `bson:"title"` //广告标题
HrefType URLJumpType `bson:"hrefType"` //广告链接类型
Href string `bson:"href"` //广告跳转地址
Position int `bson:"position"` //广告位置
SortCode int `bson:"sortCode"` //排序号
Remark string `bson:"remark"` //备注
DistrictCode string `bson:"districtCode"` //商区码
CreatedAt time.Time `bson:"createdAt"` //创建时间
Operation `bson:",inline"` //操作
Review `bson:",inline"` //审核信息
CoverProp `bson:",inline"` //图片属性
}
UpdateDoc struct {
Title *string `bson:"title,omitempty"` //广告标题
Cover *string `bson:"cover,omitempty"` //广告封面图
HrefType *URLJumpType `bson:"hrefType,omitempty"` //广告链接类型
Href *string `bson:"href,omitempty"` //广告跳转地址
Position *int `bson:"position,omitempty"` //广告位置
SortCode *int `bson:"sortCode,omitempty"` //排序号
Remark *string `bson:"remark,omitempty"` //备注
OptType *OptType `bson:"optType,omitempty"` //操作类型
ApplyAt *time.Time `bson:"applyAt,omitempty"` //申请时间
UpdatedAt time.Time `bson:"updatedAt"` //更新时间
CoverProp `bson:",inline"` //图片属性
}
)
func Init() {
mdb = db.Init(table)
initAdsIndex()
}
+141
View File
@@ -0,0 +1,141 @@
package adsmod
import (
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/common/pageopt"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
const table = models.Ads
var mdb *db.MongoDB
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// InitIndex 初始化索引
func initAdsIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "active", Value: 1}},
},
{
Keys: bson.D{{Key: "updatedAt", Value: 1}},
},
{
Keys: bson.D{{Key: "sortCode", Value: 1}},
},
{
Keys: bson.D{{Key: "type", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
// InsertOne 增加广告
func InsertOne(t *db.MongoTool, doc InsertDoc) (ObjectID, error) {
if doc.CreatedAt.IsZero() {
doc.CreatedAt = time.Now()
}
res, err := coll(t).InsertOne(doc)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertOne", table, "InsertMany", err))
return ObjectID{}, err
}
return res.InsertedID.(ObjectID), nil
}
// DeleteOne 删除广告
func DeleteOne(t *db.MongoTool, id ObjectID) error {
if _, err := coll(t).DeleteOne(bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteOne", table, "DeleteOne", err), log.Any("ids", id))
if err == mongo.ErrNoDocuments {
return ADSNotExistError{}
}
return err
}
return nil
}
func updateOne(t *db.MongoTool, doc UpdateDoc, mats ...Matcher) error {
filter := pageopt.MergeM(mats)
now := time.Now()
if doc.UpdatedAt.IsZero() {
doc.UpdatedAt = now
}
res, err := coll(t).UpdateOne(filter, bson.M{"$set": doc})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateAds", table, "UpdateOne", err), log.Any("doc", doc), log.Any("filter", filter))
return err
}
if res.MatchedCount == 0 {
return ADSNotExistError{}
}
return nil
}
func UpdateOneByID(t *db.MongoTool, id ObjectID, doc UpdateDoc) error {
return updateOne(t, doc, (&IDMatch{ID: &id}).New())
}
func findOne(mats ...Matcher) (Ads, error) {
filter := pageopt.MergeM(mats)
ads := Ads{}
if err := coll(nil).FindOne(&ads, filter); err != nil {
return Ads{}, err
}
if ads.ID.IsZero() {
return Ads{}, ADSNotExistError{}
}
return ads, nil
}
func FindOneByID(id ObjectID) (Ads, error) {
return findOne((&IDMatch{ID: &id}).New())
}
// IncAdsClick 增加广告一次点击
func IncAdsClick(id primitive.ObjectID) error {
filter := bson.M{"_id": id}
update := bson.M{"$inc": bson.M{"click": 1}}
if _, err := coll(nil).UpdateOne(filter, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IncAdsClick", table, "UpdateOne", err), log.Any("id", id))
return err
}
return nil
}
var ActiveIsTrue = true
// ActiveList ActiveList
func ActiveList(sort Sort, skip, limit *int64, matchs ...Matcher) (AdsSlice, error) {
matchs = append(matchs, (&ActiveMatch{Active: &ActiveIsTrue}).New())
return List(sort, skip, limit, matchs...)
}
// ActiveStartAndEndList ActiveStartAndEndList
func ActiveStartAndEndList(sort Sort, skip, limit *int64, matchs ...Matcher) (AdsSlice, error) {
now := time.Now()
matchs = append(matchs,
(&StartLTEMatch{t: now}).New(),
(&EndGTMatch{t: now}).New(),
)
return ActiveList(sort, skip, limit, matchs...)
}
+9
View File
@@ -0,0 +1,9 @@
package adsmod
// ADSNotExistError
type ADSNotExistError struct {
}
func (ADSNotExistError) Error() string {
return "ads is not exist"
}
+183
View File
@@ -0,0 +1,183 @@
package adsmod
import (
"time"
"91porn-server/common/log"
"91porn-server/common/pageopt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
type AdsSlice []Ads
func (r AdsSlice) Len() int {
return len(r)
}
func (r AdsSlice) Swap(i, j int) {
r[i], r[j] = r[j], r[i]
}
func (r AdsSlice) Less(i, j int) bool {
return r[i].SortCode < r[j].SortCode
}
func (a AdsSlice) ToIDs() []ObjectID {
ids := make([]ObjectID, 0, len(a))
for _, v := range a {
ids = append(ids, v.ID)
}
return ids
}
func (a AdsSlice) ToPositions() []AdPosition {
ps := make([]AdPosition, 0, len(a))
for _, v := range a {
ps = append(ps, v.Position)
}
return ps
}
func (a AdsSlice) SliceByPosition(position AdPosition) AdsSlice {
ads := make(AdsSlice, 0, len(a))
for _, v := range a {
if v.Position == position {
ads = append(ads, v)
}
}
return ads
}
type Matcher = pageopt.Matcher
// AdsTypeMatch
type AdsTypeMatch struct {
AdsType *AdsType
}
func (a *AdsTypeMatch) New() Matcher {
return pageopt.NewAssignMatch("adsType", a.AdsType)
}
// AdPositionMatch
type AdPositionMatch struct {
Position *AdPosition
}
func (a *AdPositionMatch) New() Matcher {
return pageopt.NewAssignMatch("position", a.Position)
}
// AdPositionNinMatch
type AdPositionNinMatch struct {
PositionList []AdPosition
}
func (a *AdPositionNinMatch) New() Matcher {
return pageopt.NewNinMatch("position", a.PositionList)
}
// DistrictCodeMatch
type DistrictCodeMatch struct {
DistrictCode *string
}
func (a *DistrictCodeMatch) New() Matcher {
return pageopt.NewAssignMatch("districtCode", a.DistrictCode)
}
// ActiveMatch
type ActiveMatch struct {
Active *bool
}
type StartLTEMatch struct {
t time.Time
}
// IDMatch
type IDMatch = pageopt.IDMatch
// IDInMatch
type IDInMatch = pageopt.IDInMatch
type Sort = bson.D
type EndGTMatch struct {
t time.Time
}
func (a *ActiveMatch) New() Matcher {
return pageopt.NewAssignMatch("active", a.Active)
}
func (s *StartLTEMatch) New() Matcher {
return pageopt.NewLTEMatch("start", s.t)
}
func (e *EndGTMatch) New() Matcher {
return pageopt.NewGTMatch("end", e.t)
}
var (
Sort_createdAt_N1 = Sort{{Key: "createdAt", Value: -1}}
Sort_sortCode_N1 = Sort{{Key: "sortCode", Value: -1}}
)
func List(sort Sort, skip, limit *int64, matchs ...Matcher) (AdsSlice, error) {
filter := pageopt.MergeM(matchs)
opt := (&options.FindOptions{})
if len(sort) != 0 {
opt.SetSort(sort)
}
if skip != nil {
opt.SetSkip(*skip)
}
if limit != nil {
opt.SetLimit(*limit)
}
list := AdsSlice{}
err := coll(nil).Find(&list, filter, opt)
if err != nil {
log.Error("adsmod List error", log.E(err))
return nil, err
}
return list, nil
}
func Count(matchs ...Matcher) (int64, error) {
filter := pageopt.MergeM(matchs)
count, err := coll(nil).Count(filter)
if err != nil {
log.Error("adsmod List error", log.E(err))
return 0, err
}
return count, nil
}
func SumClickByID(matchs ...Matcher) (map[ObjectID]int64, error) {
filter := pageopt.MergeM(matchs)
var pipeline []bson.M
pipeline = append(pipeline, bson.M{"$match": filter})
pipeline = append(pipeline, bson.M{
"$group": bson.M{
"_id": "$_id",
"click": bson.M{"$sum": "$click"},
},
})
var list []struct {
ID ObjectID `bson:"_id"`
Click int64 `bson:"click"` //点击次数
}
err := coll(nil).Aggregate(&list, pipeline)
if err != nil {
return nil, err
}
m := make(map[ObjectID]int64, len(list))
for _, v := range list {
m[v.ID] += v.Click
}
return m, err
}
+118
View File
@@ -0,0 +1,118 @@
package adsmod
import (
"time"
"91porn-server/common"
"91porn-server/common/db"
"91porn-server/common/ysurl"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const (
SysAds AdsType = iota //系统广告
DiscAds //商区广告
)
const (
GetAdvertiseList = "GetAdvertiseList" // 获取广告信息
GetVersionList = "GetVersionList" // 获取版本信息
GetAnnounceList = "GetAnnounceList" // 获取公告信息
GetAnnounceByTypeList = "GetAnnounceByTypeList" // 根据类型获取公告信息
GetMsgAnnounceList = "GetMsgAnnounceList" // 获取消息公告信息
)
const (
StartupPage AdPosition = iota //启动页广告
HomeRecoSmall //首页-推荐小广告
HomePopupAnnou //首页-弹窗公告
NotifyPage //消息-界面广告
LiaoCarousel //撩吧-轮播广告
WalletPage //钱包-轮播广告
SearchPage //搜索-轮播广告
AvCommentPage //AV解说-轮播广告
SignPage //签到-轮播广告
)
type (
ObjectID = primitive.ObjectID
AdsType int
URLJumpType = ysurl.URLJumpType
// 广告位
AdPosition int
ReviewInfo struct {
ReviewID ObjectID `bson:"reviewID,omitempty"` //审核id
ReviewAt *time.Time `bson:"reviewAt,omitempty"` //审核时间 omitempty 不可删除
Reviewer *string `bson:"reviewer,omitempty"` //审核人 omitempty 不可删除
}
CoverProp = common.PictureProp
// Ads 广告模型
Ads struct {
ID ObjectID `bson:"_id,omitempty"` //广告id
AdsType AdsType `bson:"adsType"` //广告类型
Cover string `bson:"cover"` //广告封面图
Title string `bson:"title"` //广告标题
HrefType URLJumpType `bson:"type"` //广告链接类型
Href string `bson:"href"` //广告跳转类型
Position AdPosition `bson:"position"` //广告位置
SortCode int `bson:"sortCode"` //排序号
Active bool `bson:"active"` //激活状态 true:激活
Click int `bson:"click"` //点击次数
Remark string `bson:"remark"` //备注
DistrictCode string `bson:"districtCode"` //商区码
Start time.Time `bson:"start"` //开始时间
End time.Time `bson:"end"` //结束时间
CreatedAt time.Time `bson:"createdAt"` //创建时间
UpdatedAt time.Time `bson:"updatedAt"` //更新时间
ReviewInfo `bson:",inline"` //商区
CoverProp `bson:",inline"` //封面属性
}
InsertDoc struct {
AdsType AdsType `bson:"adsType"` //广告类型
Cover string `bson:"cover"` //广告封面图
Title string `bson:"title"` //广告标题
HrefType URLJumpType `bson:"type"` //广告链接类型
Href string `bson:"href"` //广告跳转类型
Position AdPosition `bson:"position"` //广告位置
SortCode int `bson:"sortCode"` //排序号
Active bool `bson:"active"` //激活状态 true:激活
Click int `bson:"click"` //点击次数
Remark string `bson:"remark"` //备注
DistrictCode string `bson:"districtCode"` //商区码
Start time.Time `bson:"start"` //开始时间
End time.Time `bson:"end"` //结束时间
CreatedAt time.Time `bson:"createdAt"` //创建时间
ReviewInfo `bson:",inline"`
CoverProp `bson:",inline"` //封面属性
}
UpdateDoc struct {
Title *string `bson:"title,omitempty"` //广告标题
Cover *string `bson:"cover,omitempty"` //广告封面图
HrefType *URLJumpType `bson:"type,omitempty"` //广告链接类型
Href *string `bson:"href,omitempty"` //广告跳转类型
Position *AdPosition `bson:"position,omitempty"` //广告位置
SortCode *int `bson:"sortCode,omitempty"` //排序号
Active *bool `bson:"active,omitempty"` //激活状态 true:激活
Click *int `bson:"click,omitempty"` //点击次数
Remark *string `bson:"remark,omitempty"` //备注
Start *time.Time `bson:"start,omitempty"` //开始时间
End *time.Time `bson:"end,omitempty"` //结束时间
UpdatedAt time.Time `bson:"updatedAt,omitempty"` //更新时间
ReviewInfo `bson:",inline"`
CoverProp `bson:",inline"` //封面属性
}
)
func Init() {
mdb = db.Init(table)
initAdsIndex()
}
+130
View File
@@ -0,0 +1,130 @@
package advanceconfigmod
import (
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const table = models.AdvanceConfig
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
func Init() {
mdb = db.Init(table)
initIndex()
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "sortCode", Value: -1}},
},
{
Keys: bson.D{{Key: "status", Value: 1}},
},
{
Keys: bson.D{{Key: "type", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func InsertOne(mt *db.MongoTool, cfg *AdvanceConfig) error {
if _, err := coll(mt).InsertOne(cfg); err != nil {
log.Warn(fmt.Sprintf("[METHOD-InsertOne]==> Model %s InsertOne fail error:%+v:", table, err))
return err
}
return nil
}
// FindDataByID 根据ID查询
func FindDataByID(id string) (AdvanceConfig, error) {
objID, err := primitive.ObjectIDFromHex(id)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByID]==> Model %s ObjectIDFromHex fail error:%+v:", table, err),
log.Any("id", id),
)
return AdvanceConfig{}, err
}
var aud AdvanceConfig
if err = coll(nil).FindOne(&aud, bson.M{"_id": objID}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByID]==> Model %s FindOne fail error:%+v:", table, err),
log.Any("objID", objID),
)
return aud, err
}
return aud, nil
}
// FindDataByUID 根据UID查询
func FindDataByUID(uid uint64) ([]*AdvanceConfig, error) {
var aud []*AdvanceConfig
if err := coll(nil).Find(&aud, bson.M{"uid": uid}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByUID]==> Model %s FindOne fail error:%+v:", table, err),
log.Any("uid", uid),
)
return aud, err
}
return aud, nil
}
// QueryAllDocument 分页查询文档
func QueryAllDocument(filter primitive.M, opts ...*options.FindOptions) (out []*AdvanceConfig, err error) {
if err = coll(nil).Find(&out, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllDocument", table, "Find", err),
log.Any("filter", filter),
)
return
}
return
}
// CountDocument 查询文档条目数
func CountDocument(filter primitive.M) (int64, error) {
if count, err := coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CountDocument", table, "Count", err),
log.Any("filter", filter),
)
return 0, err
} else {
return count, nil
}
}
// IsExist 根据标签名获取标签
func IsExist(filter primitive.M) (data *AdvanceConfig, err error) {
if err = coll(nil).FindOne(&data, filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "isExist", table, "FindOne", err),
log.Any("filter", filter),
)
return nil, err
}
return data, nil
}
// Update 修改订单
func Update(t *db.MongoTool, id primitive.ObjectID, set bson.M) error {
if _, err := coll(t).UpdateOne(bson.M{"_id": id}, set); err != nil {
log.Warn(fmt.Sprintf("[METHOD-Update]==> Model %s UpdateOne fail error:%+v:", table, err),
log.Any("id", id),
log.Any("set", set),
)
return err
}
return nil
}
+51
View File
@@ -0,0 +1,51 @@
package advanceconfigmod
import (
"go.mongodb.org/mongo-driver/bson/primitive"
"time"
)
type AppAdvanceRes struct {
List []*AppAdvanceConfig `json:"list" bson:"list"` // 预售配置列表
CardList []*ProductCard `json:"cardList" bson:"cardList"` // 预售卡配置
ActivityDetail ActivityDetail `json:"activityDetail" bson:"activityDetail"` // 活动详情
}
type AppAdvanceConfig struct {
Name string `json:"name" bson:"name"` // 名称
Url string `json:"url" bson:"url"` // 配置链接
Cover string `json:"cover" bson:"cover"` // 封面
SourceURL string `form:"sourceURL" json:"sourceURL"` // 视频资源链接
Type int `json:"type" bson:"type"` // 类型 1:宣传视频,2:游戏截图,3:盲盒展示,4:花絮视频,5:下载链接
}
type ActivityDetail struct {
StartTime time.Time `json:"startTime" bson:"startTime,omitempty"` // 游戏预售开始时间
EndTime time.Time `json:"endTime" bson:"endTime,omitempty"` // 游戏预售结束时间
ActivityTime time.Time `json:"activityTime" bson:"activityTime,omitempty"` // 游戏预售活动时间
Status int `json:"status" bson:"status"` // 预售订单状态
}
type ProductCard struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"productID" ` // ID
Name string `bson:"productName" json:"productName" ` // 商品名字
Desc string `bson:"desc" json:"desc"` // 内容描述
Type int `bson:"type" json:"type"` // 会员卡类型 (1:初级,2:高级)
SendGame bool `bson:"sendGame" json:"sendGame"` // 是否赠送游戏
BGImg string `bson:"bgImg" json:"bgImg"` // 背景图
OriginalPrice int64 `bson:"originalPrice" json:"originalPrice"` // 原价
DiscountedPrice int64 `bson:"discountedPrice" json:"discountedPrice"` // 现价 单位角(金币)
DiscountedPriceIos int64 `bson:"discountedPriceIos,omitempty" json:"discountedPriceIos,omitempty"` // ios现价
DiscountedPriceAnd int64 `bson:"discountedPriceAnd,omitempty" json:"discountedPriceAnd,omitempty"` // 安卓现价
Position string `bson:"position" json:"position"` // 位置
NewPrivilege []PrivilegeInfo `bson:"newPrivilege" json:"newPrivilege"` // 新特权
GameCode []string `bson:"gameCode" json:"gameCode"` // 游戏码
IsPay bool `json:"isPay" bson:"isPay"` // 是否购买
}
// PrivilegeInfo 特权详情
type PrivilegeInfo struct {
Image string `bson:"img" json:"img"` // 特权图片
Name string `bson:"privilegeName" json:"privilegeName"` // 特权名称
Desc string `bson:"privilegeDesc" json:"privilegeDesc"` // 特权描述
}
+32
View File
@@ -0,0 +1,32 @@
package advanceconfigmod
import (
"go.mongodb.org/mongo-driver/bson/primitive"
"time"
)
type AdvanceConfig struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // ID
Name string `json:"name" bson:"name"` // 名称
Url string `json:"url" bson:"url"` // 配置链接
Cover string `json:"cover" bson:"cover"` // 封面
SourceURL string `form:"sourceURL" json:"sourceURL"` // 视频资源链接
Status int `json:"status" bson:"status"` // 配置状态 1:开启,2:关闭
Type int `json:"type" bson:"type"` // 类型 1:宣传视频,2:游戏截图,3:盲盒展示,4:花絮视频,5:下载链接
SortCode int `json:"sortCode" bson:"sortCode"` // 排序
IsDelete bool `json:"isDelete" bson:"isDelete"` // 是否删除
UpdatedAct string `json:"updatedAct" bson:"updatedAct"` // 操作用户账号
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdateTime time.Time `json:"updateTime" bson:"updateTime"` // 文档更新时间
}
type AdvanceType int
const (
_ = iota
PromotionalVideo // 1 宣传视频
GameScreenshot // 2 游戏截图
BlindBox // 3 盲盒展示
SidelightsVideo // 4 花絮视频
Download // 5 下载链接
)
+126
View File
@@ -0,0 +1,126 @@
package advanceconfigmod
import (
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
type QueryAllCond struct {
Page int64 `form:"pageNumber" binding:"required"` // 查询页码
Limit int64 `form:"pageSize" binding:"required"` // 页码大小
Type *int `form:"type" json:"type" bson:"type,omitempty"` // 类型
Status *int `form:"status" json:"status" bson:"status,omitempty"` // 配置状态
}
type QueryAllRes struct {
List []*AdvanceConfig `json:"list"`
Total int64 `json:"total"`
}
func (receiver *QueryAllCond) Filter() bson.M {
var query = bson.M{}
if receiver.Type != nil {
query["type"] = receiver.Type
}
if receiver.Status != nil {
query["status"] = receiver.Status
}
query["isDelete"] = false
return query
}
func (receiver QueryAllCond) Options() *options.FindOptions {
return options.Find().SetSkip((receiver.Page - 1) * receiver.Limit).SetLimit(receiver.Limit).SetSort(bson.M{"sortCode": -1})
}
type WebCreateReq struct {
Name string `json:"name" bson:"name"` // 名称
Cover string `json:"cover" bson:"cover"` // 封面
SourceURL string `form:"sourceURL" json:"sourceURL"` // 视频资源链接
Status int `json:"status" bson:"status"` // 配置状态 1:开启,2:关闭
Type int `json:"type" bson:"type"` // 类型 1:宣传视频,2:游戏截图,3:盲盒展示,4:花絮视频,5:下载链接
SortCode int `json:"sortCode" bson:"sortCode"` // 排序
Url string `json:"url" bson:"url"` // 配置链接
}
// Create 发布数据fi
func (p *WebCreateReq) Create(manager string) *AdvanceConfig {
now := time.Now()
data := AdvanceConfig{
Name: p.Name,
Cover: p.Cover,
Url: p.Url,
Type: p.Type,
SourceURL: p.SourceURL,
SortCode: p.SortCode,
Status: p.Status,
IsDelete: false,
UpdatedAct: manager,
UpdateTime: now,
CreatedAt: now,
}
return &data
}
type WebUpdateReq struct {
ID string `json:"id" bson:"id" binding:"required"`
Name *string `json:"name" bson:"name,omitempty"` // 名称
Cover *string `json:"cover" bson:"cover,omitempty"` // 封面图
Type *int `json:"type" bson:"type,omitempty"` // 类型
SourceURL *string `form:"sourceURL" json:"sourceURL"` // 视频资源链接
SortCode *int `json:"sortCode" bson:"sortCode,omitempty"` // 排序
Status *int `json:"status" bson:"status,omitempty"` // 是否开启
Url *string `json:"url" bson:"url,omitempty"` // 配置链接
}
func (p *WebUpdateReq) Filter() primitive.ObjectID {
id, _ := primitive.ObjectIDFromHex(p.ID)
return id
}
func (p *WebUpdateReq) Update(updateAct string) bson.M {
var data = bson.M{}
if p.Name != nil {
data["name"] = *p.Name
}
if p.Cover != nil {
data["cover"] = *p.Cover
}
if p.SourceURL != nil {
data["sourceURL"] = *p.SourceURL
}
if p.Type != nil {
data["type"] = *p.Type
}
if p.SortCode != nil {
data["sortCode"] = *p.SortCode
}
if p.Status != nil {
data["status"] = *p.Status
}
if p.Url != nil {
data["url"] = *p.Url
}
data["updatedAct"] = updateAct
data["updateTime"] = time.Now()
return bson.M{"$set": data}
}
type WebDeleteReq struct {
ID string `json:"id" bson:"id" binding:"required"` // ID
}
func (p *WebDeleteReq) Filter() primitive.ObjectID {
id, _ := primitive.ObjectIDFromHex(p.ID)
return id
}
func (p *WebDeleteReq) Del(updateAct string) bson.M {
var data = bson.M{}
data["isDelete"] = true
data["updatedAct"] = updateAct
data["updateTime"] = time.Now()
return bson.M{"$set": data}
}
+254
View File
@@ -0,0 +1,254 @@
package advanceordermod
import (
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"errors"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const table = models.AdvanceOrder
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
func Init() {
mdb = db.Init(table)
initIndex()
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "uid", Value: 1}, {Key: "productID", Value: 1}},
},
{
Keys: bson.D{{Key: "uid", Value: 1}},
},
{
Keys: bson.D{{Key: "productID", Value: 1}},
},
{
Keys: bson.D{{Key: "oid", Value: 1}},
},
//{
// Keys: bson.D{{Key: "endTime", Value: 1}, {Key: "status", Value: 1}},
//},
{
Keys: bson.D{{Key: "status", Value: 1}, {Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "status", Value: 1}, {Key: "endTime", Value: 1}, {Key: "createdAt", Value: -1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func InsertOne(mt *db.MongoTool, cfg *AdvanceOrder) error {
if _, err := coll(mt).InsertOne(cfg); err != nil {
log.Warn(fmt.Sprintf("[METHOD-InsertOne]==> Model %s InsertOne fail error:%+v:", table, err))
return err
}
return nil
}
// CreditOrder 创建预付订单
func CreditOrder(t *db.MongoTool, cfg *AdvanceOrder) (data *AdvanceOrder, err error) {
filter := bson.M{"uid": cfg.UID, "productID": cfg.ProductID}
update := bson.M{"$set": bson.M{
"uid": cfg.UID,
"advOid": cfg.AdvOid,
"productID": cfg.ProductID,
"status": cfg.Status,
"totalAmount": cfg.TotalAmount,
"advanceAmount": cfg.AdvanceAmount,
"balanceAmount": cfg.BalanceAmount,
"endTime": cfg.EndTime,
"prepaidPrivilege": cfg.PrepaidPrivilege,
"todayUse": cfg.TodayUse,
"createdAt": cfg.CreatedAt,
}}
var advanceOrder *AdvanceOrder
if err := coll(t).FindOneAndUpsert(&advanceOrder, filter, update); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CreditOrder", table, "FindOneAndUpsert", err))
return nil, err
}
if advanceOrder.ID.IsZero() {
return nil, errors.New("insert is null")
}
return advanceOrder, nil
}
// GetUserValidOrder 获取用户当前订单
func GetUserValidOrder(uid uint64) (hasOrder bool, info *AdvanceOrder) {
n := time.Now()
var cond = bson.M{"uid": uid, "endTime": bson.M{"$gt": n}, "status": bson.M{"$in": []int{AdvanceSUCCESS, BalanceProcessing}}}
var opt = options.FindOne().SetSort(bson.D{{"endTime", -1}})
if err := coll(nil).FindOne(&info, cond, opt); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetUserValidCount", table, "FindOne", err),
log.Any("uid", uid),
)
return
}
if info == nil || info.ID.IsZero() {
return
}
hasOrder = true
return
}
// Debit 扣除每日使用次数
func Debit(t *db.MongoTool, uid uint64, debitPlan DebitPlan) error {
// 先查找用户订单
hasOrder, adOrder := GetUserValidOrder(uid)
if !hasOrder {
return errors.New("user advance order not found")
}
// 检查次数是否够用
if debitPlan.CoinVideoCount != nil {
if adOrder.PrepaidPrivilege.CoinVideoLimitPerDay-adOrder.TodayUse.CoinVideoCount < *debitPlan.CoinVideoCount {
return errors.New("free count not enough")
}
}
if debitPlan.LuckyDrawCount != nil {
if adOrder.PrepaidPrivilege.LuckyDrawLimitPerDay-adOrder.TodayUse.LuckyDrawCount < *debitPlan.LuckyDrawCount {
return errors.New("free count not enough")
}
}
if debitPlan.AiUndressCount != nil {
if adOrder.PrepaidPrivilege.AiUndressLimitPerDay-adOrder.TodayUse.AiUndressCount < *debitPlan.AiUndressCount {
return errors.New("free count not enough")
}
}
if debitPlan.DownloadCount != nil {
if adOrder.PrepaidPrivilege.DownloadLimitPerDay-adOrder.TodayUse.DownloadCount < *debitPlan.DownloadCount {
return errors.New("free count not enough")
}
}
if _, err := coll(t).UpdateOne(bson.M{"_id": adOrder.ID}, bson.M{
"$inc": debitPlan,
}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Debit", table, "UpdateOne", err),
log.Any("debitPlan", debitPlan),
log.Any("id", adOrder.ID),
)
return err
}
return nil
}
// ResetToday 重置当天使用次数
func ResetToday() error {
n := time.Now()
filter := bson.M{"endTime": bson.M{"$gt": n}, "status": bson.M{"$in": []int{AdvanceSUCCESS, BalanceProcessing}}}
if _, err := coll(nil).UpdateMany(filter, bson.M{
"$set": bson.M{
"todayUse.coinVideoCount": int64(0),
"todayUse.luckyDrawCount": int64(0),
"todayUse.aiUndressCount": int64(0),
"todayUse.downloadCount": int64(0),
},
}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "ResetToday", table, "UpdateMany", err))
return err
}
return nil
}
// FindDataByID 根据ID查询
func FindDataByID(id string) (AdvanceOrder, error) {
objID, err := primitive.ObjectIDFromHex(id)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByID]==> Model %s ObjectIDFromHex fail error:%+v:", table, err),
log.Any("id", id),
)
return AdvanceOrder{}, err
}
var aud AdvanceOrder
if err = coll(nil).FindOne(&aud, bson.M{"_id": objID}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByID]==> Model %s FindOne fail error:%+v:", table, err),
log.Any("objID", objID),
)
return aud, err
}
return aud, nil
}
// FindDataByUID 根据UID查询
func FindDataByUID(uid uint64) ([]*AdvanceOrder, error) {
var aud []*AdvanceOrder
if err := coll(nil).Find(&aud, bson.M{"uid": uid}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByUID]==> Model %s FindOne fail error:%+v:", table, err),
log.Any("uid", uid),
)
return aud, err
}
return aud, nil
}
// QueryAllDocument 分页查询文档
func QueryAllDocument(filter primitive.M, opts ...*options.FindOptions) (out []*AdvanceOrder, err error) {
if err = coll(nil).Find(&out, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllDocument", table, "Find", err),
log.Any("filter", filter),
)
return
}
return
}
// CountDocument 查询文档条目数
func CountDocument(filter primitive.M) (int64, error) {
if count, err := coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CountDocument", table, "Count", err),
log.Any("filter", filter),
)
return 0, err
} else {
return count, nil
}
}
// IsExist 根据标签名获取标签
func IsExist(filter primitive.M) (data *AdvanceOrder, err error) {
if err = coll(nil).FindOne(&data, filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "isExist", table, "FindOne", err),
log.Any("filter", filter),
)
return nil, err
}
return data, nil
}
// Update 修改订单
func Update(t *db.MongoTool, id primitive.ObjectID, set bson.M) error {
set["updatedAt"] = time.Now()
if _, err := coll(t).UpdateOne(bson.M{"_id": id}, bson.M{"$set": set}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-Update]==> Model %s UpdateOne fail error:%+v:", table, err),
log.Any("id", id),
log.Any("set", set),
)
return err
}
return nil
}
+56
View File
@@ -0,0 +1,56 @@
package advanceordermod
import "time"
// AdvanceStatus 预售状态
type AdvanceStatus struct {
ActivityStatus bool `json:"activityStatus" bson:"activityStatus"` // 预售活动是否开启
ActivityPopUp bool `json:"activityPopUp" bson:"activityPopUp"` // 预售活动是否首页弹窗
GameActivityPopUp bool `json:"gameActivityPopUp" bson:"gameActivityPopUp"` // 游戏预售是否首页弹窗
GameActivityStatus bool `json:"gameActivityStatus" bson:"gameActivityStatus"` // 游戏预售是否开启
BalancePayment bool `json:"balancePayment" bson:"balancePayment"` // 是否有尾款支付
BalanceAmount int64 `bson:"balanceAmount" json:"balanceAmount"` // 尾款金额
Status int `json:"status" bson:"status"` // 预售订单状态
StartTime time.Time `json:"startTime" bson:"startTime,omitempty"` // 预售尾款开始时间
EndTime time.Time `json:"endTime" bson:"endTime,omitempty"` // 预售尾款结束时间
OId string `json:"oid" bson:"oid"` // 预付订单号
PrivilegeLimit PrivilegeLimit `json:"privilegeLimit"` // 预付权益
}
type PrivilegeLimit struct {
HasLimit bool `json:"hasLimit"` // 是否有权益限制
Limit struct {
CoinVideoLimitPerDay int64 `json:"coinVideoLimitPerDay"` // 每日金币视频免费次数
LuckyDrawLimitPerDay int64 `json:"luckyDrawLimitPerDay"` // 每日抽奖次数限制
AiUndressLimitPerDay int64 `json:"aiUndressLimitPerDay"` // 每日ai脱衣次数限制
DownloadLimitPerDay int64 `json:"downloadLimitPerDay"` // 每日下载次数限制
} `json:"limit"` // 每日限制
Remain struct {
TodayCoinVideoCount int64 `json:"todayCoinVideoCount"` // 今日剩余金币视频观看次数
TodayLuckyDrawCount int64 `json:"todayLuckyDrawCount"` // 今日剩余抽奖次数
TodayAiUndressCount int64 `json:"todayAiUndressCount"` // 今日剩余ai脱衣次数
TodayDownloadCount int64 `json:"todayDownloadCount"` // 今日剩余下载次数
} `json:"remain"` // 当日可使用次数
}
type DebitPlan struct {
CoinVideoCount *int64 `bson:"todayUse.coinVideoCount,omitempty"` // 金币视频观看次数
LuckyDrawCount *int64 `bson:"todayUse.luckyDrawCount,omitempty"` // 抽奖次数
AiUndressCount *int64 `bson:"todayUse.aiUndressCount,omitempty"` // ai脱衣次数
DownloadCount *int64 `bson:"todayUse.downloadCount,omitempty"` // 下载次数
}
func (d *DebitPlan) InvertCounts() {
if d.CoinVideoCount != nil {
*d.CoinVideoCount = -(*d.CoinVideoCount)
}
if d.LuckyDrawCount != nil {
*d.LuckyDrawCount = -(*d.LuckyDrawCount)
}
if d.AiUndressCount != nil {
*d.AiUndressCount = -(*d.AiUndressCount)
}
if d.DownloadCount != nil {
*d.DownloadCount = -(*d.DownloadCount)
}
}
+62
View File
@@ -0,0 +1,62 @@
package advanceordermod
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const (
DEFAULT = iota // 0 默认
AdvanceProcessing // 1 预付中
AdvanceSUCCESS // 2 预付成功
BalanceProcessing // 3 尾款预付中
BalanceSUCCESS // 4 尾款预付成功
)
type AdvanceOrder struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
UID uint64 `json:"uid" bson:"uid"` // 用户ID
AdvOid string `json:"advOid" bson:"advOid"` // 预付支付平台订单号
BalOid string `json:"balOid" bson:"balOid"` // 尾款支付平台订单号
ProductID primitive.ObjectID `json:"productID" bson:"productID"` // 预售产品ID
Status int `json:"status" bson:"status" ` // 预售订单状态
TotalAmount int64 `bson:"totalAmount" json:"totalAmount" ` // 预付卡总金额
AdvanceAmount int64 `bson:"advanceAmount" json:"advanceAmount" ` // 预付金额
BalanceAmount int64 `bson:"balanceAmount" json:"balanceAmount"` // 尾款金额
StartTime time.Time `json:"startTime" bson:"startTime,omitempty"` // 预售尾款开始时间
EndTime time.Time `json:"endTime" bson:"endTime,omitempty"` // 预售尾款结束时间
PrepaidPrivilege AdvanceCardPrepaidPrivilege `json:"prepaidPrivilege" bson:"prepaidPrivilege"` // 预付后的权益
TodayUse DayUse `json:"todayUse" bson:"todayUse"` // 当天使用次数
CreatedAt time.Time `json:"createdAt" bson:"createdAt,omitempty"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt,omitempty"` // 刷新时间
}
type AdvanceCardPrepaidPrivilege struct {
CoinVideoLimitPerDay int64 `json:"coinVideoLimitPerDay" bson:"coinVideoLimitPerDay"` // 每日金币视频免费次数
LuckyDrawLimitPerDay int64 `json:"luckyDrawLimitPerDay" bson:"luckyDrawLimitPerDay"` // 每日抽奖次数限制
AiUndressLimitPerDay int64 `json:"aiUndressLimitPerDay" bson:"aiUndressLimitPerDay"` // 每日ai脱衣次数限制
DownloadLimitPerDay int64 `json:"downloadLimitPerDay" bson:"downloadLimitPerDay"` // 每日下载次数限制
}
type DayUse struct {
CoinVideoCount int64 `json:"coinVideoCount" bson:"coinVideoCount"` // 金币视频观看次数
LuckyDrawCount int64 `json:"luckyDrawCount" bson:"luckyDrawCount"` // 抽奖次数
AiUndressCount int64 `json:"aiUndressCount" bson:"aiUndressCount"` // ai脱衣次数
DownloadCount int64 `json:"downloadCount" bson:"downloadCount"` // 下载次数
}
type AdvanceOrderExport struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty" xlsx:"ID"`
UID uint64 `json:"uid" bson:"uid" xlsx:"用户ID"` // 用户ID
AdvOid string `json:"advOid" bson:"advOid" xlsx:"预付支付平台订单号"` // 预付支付平台订单号
BalOid string `json:"balOid" bson:"balOid" xlsx:"尾款支付平台订单号"` // 尾款支付平台订单号
ProductID primitive.ObjectID `json:"productID" bson:"productID" xlsx:"预售产品ID"` // 预售产品ID
Status string `json:"status" bson:"status" xlsx:"预售订单状态"` // 预售订单状态
TotalAmount int64 `bson:"totalAmount" json:"totalAmount" xlsx:"预付卡总金额"` // 预付卡总金额
AdvanceAmount int64 `bson:"advanceAmount" json:"advanceAmount" xlsx:"预付金额"` // 预付金额
BalanceAmount int64 `bson:"balanceAmount" json:"balanceAmount" xlsx:"尾款金额"` // 尾款金额
StartTime time.Time `json:"startTime" bson:"startTime,omitempty" xlsx:"预售尾款开始时间"` // 预售尾款开始时间
EndTime time.Time `json:"endTime" bson:"endTime,omitempty" xlsx:"预售尾款结束时间"` // 预售尾款结束时间
CreatedAt time.Time `json:"createdAt" bson:"createdAt,omitempty" xlsx:"创建时间"` // 创建时间
}
+49
View File
@@ -0,0 +1,49 @@
package advanceordermod
import (
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
type QueryAllCond struct {
Page int64 `form:"pageNumber" json:"pageNumber" binding:"required"` // 查询页码
Limit int64 `form:"pageSize" json:"pageSize" binding:"required"` // 页码大小
AdvOid *string `form:"advOid" json:"advOid" bson:"advOid"` // 预付订单号
BalOid *string `form:"balOid" json:"balOid" bson:"balOid"` // 尾款订单号
Uid *int `form:"uid" json:"uid" bson:"uid"` // 用户ID
Status *int `form:"status" json:"status" bson:"status"` // 预售订单状态
TimeField string `form:"timeField" json:"timeField"` // 时间筛选字段 createdAt 创建时间 endTime 预售尾款结束时间
Start *time.Time `form:"start" json:"start"` // 开始时间
End *time.Time `form:"end" json:"end"` // 结束时间
}
type QueryAllRes struct {
List []*AdvanceOrder `json:"list"`
Total int64 `json:"total"`
}
func (receiver *QueryAllCond) Filter() bson.M {
var query = bson.M{}
if receiver.Uid != nil {
query["uid"] = receiver.Uid
}
if receiver.Status != nil {
query["status"] = receiver.Status
}
if receiver.AdvOid != nil {
query["advOid"] = receiver.AdvOid
}
if receiver.BalOid != nil {
query["balOid"] = receiver.BalOid
}
if receiver.TimeField != "" && receiver.Start != nil && receiver.End != nil {
query[receiver.TimeField] = bson.M{"$gte": receiver.Start, "$lt": receiver.End}
}
return query
}
func (receiver QueryAllCond) Options() *options.FindOptions {
return options.Find().SetSkip((receiver.Page - 1) * receiver.Limit).SetLimit(receiver.Limit).SetSort(bson.M{"createdAt": -1})
}
+198
View File
@@ -0,0 +1,198 @@
package aiUnDressmod
import (
"errors"
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const table = models.AiUnDress
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// InitARDIndex 设置账户充值流水表索引
func initIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "uid", Value: 1}},
},
{
Keys: bson.D{{Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "status", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("AiUnDressIndex err+%v", err))
}
}
// Insert 插入一条订单
func Insert(a *AiUnDress) error {
a.CreatedAt = time.Now()
a.UpdatedAt = a.CreatedAt
res, err := coll(nil).InsertOne(a)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-Insert]==> Model %s InsertOne fail error:%+v:", table, err))
return err
}
a.ID, _ = res.InsertedID.(primitive.ObjectID)
return nil
}
func InsertOne(mt *db.MongoTool, cfg AiUnDress) error {
if _, err := coll(mt).InsertOne(cfg); err != nil {
log.Warn(fmt.Sprintf("[METHOD-InsertOne]==> Model %s InsertOne fail error:%+v:", table, err))
return err
}
return nil
}
// FindOrders 查询脱衣订单
func FindOrders(cond bson.M, opts *options.FindOptions) (int64, []*AiUnDress, error) {
data := make([]*AiUnDress, 0)
if err := coll(nil).Find(&data, cond, opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindOrders]==> Model %s Find fail error:%+v:", table, err),
log.Any("cond", cond),
)
return 0, data, err
}
total, err := coll(nil).Count(cond)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindOrders]==> Model %s Count fail error:%+v:", table, err),
log.Any("cond", cond),
)
return total, data, err
}
return total, data, nil
}
// Update 修改订单
func Update(t *db.MongoTool, id primitive.ObjectID, set bson.M) error {
set["updatedAt"] = time.Now()
if _, err := coll(t).UpdateOne(bson.M{"_id": id}, bson.M{"$set": set}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-Update]==> Model %s UpdateOne fail error:%+v:", table, err),
log.Any("id", id),
log.Any("set", set),
)
return err
}
return nil
}
// TransitionStatus atomically changes an order from the expected status. The
// returned boolean is false when another worker or callback handled it first.
func TransitionStatus(t *db.MongoTool, id primitive.ObjectID, from, to int, set bson.M) (bool, error) {
if set == nil {
set = bson.M{}
}
set["status"] = to
set["updatedAt"] = time.Now()
result, err := coll(t).UpdateOne(bson.M{"_id": id, "status": from}, bson.M{"$set": set})
if err != nil {
return false, err
}
return result.ModifiedCount == 1, nil
}
// Edit 修改文档
func Edit(t *db.MongoTool, filter, update primitive.M) error {
result, err := coll(t).UpdateOne(filter, update)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-Edit]==> Model %s UpdateOne fail error:%+v:", table, err),
log.Any("filter", filter),
log.Any("update", update),
)
return err
}
if result.ModifiedCount == 0 {
log.Error(fmt.Sprintf("[METHOD-Edit]==> Model %s result.ModifiedCount fail error: ModifiedCount is zero", table),
log.Any("filter", filter),
log.Any("update", update),
)
return errors.New("result is null")
}
return nil
}
// FindDataByID 根据ID查询
func FindDataByID(id string) (AiUnDress, error) {
objID, err := primitive.ObjectIDFromHex(id)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByID]==> Model %s ObjectIDFromHex fail error:%+v:", table, err),
log.Any("id", id),
)
return AiUnDress{}, err
}
var aud AiUnDress
if err = coll(nil).FindOne(&aud, bson.M{"_id": objID}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByID]==> Model %s FindOne fail error:%+v:", table, err),
log.Any("objID", objID),
)
return aud, err
}
return aud, nil
}
// QueryAllDocument 分页查询文档
func QueryAllDocument(filter primitive.M, opts ...*options.FindOptions) ([]*AiUnDress, error) {
var out []*AiUnDress
if err := coll(nil).Find(&out, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[METHOD-QueryAllDocument]==> Model %s Find fail error:%+v:", table, err),
log.Any("filter", filter),
)
return nil, err
}
return out, nil
}
// CountDocument 查询文档条目数
func CountDocument(filter primitive.M) (int64, error) {
count, err := coll(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-CountDocument]==> Model %s Count fail error:%+v:", table, err),
log.Any("filter", filter),
)
return 0, err
}
return count, nil
}
func FindByID(t *db.MongoTool, id primitive.ObjectID) (*AiUnDress, error) {
var acf AiUnDress
return &acf, coll(t).FindOne(&acf, bson.M{"_id": id})
}
func InsertMany(mt *db.MongoTool, cfg []AiUnDress) error {
if _, err := coll(mt).InsertMany(cfg); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertMany", table, "InsertMany", err))
return err
}
return nil
}
// 更新订单提交状态
func SubmitStatus(id string, status int, remark string) error {
_id, err := primitive.ObjectIDFromHex(id)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-SubmitStatus]==> Model %s ObjectIDFromHex fail error:%+v:", table, err), log.Any("id", id))
return err
}
_, err = coll(nil).UpdateOne(bson.M{"_id": _id}, bson.M{"$set": bson.M{"status": status, "newPic": nil, "remark": remark}})
return err
}
+165
View File
@@ -0,0 +1,165 @@
package aiUnDressmod
import (
"time"
"91porn-server/models/commod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
// AiUnDressAppRes AI记录 App返回给前端
type AiUnDressAppRes struct {
UID uint64 `json:"uid" bson:"uid"` // 用户id
OriginPic string `json:"originPic" bson:"originPic"` // 脱衣原图
OriginPics []string `json:"originPics" bson:"originPics"` // 脱衣原图多张
NewPic []string `json:"newPic" bson:"newPic"` // 脱衣后新图
Coin int64 `json:"coin" bson:"coin"` // 此次脱衣金币个数
Status int `json:"status" bson:"status"` // 1、进行中 2、生成成功 3、生成失败
Remark string `json:"remark" bson:"remark"` // 备注
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 刷新时间
}
type ListRequest struct {
Status *int `form:"status" json:"status" bson:"status"` // 1、进行中 2、生成成功 3、生成失败
commod.Page
}
func (receiver *ListRequest) Filter(uid uint64) primitive.M {
filter := bson.M{}
if receiver.Status != nil {
if *receiver.Status == Processing {
filter["status"] = bson.M{"$in": []int{Processing, SubmitOrder}}
} else {
filter["status"] = receiver.Status
}
}
filter["uid"] = uid
filter["isHide"] = bson.M{"$in": []any{nil, false}}
return filter
}
func (receiver *ListRequest) Options() *options.FindOptions {
return options.Find().SetSkip(int64(receiver.Skip())).SetLimit(int64(receiver.Limit())).SetSort(bson.M{"updatedAt": -1})
}
type GenerateRequest struct {
OriginPic []string `json:"originPic" bson:"originPic"` // 脱衣原图
Coin int64 `json:"coin" bson:"coin"` // 此次脱衣金币个数
IsFreeTimes bool `json:"isFreeTimes" bson:"isFreeTimes"` // 是否使用免费次数
ShareTitle string `json:"shareTitle"` // 分享标题
ShareStatus int `json:"shareStatus" bson:"shareStatus"` // 是否分享 0-不分享 1-分享
}
//func (receiver *GenerateRequest) Generate(uid uint64) AiUnDress {
// now := time.Now()
// return AiUnDress{
// OriginPic: receiver.OriginPic,
// UID: uid,
// Coin: receiver.Coin,
// Status: Processing,
// IsHide: false,
// UpdatedAt: now,
// CreatedAt: now,
// }
//}
func (receiver *GenerateRequest) GenerateMany(orderId primitive.ObjectID, orderCreatedAt time.Time, uid uint64, privilegeCount, debitFreeCount, debitCoins, debitIncomeCoins, singeCoin int64, shareTitle string, shareStatus int) []AiUnDress {
var generateAiUnDress []AiUnDress
if len(receiver.OriginPic) > 0 {
p := receiver.OriginPic[0]
//for _, p := range receiver.OriginPic {
var (
picture []string
newCoin int64
newDebitAmountCoin int64
newDebitIncomeCoin int64
newDebitFreeCount int64
isFreeTimes bool
)
picture = append(picture, p)
if debitFreeCount > 0 {
isFreeTimes = true
newDebitFreeCount = 1
// 免费次数减一
debitFreeCount--
} else if privilegeCount > 0 {
isFreeTimes = true
newDebitFreeCount = 1
privilegeCount--
} else {
if debitCoins > 0 {
newDebitAmountCoin = min(singeCoin, debitCoins)
debitCoins -= newDebitAmountCoin
newCoin += newDebitAmountCoin
} else {
newDebitIncomeCoin = min(singeCoin, debitIncomeCoins)
debitIncomeCoins -= newDebitIncomeCoin
newCoin += debitIncomeCoins
}
if newCoin < singeCoin {
if debitCoins >= singeCoin-newCoin {
new2DebitAmountCoin := min(singeCoin-newCoin, debitCoins)
debitCoins -= new2DebitAmountCoin
newDebitAmountCoin += new2DebitAmountCoin
newCoin += new2DebitAmountCoin
} else {
new2DebitIncomeCoin := min(singeCoin-newCoin, debitIncomeCoins)
debitIncomeCoins -= new2DebitIncomeCoin
newDebitIncomeCoin += new2DebitIncomeCoin
newCoin += new2DebitIncomeCoin
}
}
}
generateAiUnDress = append(generateAiUnDress, AiUnDress{
ID: orderId,
OriginPics: picture,
Coin: newDebitAmountCoin + newDebitIncomeCoin,
DebitAmountCoin: newDebitAmountCoin,
DebitIncomeCoin: newDebitIncomeCoin,
IsFreeTimes: isFreeTimes,
Count: newDebitFreeCount,
UID: uid,
Status: Processing,
IsHide: false,
ShareTitle: shareTitle,
ShareStatus: shareStatus,
UpdatedAt: orderCreatedAt,
CreatedAt: orderCreatedAt,
})
}
//}
return generateAiUnDress
}
// 定义一个函数,用来返回两个整数中的较小值
func min(a, b int64) int64 {
if a < b {
return a
}
return b
}
type DelRequest struct {
ID primitive.ObjectID `json:"id" bson:"id"` // AI订单ID
}
func (receiver *DelRequest) Filter() primitive.M {
filter := bson.M{}
filter["_id"] = receiver.ID
return filter
}
func (receiver *DelRequest) Update() primitive.M {
update := bson.M{}
update["isHide"] = true
update["updatedAt"] = time.Now()
return bson.M{"$set": update}
}
+64
View File
@@ -0,0 +1,64 @@
package aiUnDressmod
import (
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const (
Processing = 1 // 1、进行中
SUCCESS = 2 // 2、成功
FAILURE = 3 // 3、失败
REFUND = 4 // 4、退款
PartSuccess = 5 // 5、部分成功
SubmitOrder = 6 // 6、已提交
)
type Status int
var status = map[Status]string{
Processing: "processing",
FAILURE: "failure",
SUCCESS: "success",
REFUND: "refund",
}
func (s Status) Desc() string {
if desc, ok := status[s]; ok {
return desc
}
return ""
}
var mdb *db.MongoDB
// AiUnDress AI脱衣
type AiUnDress struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 脱衣记录id
UID uint64 `json:"uid" bson:"uid"` // 用户id
OriginPic string `json:"originPic" bson:"originPic"` // 脱衣原图
OriginPics []string `json:"originPics" bson:"originPics"` // 脱衣原图多张
NewPic []string `json:"newPic" bson:"newPic"` // 脱衣后新图
Coin int64 `json:"coin" bson:"coin"` // 此次脱衣金币个数
DebitAmountCoin int64 `json:"debitAmountCoin" bson:"debitAmountCoin"` // 此次脱衣扣除金币个数
DebitIncomeCoin int64 `json:"debitIncomeCoin" bson:"debitIncomeCoin"` // 此次脱衣扣除收益金币个数
Status int `json:"status" bson:"status"` // 1、进行中 2、生成成功 3、生成失败 4、退款 5、部分成功 6、已提交
Count int64 `json:"count" bson:"count"` // 此次ai脱衣消耗次数
IsFreeTimes bool `json:"isFreeTimes" bson:"isFreeTimes"` // 是否使用免费次数
IsHide bool `json:"isHide" bson:"isHide"` // 是否被用户隐藏(用户订单列表是否不显示)
Remark string `json:"remark" bson:"remark"` // 备注
UpdateAct string `json:"updateAct" bson:"updateAct"` // 修改账号
ShareTitle string `json:"shareTitle" bson:"shareTitle"` // 分享标题
ShareStatus int `json:"shareStatus" bson:"shareStatus"` // 是否分享 0-不分享 1-分享
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 刷新时间
}
func Init() {
mdb = db.Init(table)
initIndex()
}
+105
View File
@@ -0,0 +1,105 @@
package aiUnDressmod
import (
"time"
"91porn-server/models/commod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
// RechargeUpdateReq 修改参数
type RechargeUpdateReq struct {
StatusDesc *string `json:"statusDesc" bson:"statusDesc"` // 状态描述
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
}
type RchgQueryReq struct {
ID *string `form:"id" json:"_id,omitempty" bson:"_id"` // 流水id
UID *uint64 `form:"uid" json:"uid,omitempty" bson:"uid"` // 用户id
Status *int `form:"status" json:"status,omitempty" bson:"status"` // 1、进行中 2、生成成功 3、生成失败 4、已经退款
}
type WebListRequest struct {
Status *int `form:"status" json:"status" bson:"status"` // 1、进行中 2、生成成功 3、生成失败 4、已经退款
UID *uint64 `form:"uid" json:"uid,omitempty" bson:"uid"` // 用户id
ID *string `form:"id" json:"_id,omitempty" bson:"_id"` // 流水id
commod.Page
}
func (receiver *WebListRequest) Filter() primitive.M {
filter := bson.M{}
if receiver.Status != nil {
filter["status"] = receiver.Status
}
if receiver.UID != nil {
filter["uid"] = receiver.UID
}
if receiver.ID != nil {
id, _ := primitive.ObjectIDFromHex(*receiver.ID)
filter["_id"] = id
}
return filter
}
func (receiver *WebListRequest) Options() *options.FindOptions {
return options.Find().SetSkip(int64(receiver.Skip())).SetLimit(int64(receiver.Limit() + 1)).SetSort(bson.M{"updatedAt": -1})
}
type EditCond struct {
ID string `json:"id" binding:"required"` // 文档
NewPic *[]string `json:"newPic" bson:"newPic"` // 脱衣后新图
Status *int `json:"status" bson:"status"` // 状态 1、进行中 2、生成成功 3、生成失败
Remark *string `json:"remark" bson:"remark"` // 拒绝理由
}
type AutoCond struct {
ID string `json:"id" binding:"required"` // 文档
}
type AutoBatchCond struct {
IDs []string `json:"ids" from:"ids" binding:"required"` // 文档
Pass bool `json:"pass" from:"pass"` // 是否通过
Remark string `json:"remark" from:"remark"` // 拒绝理由
}
func (receiver *EditCond) Filter() bson.M {
objID, _ := primitive.ObjectIDFromHex(receiver.ID)
return bson.M{"_id": objID}
}
func (receiver *EditCond) Update(updateAct string) bson.M {
var update = bson.M{}
if receiver.NewPic != nil {
update["newPic"] = receiver.NewPic
}
if receiver.Status != nil {
update["status"] = receiver.Status
}
if receiver.Remark != nil {
update["remark"] = receiver.Remark
}
update["updateAct"] = updateAct
update["updatedAt"] = time.Now()
return bson.M{"$set": update}
}
type AiUndressOrderReq struct {
AppId int `json:"appId"`
FileUrl []string `json:"fileUrl"` //base64存的文件服地址
UserId string `json:"userId"` //用户id
AppOrderNum string `json:"appOrderNum"` //app中生成的订单号
NotifyUrl string `json:"notifyUrl"` //回调产品地址
}
type AiUndressOrderResp struct {
Code int `json:"code"`
}
type CallBackReq struct {
ImgUrl []string `json:"imgUrl"` //脱衣后地址
AppOrderNum string `json:"appOrderNum"` //app订单号
Msg string `json:"msg"` //消息
}
@@ -0,0 +1,177 @@
package aichangefaceimgmod
import (
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
const table = models.AiChangeFaceImg
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// InitARDIndex 设置账户充值流水表索引
func initIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "uid", Value: 1}},
},
{
Keys: bson.D{{Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "status", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("AiUnDressIndex err+%v", err))
}
}
// Insert 插入一条订单
func Insert(a *AiChangeFaceImg) error {
a.CreatedAt = time.Now()
a.UpdatedAt = a.CreatedAt
res, err := coll(nil).InsertOne(a)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-Insert]==> Model %s InsertOne fail error:%+v:", table, err))
return err
}
a.ID, _ = res.InsertedID.(primitive.ObjectID)
return nil
}
func InsertOne(mt *db.MongoTool, cfg AiChangeFaceImg) error {
if _, err := coll(mt).InsertOne(cfg); err != nil {
log.Warn(fmt.Sprintf("[METHOD-InsertOne]==> Model %s InsertOne fail error:%+v:", table, err))
return err
}
return nil
}
// FindOrders 查询AI换脸订单
func FindOrders(cond bson.M, opts *options.FindOptions) (int64, []*AiChangeFaceImg, error) {
data := make([]*AiChangeFaceImg, 0)
if err := coll(nil).Find(&data, cond, opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindOrders]==> Model %s Find fail error:%+v:", table, err),
log.Any("cond", cond),
)
return 0, data, err
}
total, err := coll(nil).Count(cond)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindOrders]==> Model %s Count fail error:%+v:", table, err),
log.Any("cond", cond),
)
return total, data, err
}
return total, data, nil
}
// Update 修改订单
func Update(t *db.MongoTool, id primitive.ObjectID, set bson.M) error {
set["updatedAt"] = time.Now()
if _, err := coll(t).UpdateOne(bson.M{"_id": id}, bson.M{"$set": set}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-Update]==> Model %s UpdateOne fail error:%+v:", table, err),
log.Any("id", id),
log.Any("set", set),
)
return err
}
return nil
}
// TransitionStatus atomically changes an order from the expected status. The
// returned boolean is false when another worker or callback handled it first.
func TransitionStatus(t *db.MongoTool, id primitive.ObjectID, from, to int, set bson.M) (bool, error) {
if set == nil {
set = bson.M{}
}
set["status"] = to
set["updatedAt"] = time.Now()
result, err := coll(t).UpdateOne(bson.M{"_id": id, "status": from}, bson.M{"$set": set})
if err != nil {
return false, err
}
return result.ModifiedCount == 1, nil
}
// Edit 修改文档
func Edit(t *db.MongoTool, filter, update primitive.M) error {
result, err := coll(t).UpdateOne(filter, update)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-Edit]==> Model %s UpdateOne fail error:%+v:", table, err),
log.Any("filter", filter),
log.Any("update", update),
)
return err
}
if result.ModifiedCount == 0 {
log.Error(fmt.Sprintf("[METHOD-Edit]==> Model %s result.ModifiedCount fail error: ModifiedCount is zero", table),
log.Any("filter", filter),
log.Any("update", update),
)
return errors.New("result is null")
}
return nil
}
// FindDataByID 根据ID查询
func FindDataByID(id string) (AiChangeFaceImg, error) {
objID, err := primitive.ObjectIDFromHex(id)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByID]==> Model %s ObjectIDFromHex fail error:%+v:", table, err),
log.Any("id", id),
)
return AiChangeFaceImg{}, err
}
var aud AiChangeFaceImg
if err = coll(nil).FindOne(&aud, bson.M{"_id": objID}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-FindDataByID]==> Model %s FindOne fail error:%+v:", table, err),
log.Any("objID", objID),
)
return aud, err
}
return aud, nil
}
// QueryAllDocument 分页查询文档
func QueryAllDocument(filter primitive.M, opts ...*options.FindOptions) ([]*AiChangeFaceImg, error) {
var out []*AiChangeFaceImg
if err := coll(nil).Find(&out, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[METHOD-QueryAllDocument]==> Model %s Find fail error:%+v:", table, err),
log.Any("filter", filter),
)
return nil, err
}
return out, nil
}
// CountDocument 查询文档条目数
func CountDocument(filter primitive.M) (int64, error) {
count, err := coll(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-CountDocument]==> Model %s Count fail error:%+v:", table, err),
log.Any("filter", filter),
)
return 0, err
}
return count, nil
}
func FindByID(t *db.MongoTool, id primitive.ObjectID) (*AiChangeFaceImg, error) {
var acf AiChangeFaceImg
return &acf, coll(t).FindOne(&acf, bson.M{"_id": id})
}
+99
View File
@@ -0,0 +1,99 @@
package aichangefaceimgmod
import (
"91porn-server/models/commod"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
// AiChangFaceImgAppRes AI记录 App返回给前端
type AiChangFaceImgAppRes struct {
UID uint64 `json:"uid" bson:"uid"` // 用户id
OriginPic string `json:"originPic" bson:"originPic"` // 脱衣原图
NewPic []string `json:"newPic" bson:"newPic"` // 脱衣后新图
Status int `json:"status" bson:"status"` // 1、进行中 2、生成成功 3、生成失败
Remark string `json:"remark" bson:"remark"` // 备注
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 刷新时间
}
type ListRequest struct {
Status *int `form:"status" json:"status" bson:"status"` // 1、进行中 2、生成成功 3、生成失败
commod.Page
}
func (receiver *ListRequest) Filter(uid uint64) primitive.M {
filter := bson.M{}
if receiver.Status != nil {
filter["status"] = receiver.Status
if *receiver.Status == 1 {
filter["status"] = bson.M{"$in": []int{Processing, StatusSubmit}}
}
}
filter["uid"] = uid
filter["isHide"] = bson.M{"$in": []any{nil, false}}
return filter
}
func (receiver *ListRequest) Options() *options.FindOptions {
return options.Find().SetSkip(int64(receiver.Skip())).SetLimit(int64(receiver.Limit())).SetSort(bson.M{"fakeLikeCount": -1})
}
type GenerateRequest struct {
OriginPic string `json:"originPic" bson:"originPic" binding:"required"` // 换脸原图
MId string `json:"mId" bson:"mId" binding:"required"` // 模版ID
IsFreeTimes bool `json:"isFreeTimes" bson:"isFreeTimes"` // 是否使用免费次数
Coin int64 `json:"coin" bson:"coin"` // 此次脱衣金币个数
ShareTitle string `json:"shareTitle" bson:"shareTitle"` // 分享标题
ShareStatus int `json:"shareStatus" bson:"shareStatus"` // 是否分享 0-不分享 1-分享
}
func (receiver *GenerateRequest) Generate(orderId primitive.ObjectID, createdAt time.Time, uid uint64, modTitle, modPic string, privilegeCount, debitFreeCount, debitCoins, debitIncomeCoins int64) AiChangeFaceImg {
isFreeTimes := false
if debitFreeCount > 0 {
isFreeTimes = true
}
if privilegeCount > 0 {
isFreeTimes = true
}
return AiChangeFaceImg{
ID: orderId,
Coin: debitIncomeCoins + debitCoins,
DebitAmountCoin: debitCoins,
DebitIncomeCoin: debitIncomeCoins,
IsFreeTimes: isFreeTimes,
Count: debitFreeCount + privilegeCount,
OriginPic: receiver.OriginPic,
MId: receiver.MId,
ModTitle: modTitle,
ModPic: modPic,
UID: uid,
Status: Processing,
IsHide: false,
ShareTitle: receiver.ShareTitle,
ShareStatus: receiver.ShareStatus,
UpdatedAt: createdAt,
CreatedAt: createdAt,
}
}
type DelRequest struct {
ID primitive.ObjectID `json:"id" bson:"id"` // AI订单ID
}
func (receiver *DelRequest) Filter() primitive.M {
filter := bson.M{}
filter["_id"] = receiver.ID
return filter
}
func (receiver *DelRequest) Update() primitive.M {
update := bson.M{}
update["isHide"] = true
update["updatedAt"] = time.Now()
return bson.M{"$set": update}
}
+62
View File
@@ -0,0 +1,62 @@
package aichangefaceimgmod
import (
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson/primitive"
"time"
)
const (
Processing = 1 // 1、进行中
SUCCESS = 2 // 2、成功
FAILURE = 3 // 3、失败
REFUND = 4 // 4、退款
StatusSubmit = 5 //5,提交
)
type Status int
var status = map[Status]string{
Processing: "processing",
FAILURE: "failure",
SUCCESS: "success",
REFUND: "refund",
}
func (s Status) Desc() string {
if desc, ok := status[s]; ok {
return desc
}
return ""
}
var mdb *db.MongoDB
// AiChangeFaceImg AI图片换脸
type AiChangeFaceImg struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 脱衣记录id
UID uint64 `json:"uid" bson:"uid"` // 用户id
OriginPic string `json:"originPic" bson:"originPic"` // AI换脸原图
MId string `json:"mId" bson:"mId"` // AI换脸模版图ID
ModTitle string `json:"modTitle" bson:"modTitle"` // AI换脸模标题
ModPic string `json:"modPic" bson:"modPic"` // AI换脸模版图
NewPic []string `json:"newPic" bson:"newPic"` // AI换脸后新图
Coin int64 `json:"coin" bson:"coin"` // 此次AI换脸金币个数
DebitAmountCoin int64 `json:"debitAmountCoin" bson:"debitAmountCoin"` // 此次AI换脸扣除金币个数
DebitIncomeCoin int64 `json:"debitIncomeCoin" bson:"debitIncomeCoin"` // 此次AI换脸扣除收益金币个数
Status int `json:"status" bson:"status"` // 1、进行中 2、生成成功 3、生成失败
Remark string `json:"remark" bson:"remark"` // 备注
Count int64 `json:"count" bson:"count"` // 此次AI换脸AI换脸消耗次数
IsFreeTimes bool `json:"isFreeTimes" bson:"isFreeTimes"` // 是否使用免费次数
IsHide bool `json:"isHide" bson:"isHide"` // 是否被用户隐藏(用户订单列表是否不显示)
UpdateAct string `json:"updateAct" bson:"updateAct"` // 修改账号
ShareTitle string `json:"shareTitle" bson:"shareTitle"` // 分享标题
ShareStatus int `json:"shareStatus" bson:"shareStatus"` // 是否分享 0-不分享 1-分享
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 刷新时间
}
func Init() {
mdb = db.Init(table)
initIndex()
}
+79
View File
@@ -0,0 +1,79 @@
package aichangefaceimgmod
import (
"91porn-server/models/commod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
// RechargeUpdateReq 修改参数
type RechargeUpdateReq struct {
StatusDesc *string `json:"statusDesc" bson:"statusDesc"` // 状态描述
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
}
type RchgQueryReq struct {
ID *string `form:"id" json:"_id,omitempty" bson:"_id"` // 流水id
UID *uint64 `form:"uid" json:"uid,omitempty" bson:"uid"` // 用户id
Status *int `form:"status" json:"status,omitempty" bson:"status"` // 1、进行中 2、生成成功 3、生成失败 4、已经退款
}
type WebListRequest struct {
Status *int `form:"status" json:"status" bson:"status"` // 1、进行中 2、生成成功 3、生成失败 4、已经退款
UID *uint64 `form:"uid" json:"uid,omitempty" bson:"uid"` // 用户id
ID *string `form:"id" json:"_id,omitempty" bson:"_id"` // 流水id
MId *string `form:"mId" json:"mId,omitempty" bson:"_id"` // AI模版id
commod.Page
}
func (receiver *WebListRequest) Filter() primitive.M {
filter := bson.M{}
if receiver.Status != nil {
filter["status"] = receiver.Status
}
if receiver.UID != nil {
filter["uid"] = receiver.UID
}
if receiver.MId != nil {
filter["mId"] = receiver.MId
}
if receiver.ID != nil {
id, _ := primitive.ObjectIDFromHex(*receiver.ID)
filter["_id"] = id
}
return filter
}
func (receiver *WebListRequest) Options() *options.FindOptions {
return options.Find().SetSkip(int64(receiver.Skip())).SetLimit(int64(receiver.Limit() + 1)).SetSort(bson.M{"updatedAt": -1})
}
type EditCond struct {
ID string `json:"id" binding:"required"` // 文档
NewPic *[]string `json:"newPic" bson:"newPic"` // AI图片换脸后新图
Status *int `json:"status" bson:"status"` // 状态 1、进行中 2、生成成功 3、生成失败
Remark *string `json:"remark" bson:"remark"` // 拒绝理由
}
func (receiver *EditCond) Filter() bson.M {
objID, _ := primitive.ObjectIDFromHex(receiver.ID)
return bson.M{"_id": objID}
}
func (receiver *EditCond) Update(updateAct string) bson.M {
var update = bson.M{}
if receiver.NewPic != nil {
update["newPic"] = receiver.NewPic
}
if receiver.Status != nil {
update["status"] = receiver.Status
}
if receiver.Remark != nil {
update["remark"] = receiver.Remark
}
update["updateAct"] = updateAct
update["updatedAt"] = time.Now()
return bson.M{"$set": update}
}
+94
View File
@@ -0,0 +1,94 @@
package aichangefacemod
import (
"91porn-server/common/aiService"
"91porn-server/common/db"
"91porn-server/models"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const table = models.AiChangeFace
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
func Init() {
mdb = db.Init(table)
initIndex()
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "uid", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func AddAiChangeFace(t *db.MongoTool, orderId primitive.ObjectID, orderCreatedAt time.Time, uid uint64, pic []string, vidMod aiService.Template, coin, incomeCoin int64, discount []primitive.ObjectID, shareTitle string, shareStatus int) error {
_, err := coll(t).InsertOne(AiChangeFace{
ID: orderId,
Uid: uid,
Pic: pic,
VidID: vidMod.ID,
ModTitle: vidMod.Title,
ModCover: vidMod.Cover,
ModVideo: vidMod.M3u8Url,
Coin: coin,
IncomeCoin: incomeCoin,
Discount: discount,
Status: StatusGenning,
IsHide: false,
Cover: "",
Url: "",
ShareTitle: shareTitle,
ShareStatus: shareStatus,
CreatedAt: orderCreatedAt,
UpdatedAt: orderCreatedAt,
})
return err
}
func ListByUid(uid uint64, status *AiChangeFaceStatus, skip, limit int) ([]AiChangeFace, error) {
var acfs []AiChangeFace
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
if skip > 0 {
opts.SetSkip(int64(skip))
}
if limit > 0 {
opts.SetLimit(int64(limit))
}
cond := bson.M{"uid": uid, "isHide": bson.M{"$in": []any{nil, false}}}
if status != nil {
cond["status"] = *status
if *status == StatusGenning {
cond["status"] = bson.M{"$in": []int{0, 2}}
}
}
return acfs, coll(nil).Find(&acfs, cond, opts)
}
func Hide(uid uint64, id primitive.ObjectID) error {
_, err := coll(nil).UpdateOne(bson.M{"uid": uid, "_id": id}, bson.M{"$set": bson.M{"isHide": true}})
return err
}
func FindByID(t *db.MongoTool, id primitive.ObjectID) (*AiChangeFace, error) {
var acf AiChangeFace
return &acf, coll(t).FindOne(&acf, bson.M{"_id": id})
}
+11
View File
@@ -0,0 +1,11 @@
package aichangefacemod
import "go.mongodb.org/mongo-driver/bson/primitive"
type GenerateRequest struct {
Pic []string `json:"picture"` // 换脸照片
VidModID primitive.ObjectID `json:"vidModId"` // 视频模版id
Discount []primitive.ObjectID `json:"discount"` // 使用折扣券
ShareTitle string `json:"shareTitle" bson:"shareTitle"` // 分享标题
ShareStatus int `json:"shareStatus" bson:"shareStatus"` // 是否分享 0-不分享 1-分享
}
+39
View File
@@ -0,0 +1,39 @@
package aichangefacemod
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type AiChangeFaceStatus int
const (
StatusGenning AiChangeFaceStatus = 0 // 未完成
StatusComplete AiChangeFaceStatus = 1 // 已完成
StatusRefund AiChangeFaceStatus = -1 // 已退款
StatusSubmit AiChangeFaceStatus = 2 // 已提交
)
type AiChangeFace struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Uid uint64 `json:"uid" bson:"uid"` // 用户
Pic []string `json:"picture" bson:"picture"` // 换脸照片
VidID primitive.ObjectID `json:"vidId" bson:"vidId"` // 视频模版id
ModTitle string `json:"modTitle" bson:"modTitle"` //模版标题
ModCover string `json:"modCover" bson:"modCover"` //模版封面
ModVideo string `json:"modVideo" bson:"modVideo"` //模版视频
Coin int64 `json:"coin" bson:"coin"` // 普通金币数
IncomeCoin int64 `json:"incomeCoin" bson:"imcomeCoin"` // 可提现金币数
Status AiChangeFaceStatus `json:"status" bson:"status"` // 0 未完成; 1 已完成; -1 已退款
Discount []primitive.ObjectID `json:"discount" bson:"discount"` // 抵扣券id
IsHide bool `json:"-" bson:"isHide"` // 是否被用户隐藏(用户订单列表是否不显示)
Cover string `json:"cover" bson:"cover"` // 换脸后封面大图
Url string `json:"url" bson:"url"` // 换脸后视频地址
Remark string `json:"remark" bson:"remark"` // 拒绝理由
ShareTitle string `json:"shareTitle" bson:"shareTitle"` // 分享标题
ShareStatus int `json:"shareStatus" bson:"shareStatus"` // 是否分享 0-不分享 1-分享
Operator string `json:"operator" bson:"operator"` // 操作员
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 刷新时间
}
+115
View File
@@ -0,0 +1,115 @@
package aichangefacemod
import (
"91porn-server/common/db"
"91porn-server/models/commod"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
type AiChangeFaceWebResp struct {
ID primitive.ObjectID `json:"id"`
Uid uint64 `json:"uid"` // 用户
Pic []string `json:"picture"` // 换脸照片
ModId primitive.ObjectID `json:"modId"` // 视频模版id
ModUrl string `json:"modUrl"` // 视频模版播放地址url
ModTitle string `json:"modTitle"` // 模版标题
Coin int64 `json:"coin"` // 普通金币数
IncomeCoin int64 `json:"incomeCoin"` // 可提现金币数
Status AiChangeFaceStatus `json:"status"` // 0 未完成; 1 已完成; -1 已退款
Cover string `json:"cover"` // 换脸后封面大图
Url string `json:"url"` // 换脸后视频地址
Remark string `json:"remark"` // 拒绝理由
Operator string `json:"operator"` // 操作员
CreatedAt time.Time `json:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt"` // 刷新时间
}
type ListRequest struct {
ID *string `form:"id" json:"id"`
Uid *uint64 `form:"uid" json:"uid"`
Status *AiChangeFaceStatus `form:"status" json:"status"`
VidID *string `form:"vidId" json:"vidId"`
commod.Page
}
type EditAiChangeFace struct {
ID primitive.ObjectID `json:"id" binding:"required"` // 被编辑的ai换脸id
Status *AiChangeFaceStatus `json:"status"` // 0 未完成; 1 已完成; -1 已退款 2 已经提交
Cover *string `json:"cover"` // 换脸后封面大图
Url *string `json:"url"` // 换脸后视频地址
Remark *string `json:"remark"` // 拒绝理由
Title *string `json:"title"` // 标题
}
func (receiver *EditAiChangeFace) Update(updateAct string) bson.M {
var update = bson.M{}
if receiver.Url != nil {
update["url"] = receiver.Url
}
if receiver.Cover != nil {
update["cover"] = receiver.Cover
}
if receiver.Status != nil {
update["status"] = receiver.Status
}
if receiver.Remark != nil {
update["remark"] = receiver.Remark
}
update["operator"] = updateAct
update["updatedAt"] = time.Now()
return bson.M{"$set": update}
}
func WebList(id *primitive.ObjectID, uid *uint64, status *AiChangeFaceStatus, vidId *string, skip, limit int) ([]AiChangeFace, int64, error) {
cond := bson.M{}
if id != nil {
cond["_id"] = *id
}
if uid != nil {
cond["uid"] = *uid
}
if status != nil {
cond["status"] = *status
}
if vidId != nil {
vidObjId, _ := primitive.ObjectIDFromHex(*vidId)
cond["vidId"] = vidObjId
}
count, err := coll(nil).Count(cond)
if err != nil {
return nil, 0, err
}
var acfs []AiChangeFace
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
if skip > 0 {
opts.SetSkip(int64(skip))
}
if limit > 0 {
opts.SetLimit(int64(limit))
}
return acfs, count, coll(nil).Find(&acfs, cond, opts)
}
func Update(t *db.MongoTool, id primitive.ObjectID, set bson.M) error {
_, err := coll(t).UpdateOne(bson.M{"_id": id}, set)
return err
}
// TransitionStatus atomically changes an order from the expected status. The
// returned boolean is false when another worker or callback handled it first.
func TransitionStatus(t *db.MongoTool, id primitive.ObjectID, from, to AiChangeFaceStatus, set bson.M) (bool, error) {
if set == nil {
set = bson.M{}
}
set["status"] = to
set["updatedAt"] = time.Now()
result, err := coll(t).UpdateOne(bson.M{"_id": id, "status": from}, bson.M{"$set": set})
if err != nil {
return false, err
}
return result.ModifiedCount == 1, nil
}
@@ -0,0 +1,119 @@
package aichangefacevidmod
import (
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"fmt"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const table = models.AiChangeFaceVideo
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// InitARDIndex 设置账户充值流水表索引
func initIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "sort", Value: -1}},
},
{
Keys: bson.D{{Key: "createdAt", Value: -1}},
},
{
Keys: bson.D{{Key: "status", Value: -1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("AiUnDressIndex err+%v", err))
}
}
func GetMods(cond bson.M, skip, limit int) ([]AiChangeFaceVidMod, error) {
var acfms []AiChangeFaceVidMod
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
if skip > 0 {
opts.SetSkip(int64(skip))
}
if limit > 0 {
opts.SetLimit(int64(limit))
}
return acfms, coll(nil).Find(&acfms, cond, opts)
}
func GetValidMods(skip, limit int) ([]AiChangeFaceVidMod, error) {
var acfms []AiChangeFaceVidMod
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
if skip > 0 {
opts.SetSkip(int64(skip))
}
if limit > 0 {
opts.SetLimit(int64(limit))
}
return acfms, coll(nil).Find(&acfms, bson.M{"status": 1}, opts)
}
func GetAllMods() ([]AiChangeFaceVidMod, error) {
var mod []AiChangeFaceVidMod
opts := options.Find().SetSort(bson.D{{Key: "sort", Value: -1}, {Key: "createdAt", Value: -1}})
return mod, coll(nil).Find(&mod, bson.M{"status": 1}, opts)
}
func GetModById(id primitive.ObjectID) (*AiChangeFaceVidMod, error) {
var acfvm AiChangeFaceVidMod
return &acfvm, coll(nil).FindOne(&acfvm, bson.M{"_id": id})
}
func GetModByIDs(ids []primitive.ObjectID) ([]AiChangeFaceVidMod, error) {
if len(ids) == 0 {
return nil, nil
}
var acfms []AiChangeFaceVidMod
return acfms, coll(nil).Find(&acfms, bson.M{"_id": bson.M{"$in": ids}})
}
// QueryAllDocument 分页查询文档
func QueryAllDocument(filter primitive.M, opts ...*options.FindOptions) (out []*AiChangeFaceVidMod, err error) {
if err = coll(nil).Find(&out, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllDocument", table, "Find", err),
log.Any("filter", filter),
)
return
}
return
}
// CountDocument 查询文档条目数
func CountDocument(filter primitive.M) (int64, error) {
if count, err := coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CountDocument", table, "Count", err),
log.Any("filter", filter),
)
return 0, err
} else {
return count, nil
}
}
func GetAllModsByCond(filter primitive.M) ([]AiChangeFaceVidMod, error) {
var mod []AiChangeFaceVidMod
opts := options.Find().SetSort(bson.D{{Key: "sort", Value: -1}, {Key: "createdAt", Value: -1}})
return mod, coll(nil).Find(&mod, filter, opts)
}
func UpdateManyByCond(filter primitive.M, set bson.M) error {
_, err := coll(nil).UpdateMany(filter, set)
return err
}
+60
View File
@@ -0,0 +1,60 @@
package aichangefacevidmod
import (
"go.mongodb.org/mongo-driver/bson/primitive"
)
type AiChangeMod struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // AI模版ID
Title string `json:"title" bson:"title"` // 模版标题
SourceURL string `json:"sourceURL" bson:"sourceURL"` // 视频资源地址
Status int `json:"status" bson:"status"` // 状态,0 未激活 1 激活
PlayTime uint `json:"playTime" bson:"playTime"` // 影片长度
Cover string `json:"cover" bson:"cover"` // 封面大图
Type string `json:"type" bson:"type"` // 类型
ModuleType int `json:"moduleType" bson:"moduleType"` // 模块属性
HotValue int `json:"hotValue" bson:"hotValue"` // 热门值
HotMark string `json:"hotMark" bson:"hotMark"` // 热门标签
Coin uint `json:"coin" bson:"coin"` // 价格(金币)
VipCoin uint `json:"vipCoin" bson:"vipCoin"` // vip价格(金币)
}
type AiUndressMod struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // AI模版ID
Cover string `json:"cover" bson:"cover"` // AI模版图
}
type AiChangeFaceMod struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // AI模版ID
Title string `json:"title" bson:"title"` // 模版标题
Cover string `json:"cover" bson:"cover"` // AI模版图
HotValue int `json:"hotValue" bson:"hotValue"` // 热门值
HotMark string `json:"hotMark" bson:"hotMark"` // 热门标签
Coin uint `json:"coin" bson:"coin"` // 价格(金币)
VipCoin uint `json:"vipCoin" bson:"vipCoin"` // vip价格(金币)
}
type AiImgToVideoMod struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // AI模版ID
Cover string `json:"cover" bson:"cover"` // AI模版图
NewUrl string `json:"newUrl" bson:"newUrl"` // AI图生视频链接
Title string `json:"title" bson:"title"` // 模版标题
SceneType int `json:"sceneType" bson:"sceneType"` // 场景类型
}
type AiTextToImgMod struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // AI模版ID
Title string `json:"title" bson:"title"` // 模版标题
Cover string `json:"cover" bson:"cover"` // AI模版图
StyleType int `json:"styleType" bson:"styleType"` // AI绘图风格类型
ModuleType int `json:"moduleType" bson:"moduleType"` // AI模块属性类型
}
type AppResponse struct {
AiUndressMod []AiUndressMod `json:"aiUndressMod" bson:"aiUndressMod"` // AI脱衣模版
AiChangeFaceVideoMod []AiChangeMod `json:"aiChangeFaceVideoMod" bson:"aiChangeFaceVideoMod"` // AI视频换脸模型
AiChangeFaceMod []AiChangeFaceMod `json:"aiChangeFaceMod" bson:"aiChangeFaceMod"` // Ai换脸模型
AiImgToVideoMod []AiImgToVideoMod `json:"aiImgToVideoMod" bson:"aiImgToVideoMod"` // AI图生视频模型
AiTextToImgMod []AiTextToImgMod `json:"aiTextToImgMod" bson:"aiTextToImgMod"` // AI绘图模型
}
+44
View File
@@ -0,0 +1,44 @@
package aichangefacevidmod
import (
"91porn-server/common/db"
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const (
_ = iota
AIUndress // 1、AI脱衣模型配置
AIVideoChangeFace // 2、AI视频换脸配置
AIImgChangeFace // 3、AI图片换脸配置
AIImgToVideo // 4、AI图生视频配置
AITextToImage // 5、AI绘图配置
)
type AiChangeFaceVidMod struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Title string `json:"title" bson:"title"` // 视频标题
SourceURL string `json:"sourceURL" bson:"sourceURL"` // 视频资源地址
Status int `json:"status" bson:"status"` // 状态,0 未激活 1 激活
PlayTime uint `json:"playTime" bson:"playTime"` // 影片长度
Cover string `json:"cover" bson:"cover"` // 封面大图
NewUrl string `json:"newUrl" bson:"newUrl"` // 生成后链接
StyleType int `json:"styleType" bson:"styleType"` // 风格类型
Type string `json:"type" bson:"type"` // 类型
ModuleType int `json:"moduleType" bson:"moduleType"` // 模块属性
HotValue int `json:"hotValue" bson:"hotValue"` // 热门值
HotMark string `json:"hotMark" bson:"hotMark"` // 热门标签
Coin uint `json:"coin" bson:"coin"` // 价格(金币)
VipCoin uint `json:"vipCoin" bson:"vipCoin"` // vip价格(金币)
SceneType int `json:"sceneType" bson:"sceneType"` // 场景类型
Sort int `json:"sort" bson:"sort"` // 排序
CreatedAt time.Time `json:"createdAt" bson:"createdAt,omitempty"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt,omitempty"` // 刷新时间
}
func Init() {
mdb = db.Init(table)
initIndex()
}
+91
View File
@@ -0,0 +1,91 @@
package aichangefacevidmod
import (
"91porn-server/models/commod"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type ListRequest struct {
Status *int `form:"status" json:"status"`
ModuleType *int `form:"moduleType" json:"moduleType"` // 模块属性
commod.Page
}
type AddAiChangeFaceVidReq struct {
Title string `json:"title"` // 视频标题
SourceURL string `json:"sourceURL"` // 视频资源地址
Status int `json:"status"` // 状态,0 未激活 1 激活
PlayTime uint `json:"playTime"` // 影片长度
Cover string `json:"cover"` // 封面大图
NewUrl string `json:"newUrl" bson:"newUrl"` // 生成后链接
ModuleType int `json:"moduleType" bson:"moduleType"` // 模块属性
HotValue int `json:"hotValue" bson:"hotValue"` // 热门值
HotMark string `json:"hotMark" bson:"hotMark"` // 热门标签
Type string `json:"type"` // 类型
StyleType int `json:"styleType" bson:"styleType"` // 风格类型
Coin uint `json:"coin"` // 模版价格
Sort int `json:"sort" bson:"sort"` // 排序
VipCoin uint `json:"vipCoin"` // 模版会员价格
SceneType int `json:"sceneType" form:"sceneType"` // 场景类型
}
type EditAiChangeFaceVid struct {
ID primitive.ObjectID `json:"id" binding:"required"`
Title *string `json:"title"` // 视频标题
SourceURL *string `json:"sourceURL"` // 视频资源地址
Status *int `json:"status"` // 状态,0 未激活 1 激活
PlayTime *uint `json:"playTime"` // 影片长度
Cover *string `json:"cover"` // 封面大图
ModuleType *int `json:"moduleType" bson:"moduleType"` // 模块属性
StyleType *int `json:"styleType" bson:"styleType"` // 风格类型
NewUrl *string `json:"newUrl" bson:"newUrl"` // 生成后链接
HotValue *int `json:"hotValue" bson:"hotValue"` // 热门值
HotMark *string `json:"hotMark" bson:"hotMark"` // 热门标签
Type *string `json:"type"` // 类型
Coin *uint `json:"coin"` // 模版价格
Sort *int `json:"sort" bson:"sort"` // 排序
VipCoin *uint `json:"vipCoin"` // 模版会员价格
SceneType *int `json:"sceneType" form:"sceneType"` // 场景类型
}
func AddAiChangeFaceVid(afvm AiChangeFaceVidMod) error {
_, err := coll(nil).InsertOne(afvm)
return err
}
func UpdateAiChangeFaceVid(id primitive.ObjectID, set bson.M) error {
_, err := coll(nil).UpdateOne(bson.M{"_id": id}, set)
return err
}
type WebListRequest struct {
Status *int `form:"status" json:"status" bson:"status"` // 状态
ModuleType *int `form:"moduleType" json:"moduleType" bson:"moduleType"` // 模块属性
PageNumber int64 `form:"pageNumber" json:"pageNumber"` // 第几页
PageSize int64 `form:"pageSize" json:"pageSize"` // 每页数量
}
func (receiver *WebListRequest) Filter() primitive.M {
filter := bson.M{}
if receiver.Status != nil {
filter["status"] = receiver.Status
}
if receiver.ModuleType != nil {
filter["moduleType"] = receiver.ModuleType
}
return filter
}
func (receiver *WebListRequest) Options() *options.FindOptions {
return options.Find().SetSkip((receiver.PageNumber - 1) * receiver.PageSize).SetLimit(receiver.PageSize + 1).SetSort(bson.D{{Key: "sort", Value: -1}, {Key: "createdAt", Value: -1}})
}
// 换脸订单回调请求
type CallbackReq struct {
ImgUrl string `json:"imgUrl"` //脱衣后地址
AppOrderNum string `json:"appOrderNum"` //app订单号
Msg string `json:"msg"` //消息
}
+146
View File
@@ -0,0 +1,146 @@
package aiimagetovideomod
import (
"91porn-server/common/db"
"91porn-server/common/log"
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// GetList 获取列表
func GetList(cond bson.M, skip, limit int64, sort bson.D) (res []AiImageToVideo, count int64, hasNext bool, err error) {
count, err = coll(nil).Count(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetList", table, "Count", err),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("cond", cond),
log.Any("sort", sort),
)
return
}
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort).SetSkip(skip).SetLimit(limit + 1)
if err = coll(nil).Find(&res, cond, opts); err != nil {
return
}
// 判断下一页
if len(res) > int(limit) {
hasNext = true
res = res[:limit]
}
return
}
// GetAll 查询全部文档
func GetAll(filter primitive.M, sort bson.D) (out []*AiImageToVideo, err error) {
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort)
if err = coll(nil).Find(&out, filter, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAll", table, "Find", err),
log.Any("filter", filter),
log.Any("opts", opts),
)
return nil, err
}
return
}
// QueryAllCount 查询文档条目数
func QueryAllCount(filter primitive.M) (int64, error) {
if count, err := coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllCount", table, "Count", err),
log.Any("filter", filter),
)
return 0, err
} else {
return count, nil
}
}
// GetInfo 通过id获取详细信息
func GetInfo(id primitive.ObjectID) (AiImageToVideo, error) {
v := AiImageToVideo{}
if err := coll(nil).FindOne(&v, bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetInfo", table, "FindOne", err),
log.Any("id", id),
)
return v, err
}
if v.ID.IsZero() {
return v, errors.New("record not found")
}
return v, nil
}
// Insert 插入记录
func Insert(t *db.MongoTool, d AiImageToVideo) (data primitive.ObjectID, err error) {
result, err := coll(t).InsertOne(&d)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return
}
byteID, err := json.Marshal(result.InsertedID)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "Marshal", err))
return
}
if err = data.UnmarshalJSON(byteID); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "UnmarshalJSON", err))
return
}
return
}
// UpdateByID 根据id更新数据
func UpdateByID(t *db.MongoTool, id primitive.ObjectID, data map[string]interface{}) (int64, error) {
cond := bson.M{"_id": id}
return update(t, cond, data)
}
// update 更新数据
func update(t *db.MongoTool, cond primitive.M, data map[string]interface{}) (int64, error) {
result, err := coll(t).UpdateMany(cond, bson.M{"$set": bson.M(data)})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateMany", err),
log.Any("cond", cond),
log.Any("update", data),
)
return 0, err
}
return result.ModifiedCount, nil
}
// DeleteByID 删除数据
func DeleteByID(t *db.MongoTool, id primitive.ObjectID) error {
_, err := coll(t).DeleteMany(bson.M{"_id": id})
if err != nil {
if err == mongo.ErrNoDocuments {
return nil
} else {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteByID", table, "DeleteMany", err), log.Any("id", id))
}
}
return err
}
func Hide(uid uint64, id primitive.ObjectID) error {
_, err := coll(nil).UpdateOne(bson.M{"uid": uid, "_id": id}, bson.M{"$set": bson.M{"isHide": true}})
return err
}
+23
View File
@@ -0,0 +1,23 @@
package aiimagetovideomod
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// AiImageToVideoInfo 移动端返回内容
type AiImageToVideoInfo struct {
ID primitive.ObjectID `json:"id"` // 文档id
UID uint64 `json:"uid"` // 用户ID
ImgUrl string `json:"imgUrl"` // 未处理的图片地址
NewImgUrl string `json:"newImgUrl"` // 处理后的图片地址
Status int `json:"status"` // 状态
Coin int64 `json:"coin"` // 图生视频金币个数
IsFreeTimes bool `json:"isFreeTimes"` // 是否使用免费次数
IsHide bool `json:"isHide"` // 是否被用户隐藏
Remark string `json:"remark"` // 备注
IsDelete bool `json:"isDelete"` // 是否删除
CreatedAt time.Time `json:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt"` // 更新时间
}
+111
View File
@@ -0,0 +1,111 @@
package aiimagetovideomod
import (
"91porn-server/common/db"
"91porn-server/models"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
var mdb *db.MongoDB
const table = models.AiImageToVideo
type AiImageToVideoStatus int
const (
StatusOrderSuccess AiImageToVideoStatus = iota + 1 // 1: 下单成功
StatusSubmitted // 2: 已提交
StatusGenerationSuccess // 3: 生成成功
StatusGenerationFailed // 4: 生成失败
StatusRefunded // 5: 退款
)
type SceneType int
const (
SceneTagLiftShirt SceneType = iota // 0:掀衣露乳
SceneTagTearClothes // 1:男人撕衣
SceneTagCumOnFace // 2:神屌射脸
SceneOFace // 3:阿黑颜
SceneTagKiss // 4:接吻
SceneTagSuckBreasts // 5:吸奶
SceneRevealed // 6:露逼
SceneLargerChest // 7:胸部变大
)
// String 返回 SceneTag 对应的中文描述,方便打印与调试
func (t SceneType) String() string {
switch t {
case SceneTagTearClothes:
return "男人撕衣"
case SceneTagLiftShirt:
return "掀衣露乳"
case SceneTagCumOnFace:
return "神屌射脸"
case SceneOFace:
return "阿黑颜"
case SceneTagKiss:
return "接吻"
case SceneTagSuckBreasts:
return "吸奶"
case SceneRevealed:
return "露逼"
case SceneLargerChest:
return "胸部变大"
default:
return "未知场景"
}
}
type AiImageToVideo struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档id
UID uint64 `json:"uid" bson:"uid"` // 用户ID
ImgUrl string `json:"imgUrl" bson:"imgUrl"` // 未处理的图片地址
NewImgUrl string `json:"newImgUrl" bson:"newImgUrl"` // 处理后的图片地址
SceneType int `json:"sceneType" bson:"sceneType"` // 模版场景类型
Status int `json:"status" bson:"status"` // 状态 1、下单成功 2、已提交 3、生成成功 4、生成失败 5、退款
Coin int64 `json:"coin" bson:"coin"` // 图生视频金币个数
DebitAmountCoin int64 `json:"debitAmountCoin" bson:"debitAmountCoin"` // 此次脱衣扣除金币个数
DebitIncomeCoin int64 `json:"debitIncomeCoin" bson:"debitIncomeCoin"` // 此次脱衣扣除收益金币个数
IsFreeTimes bool `json:"isFreeTimes" bson:"isFreeTimes"` // 是否使用免费次数
IsHide bool `json:"isHide" bson:"isHide"` // 是否被用户隐藏
Remark string `json:"remark" bson:"remark"` // 备注
ShareTitle string `json:"shareTitle" bson:"shareTitle"` // 分享标题
ShareStatus int `json:"shareStatus" bson:"shareStatus"` // 是否分享 0-不分享 1-分享
IsDelete bool `json:"isDelete" bson:"isDelete"` // 是否删除
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
}
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// Init 初始化索引
func Init() {
mdb = db.Init(table)
initIndex()
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "status", 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))
}
}
+221
View File
@@ -0,0 +1,221 @@
package aiplazamod
import (
"encoding/json"
"errors"
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// GetList 获取列表
func GetList(cond bson.M, skip, limit int64, sort bson.D) (res []AiPlaza, count int64, hasNext bool, err error) {
count, err = coll(nil).Count(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetList", table, "Count", err),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("cond", cond),
log.Any("sort", sort),
)
return
}
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort).SetSkip(skip).SetLimit(limit + 1)
if err = coll(nil).Find(&res, cond, opts); err != nil {
return
}
// 判断下一页
if len(res) > int(limit) {
hasNext = true
res = res[:limit]
}
return
}
// GetAll 查询全部文档
func GetAll(filter primitive.M, sort bson.D) (out []AiPlaza, err error) {
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort)
if err = coll(nil).Find(&out, filter, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAll", table, "Find", err),
log.Any("filter", filter),
log.Any("opts", opts),
)
return nil, err
}
return
}
// QueryAllCount 查询文档条目数
func QueryAllCount(filter primitive.M) (int64, error) {
if count, err := coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllCount", table, "Count", err),
log.Any("filter", filter),
)
return 0, err
} else {
return count, nil
}
}
// GetInfo 通过id获取详细信息
func GetInfo(id primitive.ObjectID) (AiPlaza, error) {
v := AiPlaza{}
if err := coll(nil).FindOne(&v, bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetInfo", table, "FindOne", err),
log.Any("id", id),
)
return v, err
}
if v.ID.IsZero() {
return v, errors.New("record not found")
}
return v, nil
}
// Insert 插入记录
func Insert(t *db.MongoTool, d AiPlaza) (data primitive.ObjectID, err error) {
if d.Status == 1 {
d.ReviewAt = time.Now()
}
d.CreatedAt = time.Now()
d.UpdatedAt = time.Now()
result, err := coll(t).InsertOne(&d)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return
}
byteID, err := json.Marshal(result.InsertedID)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "Marshal", err))
return
}
if err = data.UnmarshalJSON(byteID); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "UnmarshalJSON", err))
return
}
return
}
// IncCommentCount 评论统计次数加加
func IncCommentCount(id primitive.ObjectID) error {
query := bson.M{"_id": id}
update := bson.M{"$inc": bson.M{"commentCount": 1}}
if _, err := coll(nil).UpdateOne(query, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IncCommentCount", table, "UpdateOne", err),
log.Any("id", id),
)
return err
}
return nil
}
// IncCollectCount 收藏统计次数加加
func IncCollectCount(id primitive.ObjectID) error {
query := bson.M{"_id": id}
update := bson.M{"$set": bson.M{"updatedAt": time.Now()}, "$inc": bson.M{"collectCount": 1}}
if _, err := coll(nil).UpdateOne(query, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "收藏统计次数加加", table, "UpdateOne", err),
log.Any("id", id),
)
return err
}
return nil
}
// IncLikeCount 点赞统计次数加加
func IncLikeCount(id primitive.ObjectID) error {
query := bson.M{"_id": id}
update := bson.M{"$set": bson.M{"updatedAt": time.Now()}, "$inc": bson.M{"likeCount": 1}}
if _, err := coll(nil).UpdateOne(query, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IncLikeCount", table, "UpdateOne", err),
log.Any("id", id),
)
return err
}
return nil
}
// DecLikeCount 点赞统计次数减减
func DecLikeCount(ids []primitive.ObjectID) error {
var query = bson.M{}
if len(ids) == 1 {
query["_id"] = ids[0]
} else {
query["_id"] = bson.M{"$in": ids}
}
update := bson.M{"$set": bson.M{"updatedAt": time.Now()}, "$inc": bson.M{"likeCount": -1}}
if _, err := coll(nil).UpdateMany(query, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DecLikeCount", table, "UpdateOne", err),
log.Any("ids", ids),
)
return err
}
return nil
}
// UpdateByID 根据id更新数据
func UpdateByID(t *db.MongoTool, id primitive.ObjectID, data map[string]interface{}) (int64, error) {
cond := bson.M{"_id": id}
return update(t, cond, data)
}
// UpdateByIds 根据ids更新数据
func UpdateByIds(t *db.MongoTool, ids []primitive.ObjectID, data map[string]interface{}) (int64, error) {
if len(ids) == 0 {
return 0, nil
}
cond := bson.M{"_id": bson.M{"$in": ids}}
return update(t, cond, data)
}
// update 更新数据
func update(t *db.MongoTool, cond primitive.M, data map[string]interface{}) (int64, error) {
result, err := coll(t).UpdateMany(cond, bson.M{"$set": bson.M(data)})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateMany", err),
log.Any("cond", cond),
log.Any("update", data),
)
return 0, err
}
return result.ModifiedCount, nil
}
// DeleteByID 删除数据
func DeleteByID(t *db.MongoTool, ids ...primitive.ObjectID) error {
if len(ids) == 0 {
return nil
}
filter := bson.M{"_id": ids[0]}
if len(ids) > 1 {
filter["_id"] = bson.M{"$in": ids}
}
_, err := coll(t).DeleteMany(filter)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil
} else {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteByID", table, "DeleteMany", err), log.Any("id", ids))
}
}
return err
}
+38
View File
@@ -0,0 +1,38 @@
package aiplazamod
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// AiPlazaInfo 移动端返回内容
type AiPlazaInfo struct {
ID primitive.ObjectID `json:"id"` // 文档id
Type int `json:"type"` // 1-ai图片换脸 2-ai视频换脸 3-ai脱衣 4-ai图生视频 5-ai绘画
Template string `json:"template" bson:"template"` // 关联模版id
Uid uint64 `json:"uid"` //
Name string `json:"name"` //姓名
Gender string `json:"gender"` //性别
Portrait string `json:"portrait"` //头像
Title string `json:"title"` // 标题
OriginalImage string `json:"originalImage" bson:"originalImage"` // 原图
OriginalVideo string `json:"originalVideo" bson:"originalVideo"` // 原视频
OriginalVideoCover string `json:"originalVideoCover" bson:"originalVideoCover"` // 原视频封面
OriginContent string `json:"originContent" bson:"originContent"` // 输入的原文
GenerateImage string `json:"generateImage" bson:"generateImage"` // 生成的图
GenerateVideo string `json:"generateVideo" bson:"generateVideo"` // 生成的视频
GenerateVideoCover string `json:"generateVideoCover" bson:"generateVideoCover"` // 生成的视频封面
Status int `json:"status"` // 0-待审核 1-审核通过 2-拒绝 3-下架
Reason string `json:"reason"` // 原因
SortCode int `json:"sortCode"` // 置顶排序号,大于0就是置顶
HasCollected bool `json:"hasCollected"` // 是否收藏
HasLiked bool `json:"hasLiked"` // 是否点赞
ViewCount int64 `json:"viewCount" bson:"viewCount"` // 浏览数
LikeCount int64 `json:"likeCount" bson:"likeCount"` // 点赞数
CollectCount int64 `json:"collectCount" bson:"collectCount"` // 收藏数
CommentCount int64 `json:"commentCount" bson:"commentCount"` // 评论数
ReviewAt time.Time `json:"reviewAt"` // 审核时间
CreatedAt time.Time `json:"createdAt"` // 文档创建时间
UpdatedAt time.Time `json:"updatedAt"` // 文档更新时间
}
+80
View File
@@ -0,0 +1,80 @@
package aiplazamod
import (
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
var mdb *db.MongoDB
const table = models.AiPlaza
const (
DefaultStatus = 0 // 默认审核状态
)
type AiPlaza struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档id
Type int `json:"type" bson:"type"` // 1-ai图片换脸 2-ai视频换脸 3-ai脱衣 4-ai图生视频 5-ai绘画
OrderId primitive.ObjectID `json:"orderId" bson:"orderId"` // 关联订单id
Template string `json:"template" bson:"template"` // 关联模版id
Uid uint64 `json:"uid" bson:"uid"` //
Title string `json:"title" bson:"title"` // 标题
OriginalImage string `json:"originalImage" bson:"originalImage"` // 原图
OriginalVideo string `json:"originalVideo" bson:"originalVideo"` // 原视频
OriginalVideoCover string `json:"originalVideoCover" bson:"originalVideoCover"` // 原视频封面
OriginContent string `json:"originContent" bson:"originContent"` // 输入的原文
GenerateImage string `json:"generateImage" bson:"generateImage"` // 生成的图
GenerateVideo string `json:"generateVideo" bson:"generateVideo"` // 生成的视频
GenerateVideoCover string `json:"generateVideoCover" bson:"generateVideoCover"` // 生成的视频封面
Status int `json:"status" bson:"status"` // 0-待审核 1-审核通过 2-拒绝 3-下架
Reason string `json:"reason" bson:"reason"` // 原因
SortCode int `json:"sortCode" bson:"sortCode"` // 置顶排序号,大于0就是置顶
ReviewAt time.Time `json:"reviewAt" bson:"reviewAt"` // 审核时间
ViewCount int64 `json:"viewCount" bson:"viewCount"` // 浏览数
LikeCount int64 `json:"likeCount" bson:"likeCount"` // 点赞数
CollectCount int64 `json:"collectCount" bson:"collectCount"` // 收藏数
CommentCount int64 `json:"commentCount" bson:"commentCount"` // 评论数
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 文档创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 文档更新时间
}
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// Init 初始化索引 todo: 在models/Init/init.go中调用初始化
func Init() {
mdb = db.Init(table)
initIndex()
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "_id", Value: 1}},
},
{
Keys: bson.D{{Key: "uid", Value: 1}},
},
{
Keys: bson.D{{Key: "type", Value: 1}},
},
{
Keys: bson.D{{Key: "status", Value: 1}, {Key: "sortCode", Value: -1}, {Key: "reviewAt", Value: -1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
+142
View File
@@ -0,0 +1,142 @@
package aitemplatemodulemod
import (
"encoding/json"
"errors"
"fmt"
"91porn-server/common/db"
"91porn-server/common/log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// GetList 获取列表
func GetList(cond bson.M, skip, limit int64, sort bson.D) (res []AiTemplateModule, count int64, hasNext bool, err error) {
count, err = coll(nil).Count(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetList", table, "Count", err),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("cond", cond),
log.Any("sort", sort),
)
return
}
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort).SetSkip(skip).SetLimit(limit + 1)
if err = coll(nil).Find(&res, cond, opts); err != nil {
return
}
// 判断下一页
if len(res) > int(limit) {
hasNext = true
res = res[:limit]
}
return
}
// GetAll 查询全部文档
func GetAll(filter primitive.M, sort bson.D) (out []AiTemplateModule, err error) {
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort)
if err = coll(nil).Find(&out, filter, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAll", table, "Find", err),
log.Any("filter", filter),
log.Any("opts", opts),
)
return nil, err
}
return
}
// QueryAllCount 查询文档条目数
func QueryAllCount(filter primitive.M) (int64, error) {
if count, err := coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllCount", table, "Count", err),
log.Any("filter", filter),
)
return 0, err
} else {
return count, nil
}
}
// GetInfo 通过id获取详细信息
func GetInfo(id primitive.ObjectID) (AiTemplateModule, error) {
v := AiTemplateModule{}
if err := coll(nil).FindOne(&v, bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetInfo", table, "FindOne", err),
log.Any("id", id),
)
return v, err
}
if v.ID.IsZero() {
return v, errors.New("record not found")
}
return v, nil
}
// Insert 插入记录
func Insert(t *db.MongoTool, d AiTemplateModule) (data primitive.ObjectID, err error) {
result, err := coll(t).InsertOne(&d)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return
}
byteID, err := json.Marshal(result.InsertedID)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "Marshal", err))
return
}
if err = data.UnmarshalJSON(byteID); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "UnmarshalJSON", err))
return
}
return
}
// UpdateByID 根据id更新数据
func UpdateByID(t *db.MongoTool, id primitive.ObjectID, data map[string]interface{}) (int64, error) {
cond := bson.M{"_id": id}
return update(t, cond, data)
}
// update 更新数据
func update(t *db.MongoTool, cond primitive.M, data map[string]interface{}) (int64, error) {
result, err := coll(t).UpdateMany(cond, bson.M{"$set": bson.M(data)})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateMany", err),
log.Any("cond", cond),
log.Any("update", data),
)
return 0, err
}
return result.ModifiedCount, nil
}
// DeleteByID 删除数据
func DeleteByID(t *db.MongoTool, id primitive.ObjectID) error {
_, err := coll(t).DeleteMany(bson.M{"_id": id})
if err != nil {
if err == mongo.ErrNoDocuments {
return nil
} else {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteByID", table, "DeleteMany", err), log.Any("id", id))
}
}
return err
}
+12
View File
@@ -0,0 +1,12 @@
package aitemplatemodulemod
import (
"go.mongodb.org/mongo-driver/bson/primitive"
)
// AiTemplateModuleInfo 移动端返回内容
type AiTemplateModuleInfo struct {
ID primitive.ObjectID `json:"id"` // 文档id
Type int `json:"type"` // 模块类型
Name string `json:"name"` // 模块名称
}
+55
View File
@@ -0,0 +1,55 @@
package aitemplatemodulemod
import (
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
var mdb *db.MongoDB
const table = models.AiTemplateModule
type AiTemplateModule struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档id
Type int `json:"type" bson:"type"` // 模块类型 1:AI视频换脸,2:AI图片换脸
Name string `json:"name" bson:"name"` // 模块名称
Status int `json:"status" bson:"status"` // 状态 1:开启,2:关闭
SortNum int `json:"sortNum" bson:"sortNum"` // 模块排序
IsDelete bool `json:"isDelete" bson:"isDelete"` // 是否删除
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
}
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// Init 初始化索引
func Init() {
mdb = db.Init(table)
initIndex()
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "type", Value: 1}},
},
{
Keys: bson.D{{Key: "status", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
+147
View File
@@ -0,0 +1,147 @@
package aitexttoimagemod
import (
"encoding/json"
"errors"
"fmt"
"91porn-server/common/db"
"91porn-server/common/log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// GetList 获取列表
func GetList(cond bson.M, skip, limit int64, sort bson.D) (res []AiTextToImage, count int64, hasNext bool, err error) {
count, err = coll(nil).Count(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetList", table, "Count", err),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("cond", cond),
log.Any("sort", sort),
)
return
}
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort).SetSkip(skip).SetLimit(limit + 1)
if err = coll(nil).Find(&res, cond, opts); err != nil {
return
}
// 判断下一页
if len(res) > int(limit) {
hasNext = true
res = res[:limit]
}
return
}
// GetAll 查询全部文档
func GetAll(filter primitive.M, sort bson.D) (out []*AiTextToImage, err error) {
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort)
if err = coll(nil).Find(&out, filter, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAll", table, "Find", err),
log.Any("filter", filter),
log.Any("opts", opts),
)
return nil, err
}
return
}
// QueryAllCount 查询文档条目数
func QueryAllCount(filter primitive.M) (int64, error) {
if count, err := coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllCount", table, "Count", err),
log.Any("filter", filter),
)
return 0, err
} else {
return count, nil
}
}
// GetInfo 通过id获取详细信息
func GetInfo(id primitive.ObjectID) (AiTextToImage, error) {
v := AiTextToImage{}
if err := coll(nil).FindOne(&v, bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetInfo", table, "FindOne", err),
log.Any("id", id),
)
return v, err
}
if v.ID.IsZero() {
return v, errors.New("record not found")
}
return v, nil
}
// Insert 插入记录
func Insert(t *db.MongoTool, d AiTextToImage) (data primitive.ObjectID, err error) {
result, err := coll(t).InsertOne(&d)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return
}
byteID, err := json.Marshal(result.InsertedID)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "Marshal", err))
return
}
if err = data.UnmarshalJSON(byteID); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "UnmarshalJSON", err))
return
}
return
}
// UpdateByID 根据id更新数据
func UpdateByID(t *db.MongoTool, id primitive.ObjectID, data map[string]interface{}) (int64, error) {
cond := bson.M{"_id": id}
return update(t, cond, data)
}
// update 更新数据
func update(t *db.MongoTool, cond primitive.M, data map[string]interface{}) (int64, error) {
result, err := coll(t).UpdateMany(cond, bson.M{"$set": bson.M(data)})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateMany", err),
log.Any("cond", cond),
log.Any("update", data),
)
return 0, err
}
return result.ModifiedCount, nil
}
// DeleteByID 删除数据
func DeleteByID(t *db.MongoTool, id primitive.ObjectID) error {
_, err := coll(t).DeleteMany(bson.M{"_id": id})
if err != nil {
if err == mongo.ErrNoDocuments {
return nil
} else {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteByID", table, "DeleteMany", err), log.Any("id", id))
}
}
return err
}
func Hide(uid uint64, id primitive.ObjectID) error {
_, err := coll(nil).UpdateOne(bson.M{"uid": uid, "_id": id}, bson.M{"$set": bson.M{"isHide": true}})
return err
}
+28
View File
@@ -0,0 +1,28 @@
package aitexttoimagemod
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// AiTextToImageInfo 移动端返回内容
type AiTextToImageInfo struct {
ID primitive.ObjectID `json:"id"` // 文档id
UID uint64 `json:"uid"` // 用户ID
Text string `json:"text"` // 图片描述
NewImgUrl string `json:"newImgUrl"` // 处理后的图片地址
Status int `json:"status"` // 状态
AspectRatio string `json:"aspectRatio"` // 长宽比
StyleType int `json:"styleType"` // 风格类型
StyleUrl string `json:"styleUrl"` // 绘画风格图片
Coin int64 `json:"coin"` // AI绘图金币个数
DebitAmountCoin int64 `json:"debitAmountCoin"` // 此次脱衣扣除金币个数
DebitIncomeCoin int64 `json:"debitIncomeCoin"` // 此次脱衣扣除收益金币个数
IsFreeTimes bool `json:"isFreeTimes"` // 是否使用免费次数
IsHide bool `json:"isHide"` // 是否被用户隐藏
Remark string `json:"remark"` // 备注
IsDelete bool `json:"isDelete"` // 是否删除
CreatedAt time.Time `json:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt"` // 更新时间
}
+78
View File
@@ -0,0 +1,78 @@
package aitexttoimagemod
import (
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
var mdb *db.MongoDB
const table = models.AiTextToImage
type AiTextToImageStatus int
const (
StatusOrderSuccess AiTextToImageStatus = iota + 1 // 1: 下单成功
StatusSubmitted // 2: 已提交
StatusGenerationSuccess // 3: 生成成功
StatusGenerationFailed // 4: 生成失败
StatusRefunded // 5: 退款
)
type AiTextToImage struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档id
UID uint64 `json:"uid" bson:"uid"` // 用户ID
Text string `json:"text" bson:"text"` // 图片描述
NewImgUrl string `json:"newImgUrl" bson:"newImgUrl"` // 处理后的图片地址
Status int `json:"status" bson:"status"` // 状态
AspectRatio string `json:"aspectRatio" bson:"aspectRatio"` // 长宽比
StyleType int `json:"styleType" bson:"styleType"` // 风格类型
Coin int64 `json:"coin" bson:"coin"` // AI绘图金币个数
DebitAmountCoin int64 `json:"debitAmountCoin" bson:"debitAmountCoin"` // 此次脱衣扣除金币个数
DebitIncomeCoin int64 `json:"debitIncomeCoin" bson:"debitIncomeCoin"` // 此次脱衣扣除收益金币个数
IsFreeTimes bool `json:"isFreeTimes" bson:"isFreeTimes"` // 是否使用免费次数
IsHide bool `json:"isHide" bson:"isHide"` // 是否被用户隐藏
Remark string `json:"remark" bson:"remark"` // 备注
ShareTitle string `json:"shareTitle" bson:"shareTitle"` // 分享标题
ShareStatus int `json:"shareStatus" bson:"shareStatus"` // 是否分享 0-不分享 1-分享
IsDelete bool `json:"isDelete" bson:"isDelete"` // 是否删除
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
}
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// Init 初始化索引
func Init() {
mdb = db.Init(table)
initIndex()
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "status", Value: 1}},
},
{
Keys: bson.D{{Key: "isDelete", 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))
}
}
+146
View File
@@ -0,0 +1,146 @@
package aitexttonovelmod
import (
"91porn-server/common/db"
"91porn-server/common/log"
"encoding/json"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// GetList 获取列表
func GetList(cond bson.M, skip, limit int64, sort bson.D) (res []AiTextToNovel, count int64, hasNext bool, err error) {
count, err = coll(nil).Count(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetList", table, "Count", err),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("cond", cond),
log.Any("sort", sort),
)
return
}
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort).SetSkip(skip).SetLimit(limit + 1)
if err = coll(nil).Find(&res, cond, opts); err != nil {
return
}
// 判断下一页
if len(res) > int(limit) {
hasNext = true
res = res[:limit]
}
return
}
// GetAll 查询全部文档
func GetAll(filter primitive.M, sort bson.D) (out []*AiTextToNovel, err error) {
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort)
if err = coll(nil).Find(&out, filter, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAll", table, "Find", err),
log.Any("filter", filter),
log.Any("opts", opts),
)
return nil, err
}
return
}
// QueryAllCount 查询文档条目数
func QueryAllCount(filter primitive.M) (int64, error) {
if count, err := coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllCount", table, "Count", err),
log.Any("filter", filter),
)
return 0, err
} else {
return count, nil
}
}
// GetInfo 通过id获取详细信息
func GetInfo(id primitive.ObjectID) (AiTextToNovel, error) {
v := AiTextToNovel{}
if err := coll(nil).FindOne(&v, bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetInfo", table, "FindOne", err),
log.Any("id", id),
)
return v, err
}
if v.ID.IsZero() {
return v, errors.New("record not found")
}
return v, nil
}
// Insert 插入记录
func Insert(t *db.MongoTool, d AiTextToNovel) (data primitive.ObjectID, err error) {
result, err := coll(t).InsertOne(&d)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return
}
byteID, err := json.Marshal(result.InsertedID)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "Marshal", err))
return
}
if err = data.UnmarshalJSON(byteID); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "UnmarshalJSON", err))
return
}
return
}
// UpdateByID 根据id更新数据
func UpdateByID(t *db.MongoTool, id primitive.ObjectID, data map[string]interface{}) (int64, error) {
cond := bson.M{"_id": id}
return update(t, cond, data)
}
// update 更新数据
func update(t *db.MongoTool, cond primitive.M, data map[string]interface{}) (int64, error) {
result, err := coll(t).UpdateMany(cond, bson.M{"$set": bson.M(data)})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateMany", err),
log.Any("cond", cond),
log.Any("update", data),
)
return 0, err
}
return result.ModifiedCount, nil
}
// DeleteByID 删除数据
func DeleteByID(t *db.MongoTool, id primitive.ObjectID) error {
_, err := coll(t).DeleteMany(bson.M{"_id": id})
if err != nil {
if err == mongo.ErrNoDocuments {
return nil
} else {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteByID", table, "DeleteMany", err), log.Any("id", id))
}
}
return err
}
func Hide(uid uint64, id primitive.ObjectID) error {
_, err := coll(nil).UpdateOne(bson.M{"uid": uid, "_id": id}, bson.M{"$set": bson.M{"isHide": true}})
return err
}
+77
View File
@@ -0,0 +1,77 @@
package aitexttonovelmod
import (
"91porn-server/common/db"
"91porn-server/models"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
var mdb *db.MongoDB
const table = models.AiTextToNovel
type AiTextToNovelStatus int
const (
StatusOrderSuccess AiTextToNovelStatus = iota + 1 // 1: 下单成功
StatusSubmitted // 2: 已提交
StatusGenerationSuccess // 3: 生成成功
StatusGenerationFailed // 4: 生成失败
StatusRefunded // 5: 退款
)
type AiTextToNovel struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档id
UID uint64 `json:"uid" bson:"uid"` // 用户ID
CharacterSetting string `json:"characterSetting" bson:"characterSetting"` // 小说人物设定/故事背景等
LocationScene string `json:"locationScene" bson:"locationScene"` // 地点场景
Description string `json:"description" bson:"description"` // 故事情节描述
Details string `json:"details" bson:"details"` // 细节说明/其他要求
ModelType int `json:"modelType" bson:"modelType"` // AI小说模型 12
Content string `json:"content" bson:"content"` // AI生成小说正文
Status int `json:"status" bson:"status"` // 状态
Coin int64 `json:"coin" bson:"coin"` // AI小说金币个数
DebitAmountCoin int64 `json:"debitAmountCoin" bson:"debitAmountCoin"` // 此次AI小说扣除金币个数
DebitIncomeCoin int64 `json:"debitIncomeCoin" bson:"debitIncomeCoin"` // 此次AI小说扣除收益金币个数
IsFreeTimes bool `json:"isFreeTimes" bson:"isFreeTimes"` // 是否使用免费次数
IsHide bool `json:"isHide" bson:"isHide"` // 是否被用户隐藏
Remark string `json:"remark" bson:"remark"` // 备注
IsDelete bool `json:"isDelete" bson:"isDelete"` // 是否删除
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
}
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// Init 初始化索引
func Init() {
mdb = db.Init(table)
initIndex()
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "status", Value: 1}},
},
{
Keys: bson.D{{Key: "isDelete", 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))
}
}
+172
View File
@@ -0,0 +1,172 @@
package annoumod
import (
"fmt"
"math"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const table = models.Annou
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// InitIndex 初始化索引
func initAnnouIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "createdAt", Value: 1}},
},
{
Keys: bson.D{{Key: "active", Value: 1}},
},
{
Keys: bson.D{{Key: "updatedAt", Value: 1}},
},
{
Keys: bson.D{{Key: "type", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
// AddAnnou 增加公告
func AddAnnou(annou []Annou) error {
if _, err := coll(nil).InsertMany(&annou); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddAnnou", table, "InsertMany", err), log.Any("annou", annou))
return err
}
return nil
}
// DeleteAnnou 删除公告
func DeleteAnnou(ids []primitive.ObjectID) (int64, error) {
if ids == nil {
ids = []primitive.ObjectID{}
}
cond := bson.M{"_id": bson.M{"$in": ids}}
result, err := coll(nil).DeleteMany(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteAnnou", table, "DeleteMany", err), log.Any("ids", ids))
return 0, err
}
return result.DeletedCount, nil
}
// UpdateAnnou 更新公告
func UpdateAnnou(id primitive.ObjectID, update map[string]interface{}) (int64, error) {
cond := bson.M{"_id": id}
result, err := coll(nil).UpdateMany(cond, bson.M{"$set": bson.M(update)})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateAnnou", table, "UpdateMany", err),
log.Any("id", id),
log.Any("update", update),
)
return 0, err
}
return result.ModifiedCount, nil
}
// getTotalCnt 获取查询总数总数
func getTotalCnt(cond bson.M) (int64, error) {
total, err := coll(nil).Count(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "getTotalCnt", table, "Count", err), log.Any("cond", cond))
return 0, err
}
return total, nil
}
// GetSkipSize 计算跳转
func getSkipSize(page, size uint64, cond bson.M) (uint64, uint64, int64, error) {
total, err := getTotalCnt(cond)
if err != nil {
return 0, 0, 0, err
}
totalpages := uint64(math.Ceil(float64(total) / float64(size)))
if page > totalpages {
page = totalpages
}
if page < 1 {
page = 1
}
return (page - 1) * size, totalpages, total, nil
}
// GetAnnou 查询公告
func GetAnnou(page, size uint64, field string, desc int) ([]*Annou, uint64, int64, error) {
cond := bson.M{}
sort := bson.D{{Key: field, Value: desc}}
skip, totalPages, total, err := getSkipSize(page, size, cond)
if err != nil {
return nil, 0, 0, err
}
opts := options.FindOptions{}
opts.SetSort(sort).SetSkip(int64(skip)).SetLimit(int64(size))
var back []*Annou
if err = coll(nil).Find(&back, cond, &opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAnnou", table, "Find", err),
log.Any("page", page),
log.Any("size", size),
log.Any("field", field),
log.Any("desc", desc),
)
return nil, totalPages, total, err
}
return back, totalPages, total, nil
}
// GetAnnouByType 获取指定类型的公告
func GetAnnouByType(types int) ([]*Annou, error) {
cond := bson.M{"active": true}
if types != 2 {
cond = bson.M{"type": types, "active": true}
}
sort := bson.D{{Key: "updatedAt", Value: -1}}
opts := options.FindOptions{}
opts.SetSort(sort)
var back []*Annou
if err := coll(nil).Find(&back, cond, &opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAnnouByType", table, "Find", err), log.Any("types", types))
return nil, err
}
return back, nil
}
const (
TotalType = 1 //系统公告
VIPUP = 3 //vip升级公告
)
// GetAnnouForDomain 获取指定类型的公告
func GetAnnouForDomain(types int) ([]AnnounInfo, error) {
cond := bson.M{"active": true}
if types != 2 {
cond = bson.M{"type": types, "active": true}
}
sort := bson.D{{Key: "updatedAt", Value: -1}}
opts := options.FindOptions{}
opts.SetSort(sort)
var back []AnnounInfo
if err := coll(nil).Find(&back, cond, &opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAnnouForDomain", table, "Find", err), log.Any("types", types))
return nil, err
}
return back, nil
}
+109
View File
@@ -0,0 +1,109 @@
package annoumod
import (
"fmt"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdbAnnounce *db.MongoDB
const tableAnnounce = models.Announce
func collAnnounce(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdbAnnounce.Coll(tableAnnounce)
}
return t.Coll(tableAnnounce)
}
// InitIndex 初始化索引
func initAnnounceIndex() {
indexModels := []mongo.IndexModel{
{
Keys: bson.D{{Key: "active", Value: 1}},
Options: options.Index(),
},
}
if _, err := collAnnounce(nil).CreateIndex(indexModels); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", tableAnnounce, err))
}
}
// AddAnnounce 增加会员中心跑马灯
func AddAnnounce(announce []Announce) error {
if _, err := collAnnounce(nil).InsertMany(&announce); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddAnnounce", tableAnnounce, "InsertMany", err), log.Any("announce", announce))
return err
}
return nil
}
// DeleteAnnounce 删除会员中心跑马灯
func DeleteAnnounce(ids []primitive.ObjectID) (int64, error) {
if ids == nil {
ids = []primitive.ObjectID{}
}
cond := bson.M{"_id": bson.M{"$in": ids}}
result, err := collAnnounce(nil).DeleteMany(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteAnnounce", tableAnnounce, "DeleteMany", err), log.Any("ids", ids))
return 0, err
}
return result.DeletedCount, nil
}
// UpdateAnnounce 更新会员中心跑马灯
func UpdateAnnounce(id primitive.ObjectID, update map[string]interface{}) (int64, error) {
cond := bson.M{"_id": id}
result, err := collAnnounce(nil).UpdateMany(cond, bson.M{"$set": bson.M(update)})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateAnnou", tableAnnounce, "UpdateMany", err),
log.Any("id", id),
log.Any("update", update),
)
return 0, err
}
return result.ModifiedCount, nil
}
// GetAnnounce 查询会员中心跑马灯
func GetAnnounceApi(field string, desc int) ([]Announce, error) {
cond := bson.M{"active": true, "type": 0}
sort := bson.D{{Key: field, Value: desc}}
opts := options.FindOptions{}
opts.SetSort(sort)
var back []Announce
if err := collAnnounce(nil).Find(&back, cond, &opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAnnounce", tableAnnounce, "Find", err),
log.Any("field", field),
log.Any("desc", desc),
)
return nil, err
}
return back, nil
}
// GetAnnounce 查询会员中心跑马灯
func GetAnnounce(field string, desc int) ([]Announce, error) {
cond := bson.M{"type": 0}
sort := bson.D{{Key: field, Value: desc}}
opts := options.FindOptions{}
opts.SetSort(sort)
var back []Announce
if err := collAnnounce(nil).Find(&back, cond, &opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAnnounce", tableAnnounce, "Find", err),
log.Any("field", field),
log.Any("desc", desc),
)
return nil, err
}
return back, nil
}
+24
View File
@@ -0,0 +1,24 @@
package annoumod
import "go.mongodb.org/mongo-driver/bson/primitive"
// PopReq 公告列表
type PopReq struct {
Type int `form:"type" json:"type"` //公告类型,0,2,所有 3会员升级公告
}
// AppRes 公告模型
type AnnounInfo struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` //公告id
Title string `json:"title" bson:"title"` //公告标题
Content string `json:"content" bson:"content"` //公告内容
Cover string `json:"cover" bson:"cover"` //公告封面图
Href string `json:"href" bson:"href"` //公告跳转地址
Type int `json:"type" bson:"type"` //公告类型
}
// MsgListReq 公告列表
type MsgListReq struct {
PageNumber int `form:"pageNumber" json:"pageNumber"`
PageSize int `form:"pageSize" json:"pageSize"`
}
+42
View File
@@ -0,0 +1,42 @@
package annoumod
import (
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// Annou 公告模型
type Annou struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` //公告id
Title string `json:"title" bson:"title"` //公告标题
Content string `json:"content" bson:"content"` //公告内容
Cover string `json:"cover" bson:"cover"` //公告封面图
Type int `json:"type" bson:"type"` //公告类型,0,外部连接;1,直接安装app
Href string `json:"href" bson:"href"` //公告跳转地址
Active bool `json:"active" bson:"active"` //激活状态
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` //更新时间
}
func Init() {
mdb = db.Init(table)
mdbAnnounce = db.Init(tableAnnounce)
initAnnouIndex()
initAnnounceIndex()
}
// Announce 会员中心跑马灯模型
type Announce struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` //公告id
Content string `json:"content" bson:"content"` //跑马灯内容
Type int `json:"type" bson:"type"` //跑马灯类型,0,会员中心;
Url string `json:"url" bson:"url"` //跳转连接
Active bool `json:"active" bson:"active"` //激活状态
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` //更新时间
}
const UserCenter = 0 //会员中心
+85
View File
@@ -0,0 +1,85 @@
package annoumod
import "91porn-server/models/commod"
// ListReq 视频列表请求
type ListReq struct {
Sort string `form:"sort" json:"sort"`
Desc int `form:"desc" json:"desc"`
commod.Page
}
// EditInfo 更新的内容
type EditInfo struct {
Title string `form:"title" json:"title"` //公告标题
Cover string `form:"cover" json:"cover"` //公告封面图
Content string `form:"content" json:"content"` //公告内容
Type int `form:"type" json:"type"` //公告类型,0,外部连接;1,直接安装app
Href string `form:"href" json:"href"` //公告跳转地址
Active bool `form:"active" json:"active"` //激活状态
}
// EditReq 更新公告
type EditReq struct {
ID string `form:"id" json:"id"`
EditInfo
}
// DeleteReq 删除公告
type DeleteReq struct {
IDs []string `form:"ids" json:"ids"`
}
// AddReq 增加一条公告
type AddReq struct {
Title string `form:"title" json:"title"` //公告标题
Content string `form:"content" json:"content"` //公告内容
Cover string `form:"cover" json:"cover"` //公告封面图
Type int `form:"type" json:"type"` //公告类型,0,外部连接;1,直接安装app 3,会员升级公告
Href string `form:"href" json:"href"` //公告跳转地址
Active bool `form:"active" json:"active"` //激活状态
}
// ListResp 列表应答
type ListResp struct {
AInfos []*Annou `json:"aInfos"`
Total int64 `json:"total"`
}
// OpeResp 操作应答
type OpeResp struct {
Count int64 `json:"count"`
}
// EditInfo 更新的内容
type EditAnnounceInfo struct {
Content string `form:"content" json:"content"` //跑马灯内容
Type int `form:"type" json:"type"` //跑马灯类型
Url string `form:"url" json:"url"` //跳转链接
Active bool `form:"active" json:"active"` //激活状态
}
// EditReq 更新公告
type EditAnnounceReq struct {
ID string `form:"id" json:"id"`
EditAnnounceInfo
}
// DeleteReq 删除公告
type DeleteAnnounceReq struct {
IDs []string `form:"ids" json:"ids"`
}
// AddReq 增加一条公告
type AddAnnounceReq struct {
Content string `form:"content" json:"content,omitempty" binding:"required"` //跑马灯内容
Url string `form:"url" json:"url,omitempty"` //跳转链接
Active bool `form:"active" json:"active,omitempty"` //激活状态
}
// 3、走马灯通知
// 接口:goldegg/announce
// AnnounceInfoReq 走马灯通告信息请求
type AnnounceInfoReq struct {
commod.Page
}
+323
View File
@@ -0,0 +1,323 @@
package audioanchormod
import (
"encoding/json"
"errors"
"fmt"
"time"
"91porn-server/app/appg"
"91porn-server/app/service/searcher"
"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/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const table = models.AudioAnchor
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
func GetByID(id primitive.ObjectID) (loufeng AudioAnchor, err error) {
if err = coll(nil).FindOne(&loufeng, bson.M{"_id": id}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByID", table, "FindOne", err), log.Any("id", id.Hex()))
}
return
}
// todo app
func GetInIds(ids []primitive.ObjectID) (res []AudioAnchor, err error) {
data := make([]AudioAnchor, 0)
f := bson.M{}
if ids != nil {
f["_id"] = bson.M{"$in": ids}
}
if err = coll(nil).Find(&data, f); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetInIds", table, "Find", err), log.Any("cond", f))
return
}
tempM := make(map[primitive.ObjectID]AudioAnchor)
for i := range data {
tempM[data[i].ID] = data[i]
}
res = make([]AudioAnchor, len(ids))
for i := range ids {
res[i] = tempM[ids[i]]
}
return
}
func GetRandomPush(size int) (data []AudioAnchor, err error) {
data = make([]AudioAnchor, 0)
f := bson.M{"name": bson.M{"$gt": ""}}
if err = coll(nil).Find(&data, f); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetRandomPush", table, "Aggregate", err), log.Any("filter", f))
return
}
return
}
func GetByName(name string) (data AudioAnchor, err error) {
f := bson.M{"name": name}
if err = coll(nil).FindOne(&data, f); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByFType", table, "Find", err), log.Any("cond", f))
return
}
return
}
func GetFTypes() ([]interface{}, error) {
data := make([]interface{}, 0)
redisKey := RedisSetKey + ":fType"
redisc := appg.Redis
if redisc == nil || !redisc.Exists(redisKey) {
data, err := coll(nil).Distinct("fType", bson.M{})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCitys", table, "Distinct", err))
return nil, err
}
if redisc == nil {
return data, nil
}
jsonBytes, err := json.Marshal(data)
if err != nil {
return data, err
}
_ = redisc.Set(redisKey, string(jsonBytes), time.Minute*10)
return data, nil
}
str, err := redisc.Get(redisKey)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetFTypes", table, "Find", err))
return nil, err
}
if str == nil {
return data, errors.New("redis key is null")
}
return data, json.Unmarshal([]byte(*str), &data)
}
func GetSortWord(page commod.Page, sortWord string) ([]AudioAnchor, bool, error) {
data := make([]AudioAnchor, 0)
skip := int64(page.Skip())
limit := int64(page.Limit() + 1)
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: sortWord, Value: -1}},
}
f := bson.M{"name": bson.M{"$gt": ""}}
if err := coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByFType", table, "Find", err), log.Any("cond", f))
return data, false, err
}
hasNext := false
if uint64(len(data)) > page.PageSize {
hasNext = true
data = data[:page.PageSize]
}
return data, hasNext, nil
}
func SearchName(name string, page commod.Page) (data []AudioAnchorAppRes, hasNext bool, err error) {
data = make([]AudioAnchorAppRes, 0)
skip := int64(page.Skip())
limit := int64(page.Limit() + 1)
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: "createdAt", Value: 1}},
}
f := bson.M{}
f["$or"] = bson.A{
bson.M{"name": primitive.Regex{
Pattern: name,
Options: "",
}},
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "SearchName", table, "Find", err), log.Any("cond", f))
return
}
if uint64(len(data)) > page.PageSize {
hasNext = true
data = data[:page.PageSize]
}
return
}
func IncCount(id primitive.ObjectID, inc CountInc) error {
res, err := coll(nil).UpdateOne(bson.M{"_id": id}, bson.M{"$inc": inc})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IncCount", table, "UpdateOne", err), log.Any("id", id), log.Any("inc", inc))
return err
}
if res.ModifiedCount <= 0 {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s none", "IncCount", table, "UpdateOne"), log.Any("id", id), log.Any("inc", inc), log.Any("res", res))
return nil
}
return nil
}
func GetNew(opt searcher.Opter) (data []AudioAnchorAppRes, hasNext bool, err error) {
data = make([]AudioAnchorAppRes, 0)
skip := opt.Skip()
limit := opt.Limit()
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
f := bson.M{"isActive": true}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetNew", table, "Find", err), log.Any("cond", f))
return
}
if int64(len(data)) > limit {
hasNext = true
data = data[:limit]
}
return
}
// todo web
// StdFind 通用查询
func StdFind(q QuerySelector, page commod.Page) (data []AudioAnchor, total int64, err error) {
data = make([]AudioAnchor, 0)
skip := int64(page.Skip())
limit := int64(page.Limit())
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
f, err := common.ToBsonM(q)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "StdFind", table, "ToBsonM", err), log.Any("cond", f))
return
}
if q.Title != nil {
f["title"] = primitive.Regex{
Pattern: *q.Title,
Options: "",
}
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "StdFind", table, "Find", err), log.Any("cond", f))
return
}
total, err = coll(nil).Count(f)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "StdFind", table, "Count", err), log.Any("cond", f))
}
return
}
// IsExisted 查询
func IsExisted(id primitive.ObjectID) (ok bool, err error) {
ok, err = coll(nil).Exists(bson.M{"_id": id})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsExisted", table, "Exists", err), log.Any("id", id))
return
}
return
}
// InsertAudioAnchor 插入一条数据
func InsertAudioAnchor(p *AudioAnchor) error {
p.CreatedAt = time.Now()
if _, err := coll(nil).InsertOne(p); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertAudioAnchor", table, "InsertOne", err))
return err
}
return nil
}
// InsertBulket 插入一条数据
func InsertBulket(p []EditSelector) (err error) {
fmt.Println("------------", len(p))
now := time.Now()
wm := make([]mongo.WriteModel, len(p))
for i := range p {
filter := bson.M{"name": p[i].Name}
update := bson.M{"$inc": bson.M{"totalRaido": 1}, "$set": p[i], "$setOnInsert": bson.M{"createdAt": now}}
wm[i] = mongo.NewUpdateOneModel().
SetFilter(filter).
SetUpdate(update).
SetUpsert(true)
}
ordered := false
opts := options.BulkWriteOptions{
Ordered: &ordered,
}
if _, err = coll(nil).Bulk(wm, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertMany", table, "InsertMany", err))
}
return
}
// InsertAudioAnchor 插入一条数据
func InsertMany(p []AudioAnchor) error {
if _, err := coll(nil).InsertMany(p); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertMany", table, "InsertMany", err))
return err
}
return nil
}
// UpdateAudioAnchor 修改AudioAnchor类型
func UpdateAudioAnchor(set *EditSelector) error {
set.UpdatedAt = time.Now()
if _, err := coll(nil).UpdateOne(bson.M{"_id": set.ID}, bson.M{"$set": set}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateAudioAnchor", table, "UpdateOne", err),
log.Any("set", set),
)
return err
}
return nil
}
// RemoveAudioAnchor 删除AudioAnchor类型
func RemoveAudioAnchor(id string) error {
OID, err := primitive.ObjectIDFromHex(id)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "RemoveAudioAnchor", table, "ObjectIDFromHex", err),
log.Any("id", id),
)
return err
}
if _, err = coll(nil).DeleteOne(bson.M{"_id": OID}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "RemoveAudioAnchor", table, "DeleteOne", err),
log.Any("OID", OID),
)
return err
}
return nil
}
// todo skd
// 获取ES同步数据
func GetListByUpdateTimeRange(start time.Time, end time.Time) (data []AudioAnchor, err error) {
var query = bson.M{
"updatedAt": bson.M{"$gte": start, "$lt": end},
}
if err = coll(nil).Find(&data, query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetListByUpdateTimeRange", table, "Find", err),
log.Any("start", start),
log.Any("end", end),
)
return
}
return
}
+105
View File
@@ -0,0 +1,105 @@
package audioanchormod
import (
"fmt"
"91porn-server/common/elastic"
"91porn-server/common/log"
"91porn-server/models"
)
var es *elastic.Client
const ESTable = models.ESInfoLouFengTable
func InitESIndex() {
es = elastic.Init()
var setting = elastic.M{
"settings": elastic.M{
"number_of_shards": elastic.NumberOfShards,
"number_of_replicas": elastic.NumberOfReplicas,
"analysis": elastic.M{
"analyzer": elastic.M{
"ik": elastic.M{
"tokenizer": elastic.AnalyzerIkMaxWord,
},
},
},
},
"mappings": elastic.M{
"properties": elastic.M{
"age": elastic.M{
"type": "text",
"analyzer": elastic.AnalyzerIkMaxWord,
"search_analyzer": elastic.AnalyzerIkSmart,
},
"price": elastic.M{
"type": "text",
"analyzer": elastic.AnalyzerIkMaxWord,
"search_analyzer": elastic.AnalyzerIkSmart,
},
"title": elastic.M{
"type": "text",
"analyzer": elastic.AnalyzerIkMaxWord,
"search_analyzer": elastic.AnalyzerIkSmart,
},
"city": elastic.M{
"type": "text",
"analyzer": elastic.AnalyzerIkMaxWord,
"search_analyzer": elastic.AnalyzerIkSmart,
},
"district": elastic.M{
"type": "text",
"analyzer": elastic.AnalyzerIkMaxWord,
"search_analyzer": elastic.AnalyzerIkSmart,
},
"impression": elastic.M{
"type": "text",
"analyzer": elastic.AnalyzerIkMaxWord,
"search_analyzer": elastic.AnalyzerIkSmart,
},
"contact": elastic.M{
"type": "text",
"analyzer": elastic.AnalyzerIkSmart,
"search_analyzer": elastic.AnalyzerIkSmart,
},
"serviceItems": elastic.M{
"type": "text",
"analyzer": elastic.AnalyzerIkMaxWord,
"search_analyzer": elastic.AnalyzerIkSmart,
},
},
},
}
if err := es.CreateIndices(ESTable, setting); err != nil {
panic(fmt.Sprintf("%s index indeices err ==>[%+v]", ESTable, err))
}
}
func Search(keywords string, from int64, size int64) (data []ESUserSource, err error) {
query := elastic.M{
"query": elastic.M{
"bool": elastic.M{
"must": elastic.A{
{"multi_match": elastic.M{
"query": keywords,
"fields": []string{"city", "impression", "title", "serviceItems", "price"}},
},
{"term": elastic.M{"isActive": true}},
},
},
},
"from": from,
"size": size,
}
if err = es.Search(ESTable, &data, query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Search", table, "CommonSearch", err),
log.Any("keywords", keywords),
log.Any("from", from),
log.Any("size", size),
)
return
}
return
}
+69
View File
@@ -0,0 +1,69 @@
package audioanchormod
import (
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson/primitive"
)
var mdb *db.MongoDB
type AudioAnchor struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Name string `json:"name" bson:"name"` //名字
Avatar string `json:"avatar" bson:"avatar"` //头像
TotalRaido int `json:"totalRaido" bson:"totalRaido"` //作品总量
CountCollect int64 `json:"countCollect" bson:"countCollect"` //收藏数
IsCollect bool `json:"isCollect" bson:"-"`
CreatedAt time.Time `json:"createdAt" bson:"createdAt,omitempty"` //创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt,omitempty"` //修改时间
}
func Init() {
mdb = db.Init(table)
}
type QuerySelector struct {
ID *primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`
Title *string `json:"title,omitempty" bson:"title,omitempty"` //标题
FType *string `json:"fType,omitempty" bson:"fType,omitempty"` //小说类型
Summary *string `json:"summary,omitempty" bson:"summary,omitempty"` //简介
ContentURL *string `json:"contentUrl,omitempty" bson:"contentUrl,omitempty"` //内容地址
IsActive *bool `json:"isActive,omitempty" bson:"isActive,omitempty"` //是否激活
Number *int `json:"number,omitempty" bson:"number,omitempty"` //编号
}
type EditSelector struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Name string `json:"name" bson:"name"` //名字
Avatar string `json:"avatar" bson:"avatar,omitempty"` //头像
Number int `json:"number" bson:"number,omitempty"` //编号
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` //更新时间
}
const RedisSetKey = "fiction"
// todo app
type AudioAnchorAppRes struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Title string `json:"title" bson:"title,omitempty"` //标题
FType string `json:"fType" bson:"fType"` //小说类型
Summary string `json:"summary" bson:"summary"` //简介
ContentURL string `json:"contentUrl" bson:"contentUrl"` //内容地址
IsActive bool `json:"isActive" bson:"isActive"` //是否激活
CountPurchases int64 `json:"countPurchases" bson:"countPurchases"` //购买数
CountBrowse int64 `json:"countBrowse" bson:"countBrowse"` //浏览数
CountCollect int64 `json:"countCollect" bson:"countCollect"` //收藏数
IsCollect bool `json:"isCollect"` //是否收藏
}
type CountInc struct {
CountCollect *int `json:"countCollect" bson:"countCollect,omitempty"` //收藏数
}
type ESUserSource struct {
ID string `json:"_id"`
Source AudioAnchorAppRes `json:"_source"`
}
+631
View File
@@ -0,0 +1,631 @@
package audiobookmod
import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"time"
"91porn-server/app/appg"
"91porn-server/app/service/searcher"
"91porn-server/common"
"91porn-server/common/constant/redisconst"
"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/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const table = models.AudioBook
// InitIndex 设置index
func initIndex() {
coll := coll(nil)
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "number", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "isActive", Value: 1}},
},
{
Keys: bson.D{{Key: "fType", Value: 1}},
},
{
Keys: bson.D{{Key: "anchor", Value: 1}},
},
}
if _, err := coll.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 GetByID(id primitive.ObjectID) (ab AudioBookAppRes, err error) {
redisKey := redisconst.DataCachKey(table, id.Hex())
redisc := appg.Redis
if redisc == nil || !redisc.Exists(redisKey) {
if err = coll(nil).FindOne(&ab, bson.M{"_id": id}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByID", table, "FindOne", err), log.Any("id", id.Hex()))
return
}
if redisc == nil {
return
}
var jsonBytes []byte
jsonBytes, err = json.Marshal(&ab)
if err != nil {
return
}
err = redisc.Set(redisKey, string(jsonBytes), redisconst.DataCachExpire)
return
}
str, err := redisc.Get(redisKey)
if err != nil {
return
}
if str == nil {
err = errors.New("redis key is null")
return
}
if err = json.Unmarshal([]byte(*str), &ab); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByID", table, "FindOne", err), log.Any("id", id.Hex()))
return
}
return
}
// todo app
func GetByIds(ids []primitive.ObjectID) (res []AudioBookAppRes, err error) {
data := make([]AudioBookAppRes, 0)
f := bson.M{}
if ids != nil {
f["_id"] = bson.M{"$in": ids}
}
if err = coll(nil).Find(&data, f); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByBusinessDateAndCityInIds", table, "Find", err), log.Any("cond", f))
return
}
tempM := make(map[primitive.ObjectID]AudioBookAppRes)
for i := range data {
tempM[data[i].ID] = data[i]
}
res = make([]AudioBookAppRes, len(ids))
for i := range ids {
res[i] = tempM[ids[i]]
}
return
}
func GetByFType(fType string, page commod.Page) (data []AudioBookBase, hasNext bool, err error) {
data = make([]AudioBookBase, 0)
skip := int64(page.Skip())
limit := int64(page.Limit() + 1)
sortWord := "createdAt"
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: sortWord, Value: -1}},
}
f := bson.M{"isActive": true}
if fType != "" {
if fType == ListenPermissionBuyZone {
f["contentSet.listenPermission"] = ListenPermissionBuy
} else {
f["fType"] = fType
}
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByFType", table, "Find", err), log.Any("cond", f))
return
}
if uint64(len(data)) > page.PageSize {
hasNext = true
data = data[:page.PageSize]
}
for i := range data {
for j := range data[i].ContentSet {
data[i].ContentSet[j].ListenPermission = 3
data[i].ContentSet[j].Price = 0
}
}
return
}
func GetByAnchor(anchor string, page commod.Page) (data []AudioBookBase, hasNext bool, err error) {
data = make([]AudioBookBase, 0)
skip := int64(page.Skip())
limit := int64(page.Limit() + 1)
sortWord := "createdAt"
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: sortWord, Value: -1}},
}
f := bson.M{"isActive": true}
if anchor != "" {
f["anchor"] = anchor
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByFType", table, "Find", err), log.Any("cond", f))
return
}
if uint64(len(data)) > page.PageSize {
hasNext = true
data = data[:page.PageSize]
}
return
}
// 获取热门
func GetHots(page commod.Page) (data []AudioBookBase, hasNext bool, err error) {
data = make([]AudioBookBase, 0)
skip := int64(page.Skip())
limit := int64(page.Limit() + 1)
sortWord := "countPurchases"
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: sortWord, Value: -1}},
}
f := bson.M{"isActive": true}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetByFType", table, "Find", err), log.Any("cond", f))
return
}
if uint64(len(data)) > page.PageSize {
hasNext = true
data = data[:page.PageSize]
}
return
}
func GetRandomPush(size int) (data []AudioBookBase, err error) {
data = make([]AudioBookBase, 0)
redisK := "tempSet:" + RedisSetKey + ":randomData"
redisc := appg.Redis
if redisc == nil || !redisc.Exists(redisK) {
f := bson.M{"isActive": true}
var total int64
total, err = randomCount(f)
if err != nil {
return
}
var limit int64 = 100
var skip int64 = 0
if total-limit > limit {
skip = rand.Int63n(total - limit)
}
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetRandomPush", table, "Find", err), log.Any("filter", f))
return
}
if len(data) < 1 {
return
}
if redisc == nil {
return
}
tempd := make([]string, len(data))
for i := range data {
var strB []byte
strB, err = json.Marshal(data[i])
if err != nil {
return
}
tempd[i] = string(strB)
}
if _, err = redisc.SAdd(redisK, tempd); err != nil {
return
}
_, _ = redisc.ExpireKey(redisK, time.Minute*10)
}
tempd, err := redisc.SRandMemberN(redisK, int64(size))
if len(tempd) < 1 {
return data, errors.New("redis key is null")
}
data = make([]AudioBookBase, len(tempd))
for i := range data {
_ = json.Unmarshal([]byte(tempd[i]), &data[i])
}
return
}
func GetRandomPush_PermissionBuy(size int) (data []AudioBookBase, err error) {
data = make([]AudioBookBase, 0)
redisK := "tempSet:" + RedisSetKey + ":randomData:permissionBuy"
redisc := appg.Redis
if redisc == nil || !redisc.Exists(redisK) {
f := bson.M{"isActive": true, "contentSet.listenPermission": ListenPermissionBuy}
var total int64
total, err = randomCount(f)
if err != nil {
return
}
var limit int64 = 100
var skip int64 = 0
if total-limit > limit {
skip = rand.Int63n(total - limit)
}
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetRandomPush_PermissionBuy", table, "Find", err), log.Any("filter", f))
return
}
if len(data) < 1 {
return
}
if redisc == nil {
return
}
tempd := make([]string, len(data))
for i := range data {
var strB []byte
strB, err = json.Marshal(data[i])
if err != nil {
return
}
tempd[i] = string(strB)
}
if _, err = redisc.SAdd(redisK, tempd); err != nil {
return
}
_, _ = redisc.ExpireKey(redisK, time.Minute*10)
}
tempd, err := redisc.SRandMemberN(redisK, int64(size))
if len(tempd) < 1 {
return data, errors.New("redis key is null")
}
data = make([]AudioBookBase, len(tempd))
for i := range data {
_ = json.Unmarshal([]byte(tempd[i]), &data[i])
}
return
}
func GetRandomPush_PermissionVIP(size int) (data []AudioBookBase, err error) {
data = make([]AudioBookBase, 0)
redisK := "tempSet:" + RedisSetKey + ":randomData:PermissionVIP"
redisc := appg.Redis
if redisc == nil || !redisc.Exists(redisK) {
f := bson.M{"isActive": true, "contentSet.listenPermission": ListenPermissionVIP}
var total int64
total, err = randomCount(f)
if err != nil {
return
}
var limit int64 = 100
var skip int64 = 0
if total-limit > limit {
skip = rand.Int63n(total - limit)
}
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetRandomPush_PermissionVIP", table, "Find", err), log.Any("filter", f))
return
}
if len(data) < 1 {
return
}
if redisc == nil {
return
}
tempd := make([]string, len(data))
for i := range data {
var strB []byte
strB, err = json.Marshal(data[i])
if err != nil {
return
}
tempd[i] = string(strB)
}
if _, err = redisc.SAdd(redisK, tempd); err != nil {
return
}
_, _ = redisc.ExpireKey(redisK, time.Minute*10)
}
tempd, err := redisc.SRandMemberN(redisK, int64(size))
if len(tempd) < 1 {
return data, errors.New("redis key is null")
}
data = make([]AudioBookBase, len(tempd))
for i := range data {
_ = json.Unmarshal([]byte(tempd[i]), &data[i])
}
return
}
func GetFTypes() (data []interface{}, err error) {
data = make([]interface{}, 0)
redisKey := RedisSetKey + ":fType"
redisc := appg.Redis
if redisc == nil || !redisc.Exists(redisKey) {
data, err = coll(nil).Distinct("fType", bson.M{})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCitys", table, "Distinct", err))
return nil, err
}
if redisc == nil {
return data, err
}
jsonBytes, err := json.Marshal(data)
if err != nil {
return data, err
}
_ = redisc.Set(redisKey, string(jsonBytes), time.Minute*10)
return data, err
}
str, err := redisc.Get(redisKey)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetFTypes", table, "Find", err))
return nil, err
}
if str == nil {
return data, errors.New("redis key is null")
}
err = json.Unmarshal([]byte(*str), &data)
return
}
func SearchTitle(title string, page commod.Page) (data []AudioBookBase, hasNext bool, err error) {
data = make([]AudioBookBase, 0)
skip := int64(page.Skip())
limit := int64(page.Limit() + 1)
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: "createdAt", Value: 1}},
}
f := bson.M{"isActive": true}
f["$or"] = bson.A{
bson.M{"title": primitive.Regex{
Pattern: title,
Options: "",
}},
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "SearchTitle", table, "Find", err), log.Any("cond", f))
return
}
if uint64(len(data)) > page.PageSize {
hasNext = true
data = data[:page.PageSize]
}
return
}
func IncCount(id primitive.ObjectID, inc CountInc) (err error) {
res, err := coll(nil).UpdateOne(bson.M{"_id": id}, bson.M{"$inc": inc})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IncCount", table, "UpdateOne", err), log.Any("id", id), log.Any("inc", inc))
return
}
if res.ModifiedCount <= 0 {
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IncCount", table, "UpdateOne", err), log.Any("id", id), log.Any("inc", inc), log.Any("res", res))
return
}
}
return
}
func GetNew(opt searcher.Opter) (data []AudioBookAppRes, hasNext bool, err error) {
data = make([]AudioBookAppRes, 0)
skip := opt.Skip()
limit := opt.Limit() + 1
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: bson.D{{Key: "createdAt", Value: -1}},
}
f := bson.M{"isActive": true}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetNew", table, "Find", err), log.Any("cond", f))
return
}
if int64(len(data)) > opt.Limit() {
hasNext = true
data = data[:opt.Limit()]
}
return
}
func randomCount(f bson.M) (count int64, err error) {
count, err = coll(nil).Count(f)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCitys", table, "Distinct", err))
return
}
return
}
// todo web
// StdFind 通用查询
func StdFind(q QuerySelector, page commod.Page) (data []AudioBook, total int64, err error) {
data = make([]AudioBook, 0)
skip := int64(page.Skip())
limit := int64(page.Limit())
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
}
f, err := common.ToBsonM(q)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "StdFind", table, "ToBsonM", err), log.Any("cond", f))
return
}
if q.Title != nil {
f["title"] = primitive.Regex{
Pattern: *q.Title,
Options: "",
}
}
if err = coll(nil).Find(&data, f, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "StdFind", table, "Find", err), log.Any("cond", f))
return
}
total, err = coll(nil).Count(f)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "StdFind", table, "Count", err), log.Any("cond", f))
}
return
}
// IsExisted 查询
func IsExisted(id primitive.ObjectID) (ok bool, err error) {
ok, err = coll(nil).Exists(bson.M{"_id": id})
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsExisted", table, "Exists", err), log.Any("id", id))
return
}
return
}
// InsertAudioBook 插入一条数据
func InsertAudioBook(p *AudioBook) (err error) {
p.CreatedAt = time.Now()
if _, err = coll(nil).InsertOne(p); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertAudioBook", table, "InsertOne", err))
}
return
}
// InsertBulket 插入一条数据
func InsertBulket(p []AudioBookUpsertEdit) (err error) {
fmt.Println("------------", len(p))
now := time.Now()
wm := make([]mongo.WriteModel, len(p))
for k := range p {
filter := bson.M{"number": p[k].Number}
update := bson.M{"$set": p[k], "$setOnInsert": bson.M{"createdAt": now, "contentSet": p[k].ContentSet}}
model := mongo.NewUpdateOneModel().
SetFilter(filter).
SetUpdate(update).
SetUpsert(true)
wm[k] = model
}
ordered := false
opts := options.BulkWriteOptions{
Ordered: &ordered,
}
if _, err = coll(nil).Bulk(wm, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertMany", table, "InsertMany", err))
}
return
}
// InsertAudioBook 插入一条数据
func InsertMany(p []AudioBook) (err error) {
if _, err = coll(nil).InsertMany(p); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertMany", table, "InsertMany", err))
}
return
}
// UpdateAudioBook 修改AudioBook类型
func UpdateAudioBookBatch(sets []EditSelector) (err error) {
now := time.Now()
wm := make([]mongo.WriteModel, len(sets))
for k := range sets {
sets[k].UpdatedAt = now
filter := bson.M{"_id": sets[k].ID}
update := bson.M{"$set": sets[k]}
model := mongo.NewUpdateOneModel().
SetFilter(filter).
SetUpdate(update).
SetUpsert(false)
wm[k] = model
}
ordered := false
opts := options.BulkWriteOptions{
Ordered: &ordered,
}
if _, err = coll(nil).Bulk(wm, &opts); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertMany", table, "InsertMany", err))
}
return
}
// UpdateAudioBook 修改AudioBook类型
func UpdateAudioBook(set EditSelector) error {
set.UpdatedAt = time.Now()
setM, err := common.ToBsonM(set)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "ToBsonM", table, "UpdateOne", err),
log.Any("set", set))
return err
}
if _, err = coll(nil).UpdateOne(bson.M{"_id": set.ID}, bson.M{"$set": setM}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateAudioBook", table, "UpdateOne", err),
log.Any("set", set),
)
return err
}
return nil
}
// RemoveAudioBook 删除AudioBook类型
func RemoveAudioBook(id string) error {
OID, err := primitive.ObjectIDFromHex(id)
if err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "RemoveAudioBook", table, "ObjectIDFromHex", err),
log.Any("id", id),
)
return err
}
if _, err = coll(nil).DeleteOne(bson.M{"_id": OID}); err != nil {
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "RemoveAudioBook", table, "DeleteOne", err),
log.Any("OID", OID),
)
return err
}
return nil
}
// todo skd
// 获取ES同步数据
func GetListByUpdateTimeRange(start time.Time, end time.Time) (data []AudioBookBase, err error) {
var query = bson.M{
"updatedAt": bson.M{"$gte": start, "$lt": end},
}
if err = coll(nil).Find(&data, query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetListByUpdateTimeRange", table, "Find", err),
log.Any("start", start),
log.Any("end", end),
)
return
}
return
}
func GetListByCond(cond bson.M, opts *options.FindOptions) ([]AudioBook, error) {
var data []AudioBook
if err := coll(nil).Find(&data, cond, opts); err != nil {
return nil, err
}
return data, nil
}
+69
View File
@@ -0,0 +1,69 @@
package audiobookmod
import (
"fmt"
"91porn-server/common/elastic"
"91porn-server/common/log"
"91porn-server/models"
)
var es *elastic.Client
const ESTable = models.ESInfoAudioBookTable
func InitESIndex() {
es = elastic.Init()
var setting = elastic.M{
"settings": elastic.M{
"number_of_shards": elastic.NumberOfShards,
"number_of_replicas": elastic.NumberOfReplicas,
"analysis": elastic.M{
"analyzer": elastic.M{
"ik": elastic.M{
"tokenizer": elastic.AnalyzerIkMaxWord,
},
},
},
},
"mappings": elastic.M{
"properties": elastic.M{
"title": elastic.M{
"type": "text",
"analyzer": elastic.AnalyzerIkMaxWord,
"search_analyzer": elastic.AnalyzerIkSmart,
},
},
},
}
if err := es.CreateIndices(ESTable, setting); err != nil {
panic(fmt.Sprintf("%s index indeices err ==>[%+v]", ESTable, err))
}
}
func Search(keywords string, from int64, size int64) (data []ESAudioBookSource, err error) {
query := elastic.M{
"query": elastic.M{
"bool": elastic.M{
"must": elastic.A{
{"multi_match": elastic.M{
"query": keywords,
"fields": []string{"title"}},
},
{"term": elastic.M{"isActive": true}},
},
},
},
"from": from,
"size": size,
}
if err = elastic.Init().Search(ESTable, &data, query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Search", table, "CommonSearch", err),
log.Any("keywords", keywords),
log.Any("from", from),
log.Any("size", size),
)
return
}
return
}
+145
View File
@@ -0,0 +1,145 @@
package audiobookmod
import (
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson/primitive"
)
var mdb *db.MongoDB
const (
ListenPermissionVIP = 0
ListenPermissionBuy = 1
ListenPermissionBuyZone = "付费专区"
)
type Content struct {
EpisodeNumber int `json:"episodeNumber" bson:"episodeNumber" ` //第几集
ListenPermission int `json:"listenPermission" bson:"listenPermission"` //收听权限 0:会员 1:金币购买 3:试听
Price int64 `json:"price" bson:"price"` //购买价格
Name string `json:"name" bson:"name"` //章节名
URL string `json:"contentUrl" bson:"contentUrl"` //资源地址
MediaSize int64 `json:"mediaSize" bson:"mediaSize"` //资源大小
IsBrought bool `json:"isBrought" bson:"-"` //是否购买
}
type AudioBook struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Title string `json:"title" bson:"title,omitempty"` //标题
Anchor string `json:"anchor" bson:"anchor"` //作者
Cover string `json:"cover" bson:"cover"` //封面
ContentSet []Content `json:"contentSet" bson:"contentSet"` //内容集
TotalEpisode int `json:"totalEpisode" bson:"totalEpisode"` //总集数
TrialSet []Content `json:"trialSet" bson:"trialSet"` //试听集
FType string `json:"fType" bson:"fType"` //小说类型
Summary string `json:"summary" bson:"summary"` //简介
IsActive bool `json:"isActive" bson:"isActive"` //是否激活
CountPurchases int64 `json:"countPurchases" bson:"countPurchases"` //购买数
CountBrowse int64 `json:"countBrowse" bson:"countBrowse"` //浏览数
CountCollect int64 `json:"countCollect" bson:"countCollect"` //收藏数
Number int64 `json:"number" bson:"number,omitempty"` //编号
CreatedAt time.Time `json:"createdAt" bson:"createdAt,omitempty"` //创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt,omitempty"` //修改时间
}
func Init() {
mdb = db.Init(table)
initIndex()
}
type QuerySelector struct {
ID *primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`
Title *string `json:"title,omitempty" bson:"title,omitempty"` //标题
Anchor *string `json:"anchor,omitempty" bson:"anchor,omitempty"` //作者
FType *string `json:"fType,omitempty" bson:"fType,omitempty"` //小说类型
IsActive *bool `json:"isActive,omitempty" bson:"isActive,omitempty"` //是否激活
Number *int `json:"number,omitempty" bson:"number,omitempty"` //编号
}
type EditSelector struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Title string `json:"title" bson:"title,omitempty"` //标题
Anchor string `json:"anchor" bson:"anchor"` //作者
Cover string `json:"cover" bson:"cover"` //封面
ContentSet []Content `json:"contentSet" bson:"contentSet"` //内容集
TotalEpisode int `json:"totalEpisode" bson:"totalEpisode"` //总集数
TrialSet []Content `json:"trialSet" bson:"trialSet"` //试听集
FType string `json:"fType" bson:"fType"` //小说类型
Summary string `json:"summary" bson:"summary"` //简介
IsActive bool `json:"isActive" bson:"isActive"` //是否激活
CountPurchases int64 `json:"countPurchases" bson:"countPurchases"` //购买数
CountBrowse int64 `json:"countBrowse" bson:"countBrowse"` //浏览数
CountCollect int64 `json:"countCollect" bson:"countCollect"` //收藏数
Number int `json:"number" bson:"number,omitempty"` //编号
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt,omitempty"` //修改时间
}
const RedisSetKey = "audiobook"
// todo app
type AudioBookAppRes struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Title string `json:"title" bson:"title,omitempty"` //标题
Anchor string `json:"-" bson:"anchor"` //作者
Cover string `json:"cover" bson:"cover"` //封面
ContentSet []Content `json:"contentSet" bson:"contentSet"` //内容集
TrialSet []Content `json:"trialSet" bson:"trialSet"` //试听集
FType string `json:"fType" bson:"fType"` //小说类型
Summary string `json:"summary" bson:"summary"` //简介
IsActive bool `json:"isActive" bson:"isActive"` //是否激活
TotalEpisode int `json:"totalEpisode" bson:"totalEpisode"` //总集数
CountPurchases int64 `json:"countPurchases" bson:"countPurchases"` //购买数
CountBrowse int64 `json:"countBrowse" bson:"countBrowse"` //浏览数
OriginalPrice int64 `json:"originalPrice" bson:"-"` //原价
DiscountPrice int64 `json:"discountPrice" bson:"-"` //优惠价(用户实际需要支付的价格)
}
type AudioBookBase struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Title string `json:"title" bson:"title,omitempty"` //标题
Anchor string `json:"anchor" bson:"anchor"` //作者
Cover string `json:"cover" bson:"cover"` //封面
TotalEpisode int `json:"totalEpisode" bson:"totalEpisode"` //总集数
TrialSet []Content `json:"trialSet" bson:"trialSet"` //试听集
FType string `json:"fType" bson:"fType"` //小说类型
Summary string `json:"summary" bson:"summary"` //简介
CountPurchases int64 `json:"countPurchases" bson:"countPurchases"` //购买数
CountBrowse int64 `json:"countBrowse" bson:"countBrowse"` //浏览数
ContentSet []struct {
EpisodeNumber int `json:"episodeNumber" bson:"episodeNumber" ` //第几集
ListenPermission int `json:"listenPermission" bson:"listenPermission"` //收听权限 0:会员 1:金币购买 3:试听
Price int64 `json:"price" bson:"price"` //购买价格
Name string `json:"name" bson:"name"` //章节名
MediaSize int64 `json:"mediaSize" bson:"mediaSize"` //资源大小
} `json:"contentSet" bson:"contentSet"`
}
type AudioBookUpsertEdit struct {
Title string `json:"title" bson:"title,omitempty"` //标题
Anchor string `json:"anchor" bson:"anchor"` //作者
Cover string `json:"cover" bson:"cover"` //封面
ContentSet []Content `json:"contentSet" bson:"-"` //内容集
TotalEpisode int `json:"totalEpisode" bson:"totalEpisode"` //总集数
TrialSet []Content `json:"trialSet" bson:"trialSet"` //试听集
FType string `json:"fType" bson:"fType"` //小说类型
Summary string `json:"summary" bson:"summary"` //简介
IsActive bool `json:"isActive" bson:"isActive"` //是否激活
Number int64 `json:"number" bson:"number,omitempty"` //编号
CreatedAt time.Time `json:"createdAt" bson:"createdAt,omitempty"` //创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt,omitempty"` //修改时间
}
type CountInc struct {
CountPurchases *int `json:"countPurchases" bson:"countPurchases,omitempty"` //购买数
CountBrowse *int `json:"countBrowse" bson:"countBrowse,omitempty"` //浏览数
CountCollect *int `json:"countCollect" bson:"countCollect,omitempty"` //收藏数
}
type ESAudioBookSource struct {
ID string `json:"_id"`
Source AudioBookBase `json:"_source"`
}
+131
View File
@@ -0,0 +1,131 @@
package authoritymod
import (
"fmt"
"time"
"91porn-server/common"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"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.Authority
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// initIndex 初始化索引
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "role", Value: 1}},
Options: options.Index().SetUnique(true),
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
// Insert 插入记录
func Insert(doc AuthorityDoc) error {
now := time.Now()
doc.CreatedAt = &now
doc.UpdatedAt = &now
if _, err := coll(nil).InsertOne(doc); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return err
}
return nil
}
// UpdateTo
func UpdateTo(id ObjectID, doc AuthorityDoc) error {
now := time.Now()
doc.UpdatedAt = &now
update, err := common.ToBsonM(doc)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateTo", table, "ToBsonM", err), log.Any("id", id))
return err
}
result, err := coll(nil).UpdateOne(M{"_id": id}, M{"$set": update})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateTo", table, "UpdateOne", err), log.Any("id", id), log.Any("update", update))
return err
}
if result.ModifiedCount+result.UpsertedCount != 1 {
return fmt.Errorf("coll:%s UpdateTo Count error, id:%+v update:%+v", table, id, update)
}
return nil
}
// DeleteMany DeleteMany
func DeleteMany(idArray []ObjectID) error {
if _, err := coll(nil).DeleteMany(M{"_id": M{"$in": idArray}}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteMany", table, "DeleteMany", err))
return err
}
return nil
}
func FindOne(doc AuthorityDoc) (authority Authority, err error) {
filter, err := common.ToBsonM(doc)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindOne", table, "ToBsonM", err))
return
}
if err = coll(nil).FindOne(&authority, filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FindOne", table, "FindOne", err))
}
return
}
func ExistsByID(id ObjectID) (existed bool, err error) {
filter := M{
"_id": id,
}
count, err := coll(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "ExistsByID", table, "Count", err))
return false, err
}
return count > 0, nil
}
// FineOneByRole 通过权限id获取权限json
func FineOneByRole(role string) (Authority, error) {
var auth Authority
if err := coll(nil).FindOne(&auth, bson.M{"role": role}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FineOneByRole", table, "FindOne", err), log.Any("role", role))
return Authority{}, err
}
return auth, nil
}
// IDMapByRoles role->id Map
func IDMapByRoles(roleArray []string) (map[string]ObjectID, error) {
filter := M{
"role": M{"$in": roleArray},
}
authArray := make([]Authority, 0, len(roleArray))
if err := coll(nil).Find(&authArray, filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IDMapByRoles", table, "Find", err), log.Any("roleArray", roleArray))
return nil, err
}
idMap := make(map[string]ObjectID, len(authArray))
for _, auth := range authArray {
idMap[auth.Role] = auth.ID
}
return idMap, nil
}
+40
View File
@@ -0,0 +1,40 @@
package authoritymod
import (
"fmt"
"91porn-server/common/log"
)
// AuthorPage AuthorPage
type AuthorPage struct {
Total int `json:"total" bson:"total"`
List []AuthorityDoc `json:"list" bson:"list"`
}
// AuthorPages AuthorPages
func AuthorPages(skip int64, limit int64) (page AuthorPage, err error) {
pipeline := []M{
M{
"$facet": M{
"total": A{M{"$count": "total"}},
"list": A{
M{"$sort": M{"role": 1}},
M{"$skip": skip},
M{"$limit": limit},
},
},
},
M{
"$project": M{
"total": M{"$arrayElemAt": A{"$total.total", 0}},
"list": 1,
},
},
}
if err = coll(nil).AggregateDecode(&page, pipeline); err != nil {
log.ZapLog.Error(fmt.Sprintf("coll:%s Page error:%+v:", table, err))
return
}
return
}
+48
View File
@@ -0,0 +1,48 @@
package authoritymod
import (
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type (
// M M from Map
M = bson.M
// D D from Doc
D = bson.D
// A A from Array
A = bson.A
// ObjectID ObjectID
ObjectID = primitive.ObjectID
// 用于记录权限配置
Authority struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Role string `json:"role" bson:"role"` //角色,映射到权限模型
AuthJson string `json:"authJson" bson:"authJson"` //"路由权限数据,json格式"
ActJson string `json:"actJson" bson:"actJson"` //"功能权限数据,json格式"
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"`
}
AuthorityDoc struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Role *string `json:"role" bson:"role,omitempty"` //角色,映射到权限模型
AuthJson *string `json:"authJson" bson:"authJson,omitempty" ` //"路由权限数据,json格式"
ActJson *string `json:"actJson" bson:"actJson,omitempty"` //"功能权限数据,json格式"
CreatedAt *time.Time `json:"createdAt,omitempty" bson:"createdAt,omitempty"`
UpdatedAt *time.Time `json:"updatedAt,omitempty" bson:"updatedAt,omitempty"`
}
)
func Init() {
mdb = db.Init(table)
initIndex()
}
+9
View File
@@ -0,0 +1,9 @@
package backpackmod
import "91porn-server/models/commod"
type QueryAllCond struct {
UID uint64
Status *GoodsStatus `form:"status" json:"status" binding:"required,min=1"` // 物品状态
commod.Page
}
+221
View File
@@ -0,0 +1,221 @@
package backpackmod
import (
"errors"
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const table = models.Backpack
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// Init 索引设置
func initIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{
{Key: "uid", Value: 1},
{Key: "status", Value: 1},
{Key: "createTimt", Value: -1},
},
},
{
Keys: bson.D{
{Key: "uid", Value: 1},
{Key: "status", Value: 1},
{Key: "useTime", Value: -1},
},
},
{
Keys: bson.D{
{Key: "uid", Value: 1},
{Key: "expiredTime", Value: -1},
},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("backpack model set index err ==>[%+v]", err))
}
}
// 获取个人拥有可用优惠卷列表
func GetCouponListByUID(uid uint64, goodsType int) ([]*Backpack, error) {
var out []*Backpack = make([]*Backpack, 0)
if err := coll(nil).Find(&out, bson.M{
"uid": uid,
"goodsType": goodsType,
"status": Unused,
"expiredTime": bson.M{"$gt": time.Now()},
}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCouponListByUID", models.Backpack, "Find", err),
log.Any("uid", uid),
log.Any("goodsType", goodsType),
)
return nil, err
}
return out, nil
}
// 添加物品到背包
func AddGoods(t *db.MongoTool, uid uint64, b ...Backpack) error {
for _, item := range b {
item.GoodsName = item.GoodsType.GetName()
item.GoodsDesc = item.GoodsType.GetDesc()
}
if _, err := coll(t).InsertMany(&b); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddGoods", models.Backpack, "InsertMany", err),
log.Any("uid", uid),
)
return err
}
return nil
}
// AddGoodsMany 添加物品到背包
func AddGoodsMany(t *db.MongoTool, uid uint64, b []Backpack) error {
if _, err := coll(t).InsertMany(&b); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddGoodsMany", models.Backpack, "InsertMany", err),
log.Any("uid", uid),
)
return err
}
return nil
}
// 使用物品
func UseGoods(t *db.MongoTool, id primitive.ObjectID) error {
result, err := coll(t).UpdateOne(bson.M{"_id": id}, bson.M{"$set": bson.M{"status": Used, "useTime": time.Now()}})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UseGoods", models.Backpack, "UpdateOne", err),
log.Any("id", id),
)
return err
}
if result.ModifiedCount == 0 {
err = errors.New("backpack UpdateOne ModifiedCount err")
log.Warn(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UseGoods", models.Backpack, "result.ModifiedCount == 0", err),
log.Any("id", id),
)
return err
}
return nil
}
// 查询背包列表
func GetCouponList(uid uint64, types, status int, limit, page int64) ([]*Backpack, error) {
var out []*Backpack = make([]*Backpack, 0)
cond := bson.M{"uid": uid}
sort := bson.M{}
switch GoodsStatus(status) {
case Used:
sort["useTime"] = -1
cond["status"] = status
case Unused:
cond["status"] = status
cond["expiredTime"] = bson.M{"$gt": time.Now()}
sort["createTime"] = 1
case Expired:
cond["expiredTime"] = bson.M{"$lte": time.Now()}
sort["expiredTime"] = -1
}
if types > 0 {
cond["goodsType"] = types
}
opts := options.Find().SetLimit(limit).SetSkip((page - 1) * limit).SetSort(sort)
if err := coll(nil).Find(&out, cond, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetGoodsList", models.Backpack, "Find", err),
log.Any("uid", uid),
)
return nil, err
}
return out, nil
}
// 获取物品信息
func GetGoodsDetail(id primitive.ObjectID) (*Backpack, error) {
var out *Backpack
if err := coll(nil).FindOne(&out, bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetGoodsDetail", models.Backpack, "FindOne", err),
log.Any("id", id),
)
return nil, err
}
return out, nil
}
// 根据id获取券信息
// 如果未找到, 返回nil
func GetByID(t *db.MongoTool, id primitive.ObjectID) (*Backpack, error) {
var bp Backpack
if err := coll(t).FindOne(&bp, bson.M{"_id": id}); err != nil {
return nil, err
}
if bp.ID != id {
return nil, nil
}
return &bp, nil
}
// UseManyGoods 使用物品(多件)
func UseManyGoods(t *db.MongoTool, ids []primitive.ObjectID) (int64, error) {
filter := bson.M{"_id": bson.M{"$in": ids}, "status": Unused}
result, err := coll(t).UpdateMany(filter, bson.M{"$set": bson.M{"status": Used, "useTime": time.Now()}})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UseManyGoods", models.Backpack, "UpdateOne", err),
log.Any("id", ids),
)
return 0, err
}
return result.ModifiedCount, nil
}
// UnuseManyGoods 退换物品(多件)
func UnuseManyGoods(t *db.MongoTool, ids []primitive.ObjectID) (int64, error) {
result, err := coll(t).UpdateMany(bson.M{"_id": bson.M{"$in": ids}, "status": Used}, bson.M{"$set": bson.M{"status": Unused}})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UseManyGoods", models.Backpack, "UpdateOne", err),
log.Any("id", ids),
)
return 0, err
}
return result.ModifiedCount, nil
}
// QueryAllList 分页查询文档
func QueryAllList(filter primitive.M, opts ...*options.FindOptions) (out []*Backpack, err error) {
if err = coll(nil).Find(&out, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllList", table, "Find", err),
log.Any("filter", filter),
log.Any("opts", opts),
)
return nil, err
}
return
}
// QueryAllCount 查询文档条目数
func QueryAllCount(filter primitive.M) (int64, error) {
if count, err := coll(nil).Count(filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "QueryAllCount", table, "Count", err),
log.Any("filter", filter),
)
return 0, err
} else {
return count, nil
}
}
+76
View File
@@ -0,0 +1,76 @@
package backpackmod
import (
"time"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson/primitive"
)
var mdb *db.MongoDB
var itemNames = map[GoodsType]string{
LouFengUnLock: "楼风解锁折扣卷",
VIPDiscount: "会员折扣卷",
AiChangeFaceDiscount: "AI换脸折扣券",
GoldBonusCoupon: "金币加赠券",
ExchangeCoupon: "兑换码观影券",
SIGNCoupon: "签到赠观影券",
}
var itemDesc = map[GoodsType]string{
LouFengUnLock: "楼风解锁专享折扣",
VIPDiscount: "购买会员专享折扣",
AiChangeFaceDiscount: "AI换脸专享折扣",
GoldBonusCoupon: "充值加送金币",
ExchangeCoupon: "兑换码观影券",
SIGNCoupon: "签到赠观影券",
}
type GoodsType int
const (
LouFengUnLock GoodsType = 1 // 1、楼风解锁折扣卷
VIPDiscount GoodsType = 2 // 2、会员折扣卷
AiChangeFaceDiscount GoodsType = 3 // 3、AI换脸折扣券
GameCode GoodsType = 4 // 4、游戏码
GoldBonusCoupon GoodsType = 5 // 5、金币加赠券(用于购买金币时额外赠送额度)
ExchangeCoupon GoodsType = 6 // 6、兑换赠观影券
SIGNCoupon GoodsType = 7 // 7、签到赠观影券
)
func (t GoodsType) GetName() string {
return itemNames[t]
}
func (t GoodsType) GetDesc() string {
return itemDesc[t]
}
type GoodsStatus int
const (
Used GoodsStatus = iota + 1 // 已使用
Unused // 未使用
Expired // 过期
)
type Backpack struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档ID
UID uint64 `json:"uid" bson:"uid"` // 用户ID
GoodsName string `json:"goodsName" bson:"goodsName"` // 物品名称
GoodsType GoodsType `json:"goodsType" bson:"goodsType"` // 物品类型
GoodsValue int64 `json:"goodsValue" bson:"goodsValue"` // 物品价值
GoodsOrigin string `json:"goodsOrigin" bson:"goodsOrigin"` // 物品来源
GoodsDesc string `json:"goodsDesc" bson:"goodsDesc"` // 物品描述
Status GoodsStatus `json:"status" bson:"status"` // 物品状态
ExpiredTime time.Time `json:"expiredTime" bson:"expiredTime"` // 物品过期时间
UseTime time.Time `json:"useTime" bson:"useTime"` // 物品使用时间
CreateTime time.Time `json:"createTime" bson:"createTime"` // 创建时间
}
func Init() {
mdb = db.Init(models.Backpack)
initIndex()
}
+41
View File
@@ -0,0 +1,41 @@
package backpackmod
import (
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
type QueryAllWebCond struct {
Page int64 `form:"page" binding:"required"`
Limit int64 `form:"limit" binding:"required"`
Uid *int `form:"uid"` // 用户ID
Status *int `form:"status"` // 使用状态 1、已使用 2、未使用 3、过期
GoodsType *int `form:"goodsType"` // 类型
GoodsDesc *string `form:"goodsDesc"` // 描述
}
type QueryAllRes struct {
List []*Backpack `json:"list"`
Total int64 `json:"total"`
}
func (receiver *QueryAllWebCond) Filter() bson.M {
var query = bson.M{}
if receiver.Uid != nil {
query["uid"] = receiver.Uid
}
if receiver.GoodsType != nil {
query["goodsType"] = receiver.GoodsType
}
if receiver.GoodsDesc != nil {
query["goodsDesc"] = receiver.GoodsDesc
}
if receiver.Status != nil {
query["status"] = receiver.Status
}
return query
}
func (receiver QueryAllWebCond) Options() *options.FindOptions {
return options.Find().SetSkip((receiver.Page - 1) * receiver.Limit).SetLimit(receiver.Limit).SetSort(bson.D{{"createTime", -1}})
}
+19
View File
@@ -0,0 +1,19 @@
package bannerjumpmod
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// BannerJumpInfo 移动端返回内容
type BannerJumpInfo struct {
ID primitive.ObjectID `json:"id"` // 浮窗ID
Position Position `json:"position"` // 位置 1-视频播放器下方 2-收益页 3-首页浮窗
Banner string `json:"banner"` // BANNER图片
Title string `json:"title"` // 标题
Url string `json:"url"` // 跳转地址
StartAt time.Time `json:"startAt"` // 开始时间;CountdownType=1 时为红包雨场次开始时间,否则为 banner 自身开始时间
EndAt time.Time `json:"endAt"` // 结束时间;CountdownType=1 时为红包雨场次结束时间,否则为 banner 自身结束时间
CountdownType int `json:"countdownType"` // 倒计时类型 0-无 1-红包雨倒计时
}
+130
View File
@@ -0,0 +1,130 @@
package bannerjumpmod
import (
"encoding/json"
"errors"
"fmt"
"91porn-server/common/db"
"91porn-server/common/log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// GetList 获取列表
func GetList(cond bson.M, skip, limit int64, sort bson.D) (res []BannerJump, count int64, hasNext bool, err error) {
count, err = coll(nil).Count(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetList", table, "Count", err),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("cond", cond),
log.Any("sort", sort),
)
return
}
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort).SetSkip(skip).SetLimit(limit + 1)
if err = coll(nil).Find(&res, cond, opts); err != nil {
return
}
// 判断下一页
if len(res) > int(limit) {
hasNext = true
res = res[:limit]
}
return
}
// GetAll 查询全部文档
func GetAll(filter primitive.M, sort bson.D) (out []*BannerJump, err error) {
if len(sort) == 0 {
sort = bson.D{{Key: "_id", Value: -1}}
}
opts := options.Find().SetSort(sort)
if err = coll(nil).Find(&out, filter, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAll", table, "Find", err),
log.Any("filter", filter),
log.Any("opts", opts),
)
return nil, err
}
return
}
// GetInfo 通过id获取详细信息
func GetInfo(id primitive.ObjectID) (BannerJump, error) {
v := BannerJump{}
if err := coll(nil).FindOne(&v, bson.M{"_id": id}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetInfo", table, "FindOne", err),
log.Any("id", id),
)
return v, err
}
if v.ID.IsZero() {
return v, errors.New("record not found")
}
return v, nil
}
// Insert 插入记录
func Insert(t *db.MongoTool, d BannerJump) (data primitive.ObjectID, err error) {
result, err := coll(t).InsertOne(&d)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return
}
byteID, err := json.Marshal(result.InsertedID)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "Marshal", err))
return
}
if err = data.UnmarshalJSON(byteID); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "UnmarshalJSON", err))
return
}
return
}
// UpdateByID 根据id更新数据
func UpdateByID(t *db.MongoTool, id primitive.ObjectID, data map[string]interface{}) (int64, error) {
cond := bson.M{"_id": id}
return update(t, cond, data)
}
// update 更新数据
func update(t *db.MongoTool, cond primitive.M, data map[string]interface{}) (int64, error) {
result, err := coll(t).UpdateMany(cond, bson.M{"$set": bson.M(data)})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateMany", err),
log.Any("cond", cond),
log.Any("update", data),
)
return 0, err
}
return result.ModifiedCount, nil
}
// DeleteByID 删除数据
func DeleteByID(t *db.MongoTool, id primitive.ObjectID) error {
_, err := coll(t).DeleteMany(bson.M{"_id": id})
if err != nil {
if err == mongo.ErrNoDocuments {
return nil
} else {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteByID", table, "DeleteMany", err), log.Any("id", id))
}
}
return err
}
+62
View File
@@ -0,0 +1,62 @@
package bannerjumpmod
import (
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
var mdb *db.MongoDB
const table = models.BannerJump
type Position = int
const (
VideoPlayer Position = 1 // 视频播放器下翻跳转banner
UsersProxy Position = 2 // 全民代理页面页面banner
)
type BannerJump struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // 文档id
Position Position `json:"position" bson:"position"` // 位置 1-视频播放器下方 2-收益页 3-首页浮窗
Banner string `json:"banner" bson:"banner"` // BANNER图片
Title string `json:"title" bson:"title"` // 标题
Url string `json:"url" bson:"url"` // 跳转地址
StartAt time.Time `json:"startAt" bson:"startAt"` // 开始时间
EndAt time.Time `json:"endAt" bson:"endAt"` // 结束时间
Weight int `json:"weight" bson:"weight"` // 权重
Enable bool `json:"enable" bson:"enable"` // 是否启用
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` // 更新时间
}
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// Init 初始化索引
func Init() {
mdb = db.Init(table)
initIndex()
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "startAt", Value: 1}, {Key: "endAt", Value: 1}, {Key: "enable", Value: 1}, {Key: "weight", Value: -1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
+98
View File
@@ -0,0 +1,98 @@
package chatrobotmod
import (
"fmt"
"91porn-server/common"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"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.ChatRobot
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// initCommentIndex 设置index
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "type", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "isActive", Value: 1}},
},
{
Keys: bson.D{{Key: "updatedAt", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func Insert(doc ChatRobot) error {
if _, err := coll(nil).InsertOne(doc); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
return err
}
return nil
}
func ConfExists(rType EnumRobotType) (isExists bool, err error) {
if isExists, err = coll(nil).Exists(bson.M{"type": rType}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "ConfExists", table, "Exists", err), log.Any("rType", rType))
return
}
return
}
func GetRobotConfByType(rType EnumRobotType) (data ChatRobot, err error) {
if err = coll(nil).FindOne(&data, bson.M{"type": rType}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetRobotConfByType", table, "FindOne", err), log.Any("rType", rType))
return
}
return
}
func GetRobotConf(rType *EnumRobotType, skip int64, limit int64) (total int64, data []ChatRobot, err error) {
var query = bson.M{}
if rType != nil {
query["type"] = *rType
}
var opts = options.Find()
opts.SetSkip(skip).SetLimit(limit)
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetRobotConf", table, "Find", err), log.Any("rType", rType))
return
}
if total, err = coll(nil).Count(query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetRobotConf", table, "Count", err), log.Any("rType", rType))
return
}
return
}
func UpdateCmtRobotConf(rType EnumRobotType, doc CmtUpdateDoc) (err error) {
var update, _ = common.ToBsonM(doc)
if _, err = coll(nil).UpdateOne(bson.M{"type": rType}, bson.M{"$set": update}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpdateCmtRobotConf", table, "UpdateOne", err),
log.Any("rType", rType),
log.Any("update", update),
)
return
}
return
}
+63
View File
@@ -0,0 +1,63 @@
package chatrobotmod
import (
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type (
ObjectID = primitive.ObjectID
EnumRobotType = string // 机器人类型枚举
)
const (
Comment EnumRobotType = "COMMENT" // 评论机器人
Film EnumRobotType = "FILM" // 影院机器人
)
func Init() {
mdb = db.Init(table)
initIndex()
}
type ChatRobot struct {
ID ObjectID `bson:"_id,omitempty"`
Type EnumRobotType `bson:"type"` // 机器人类型
IsActive bool `bson:"isActive"` // 是否开启
CreatedAt time.Time `bson:"createdAt"` // 创建时间
UpdatedAt time.Time `bson:"updatedAt"` // 更新时间
CommentRobot `bson:",inline"` // 评论机器人配置
}
// 评论机器人配置
type CommentRobot struct {
From string `bson:"from,omitempty"` // 每天的起始时间 HH:MM:SS
To string `bson:"to,omitempty"` // 每天的结束时间 HH:MM:SS
TotalLimit int `bson:"totalLimit,omitempty"` // 机器人每天总评论数
PureLimit int `bson:"pureLimit,omitempty"` // 单个机器人每天评论数
Frequency int `bson:"frequency"` // 发表评论频率 单位:秒/条
MaxCommentNum int `bson:"maxCommentNum"` // 视频评论最小数
MaxFakeLikes int `bson:"maxFakeLikes"` // 视频点赞数最大值
MinFakeLikes int `bson:"minFakeLikes"` // 视频点赞数最小值
MaxFakePlayCount int `bson:"maxFakePlayCount"` // 视频播放量最大值
MinFakePlayCount int `bson:"minFakePlayCount"` // 视频播放量最小值
}
// 评论机器人配置更新
type CmtUpdateDoc struct {
From *string `bson:"from,omitempty"`
To *string `bson:"to,omitempty"`
TotalLimit *int `bson:"totalLimit,omitempty"`
PureLimit *int `bson:"pureLimit,omitempty"`
IsActive *bool `bson:"isActive,omitempty"`
Frequency *int `bson:"frequency"`
UpdatedAt time.Time `bson:"updatedAt"`
MaxCommentNum *int `bson:"maxCommentNum"`
MaxFakeLikes *int `bson:"maxFakeLikes"` // 视频点赞数最大值
MinFakeLikes *int `bson:"minFakeLikes"` // 视频点赞数最小值
MaxFakePlayCount *int `bson:"maxFakePlayCount"` // 视频播放量最大值
MinFakePlayCount *int `bson:"minFakePlayCount"` // 视频播放量最小值
}
+74
View File
@@ -0,0 +1,74 @@
package chatrobotmod
import (
"time"
"91porn-server/models/commod"
)
type ReqConfList struct {
Type *string `form:"type" json:"type"`
commod.Page
}
type RespList struct {
ID ObjectID `json:"id"`
Type EnumRobotType `json:"type"` // 机器人类型
IsActive bool `json:"isActive"` // 是否开启
CreatedAt time.Time `json:"createdAt"` // 创建时间
UpdatedAt time.Time `json:"updatedAt"` // 更新时间
CommentRobotResp `json:",inline"`
}
type CommentRobotResp struct {
From string `json:"from"` // 每天的起始时间 HH:MM:SS
To string `json:"to"` // 每天的结束时间 HH:MM:SS
TotalLimit int `json:"totalLimit"` // 机器人每天总评论数
PureLimit int `json:"pureLimit"` // 单个机器人每天评论数
Frequency int `json:"frequency"` // 发表评论频率 单位:秒/条
MaxCommentNum int `json:"maxCommentNum"` // 参与评论视频的最大评论数
MaxFakeLikes int `json:"maxFakeLikes"` // 视频点赞数最大值
MinFakeLikes int `json:"minFakeLikes"` // 视频点赞数最小值
MaxFakePlayCount int `json:"maxFakePlayCount"` // 视频播放量最大值
MinFakePlayCount int `json:"minFakePlayCount"` // 视频播放量最小值
}
type ReqUpdate struct {
Type EnumRobotType `json:"type" binding:"required"`
ReqUpdateCmt // 评论机器人配置更新请求参数
}
// 评论机器人配置更新请求参数
type ReqUpdateCmt struct {
From *string `json:"from"`
To *string `json:"to"`
TotalLimit *int `json:"totalLimit"`
PureLimit *int `json:"pureLimit"`
Frequency *int `json:"frequency"`
IsActive *bool `json:"isActive"`
MaxCommentNum *int `json:"maxCommentNum"`
MaxFakeLikes *int `json:"maxFakeLikes"` // 视频点赞数最大值
MinFakeLikes *int `json:"minFakeLikes"` // 视频点赞数最小值
MaxFakePlayCount *int `json:"maxFakePlayCount"` // 视频播放量最大值
MinFakePlayCount *int `json:"minFakePlayCount"` // 视频播放量最小值
}
// 添加配置
type ReqAdd struct {
Type EnumRobotType `json:"type" binding:"required"`
ReqAddCmt
}
type ReqAddCmt struct {
From string `json:"from"`
To string `json:"to"`
TotalLimit int `json:"totalLimit"`
PureLimit int `json:"pureLimit"`
Frequency int `json:"frequency"`
IsActive bool `json:"isActive"`
MaxCommentNum int `json:"maxCommentNum"`
MaxFakeLikes int `json:"maxFakeLikes"` // 视频点赞数最大值
MinFakeLikes int `json:"minFakeLikes"` // 视频点赞数最小值
MaxFakePlayCount int `json:"maxFakePlayCount"` // 视频播放量最大值
MinFakePlayCount int `json:"minFakePlayCount"` // 视频播放量最小值
}
@@ -0,0 +1,83 @@
package checkinconfigmod
import (
"fmt"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
const table = models.CheckinConfig
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "enable", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func Init() {
mdb = db.Init(table)
initIndex()
}
// FindOne 查找签到配置
func FindOne(filter primitive.M) (*CheckinConfig, error) {
var config CheckinConfig
if err := coll(nil).FindOne(&config, filter); err != nil {
log.Error(fmt.Sprintf("[checkinconfigmod:FindOne] failed: %+v", err))
return nil, err
}
if config.ID.IsZero() {
return nil, nil
}
return &config, nil
}
// UpdateOne 更新签到配置
func UpdateOne(filter primitive.M, update primitive.M) error {
result, err := coll(nil).UpdateOne(filter, update)
if err != nil {
log.Error(fmt.Sprintf("[checkinconfigmod:UpdateOne] failed: %+v", err))
return err
}
if result.MatchedCount == 0 {
return mongo.ErrNoDocuments
}
return nil
}
// InsertOne 插入签到配置
func InsertOne(config *CheckinConfig) error {
if _, err := coll(nil).InsertOne(config); err != nil {
log.Error(fmt.Sprintf("[checkinconfigmod:InsertOne] failed: %+v", err))
return err
}
return nil
}
// Count 统计数量
func Count(filter primitive.M) (int64, error) {
count, err := coll(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[checkinconfigmod:Count] failed: %+v", err))
return 0, err
}
return count, nil
}
+33
View File
@@ -0,0 +1,33 @@
package checkinconfigmod
import (
"91porn-server/common/db"
"91porn-server/models/v/prizemod"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const CheckinConfigId = "checkin_config_1"
type CheckinConfig struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Enable bool `json:"enable" bson:"enable"` // 是否启用
Description string `json:"description" bson:"description"` // 规则说明
BackgroundImage string `json:"backgroundImage" bson:"backgroundImage"` // 背景图片
RewardBgVideos []RewardBgVideo `json:"rewardBgVideos" bson:"rewardBgVideos"` // 奖励播放媒体地址
IntegerExchangeList []GiftItem `json:"integerExchangeList" bson:"integerExchangeList"` // 积分可兑换豪礼列表
}
type GiftItem struct {
Name string `json:"name" bson:"name"`
Icon string `json:"icon" bson:"icon"`
}
type RewardBgVideo struct {
PrizeType prizemod.PrizeType `json:"prizeType" bson:"prizeType"` // 奖品类型
BgMediaUrl string `json:"bgMediaUrl" bson:"bgMediaUrl"` // 奖励背景动画
FsResourceStatus string `json:"fsResourceStatus" bson:"fsResourceStatus"` // 视频文件切片状态
FsResourceId string `json:"fsResourceId" bson:"fsResourceId"` // 文件服id
}
var mdb *db.MongoDB
+116
View File
@@ -0,0 +1,116 @@
package checkinprizemod
import (
"fmt"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const table = models.CheckinPrize
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "status", Value: 1}, {Key: "checkinType", Value: 1}, {Key: "checkinDays", Value: 1}},
},
{
Keys: bson.D{{Key: "checkinDays", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func Init() {
mdb = db.Init(table)
initIndex()
}
// InsertOne 插入一个签到奖品
func InsertOne(data *CheckinPrize) error {
if _, err := coll(nil).InsertOne(data); err != nil {
log.Error(fmt.Sprintf("[checkinprizemod:InsertOne] failed: %+v", err))
return err
}
return nil
}
// FindMany 查找一批签到奖品
func FindMany(filter primitive.M, opts ...*options.FindOptions) (CheckinPrizeList, error) {
data := make(CheckinPrizeList, 0)
if err := coll(nil).Find(&data, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[checkinprizemod:FindMany] failed: %+v", err))
return nil, err
}
return data, nil
}
// FindManyWithBind 用自定义结构查找
func FindManyWithBind(bind interface{}, filter primitive.M, opts ...*options.FindOptions) error {
if err := coll(nil).Find(bind, filter, opts...); err != nil {
log.Error(fmt.Sprintf("[checkinprizemod:FindManyWithBind] failed: %+v", err))
return err
}
return nil
}
// FindOne 查找一个签到奖品
func FindOne(filter primitive.M) (*CheckinPrize, error) {
var data CheckinPrize
if err := coll(nil).FindOne(&data, filter); err != nil {
log.Error(fmt.Sprintf("[checkinprizemod:FindOne] failed: %+v", err))
return nil, err
}
if data.ID.IsZero() {
return nil, nil
}
return &data, nil
}
// Count 统计数量
func Count(filter primitive.M) (int64, error) {
count, err := coll(nil).Count(filter)
if err != nil {
log.Error(fmt.Sprintf("[checkinprizemod:Count] failed: %+v", err))
return 0, err
}
return count, nil
}
// UpdateOne 更新一个签到奖品
func UpdateOne(filter primitive.M, update primitive.M) error {
result, err := coll(nil).UpdateOne(filter, update)
if err != nil {
log.Error(fmt.Sprintf("[checkinprizemod:UpdateOne] failed: %+v", err))
return err
}
if result.MatchedCount == 0 {
return mongo.ErrNoDocuments
}
return nil
}
// DeleteOne 删除一个签到奖品
func DeleteOne(filter primitive.M) (int64, error) {
result, err := coll(nil).DeleteOne(filter)
if err != nil {
log.Error(fmt.Sprintf("[checkinprizemod:DeleteOne] failed: %+v", err))
return 0, err
}
return result.DeletedCount, nil
}
+47
View File
@@ -0,0 +1,47 @@
package checkinprizemod
import (
"fmt"
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type CheckinType int64
const (
CheckinTypeNone CheckinType = 0 // 占位符,无意义
CheckinTypeContinuously CheckinType = 1 // 连续签到
CheckinTypeCumulative CheckinType = 2 // 累计签到
)
type CheckinPrize struct {
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` // ID
Title string `json:"title" bson:"title"` // 标题
Image string `json:"image" bson:"image"` // 图片
CheckinDays int64 `json:"checkinDays" bson:"checkinDays"` // 签到天数
CheckinType CheckinType `json:"checkinType" bson:"checkinType"` // 签到类型
PrizeId primitive.ObjectID `json:"prizeId" bson:"prizeId"` // 奖品ID(关联activity_prize
PrizeName string `json:"prizeName" bson:"prizeName"` // 奖品名称
Status bool `json:"status" bson:"status"` // 状态
BigPrize bool `json:"bigPrize" bson:"bigPrize"` // 是否VIP奖励
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"`
}
func (s *CheckinPrize) Desc() string {
msg := ""
if s.CheckinType == CheckinTypeContinuously {
msg += "连续"
} else if s.CheckinType == CheckinTypeCumulative {
msg += "累计"
}
msg += fmt.Sprintf("签到%d天", s.CheckinDays)
return msg
}
type CheckinPrizeList []*CheckinPrize
var mdb *db.MongoDB
+149
View File
@@ -0,0 +1,149 @@
package cmtmod
type ComicsTitlePullReq struct {
PageNum int64 `form:"pageNum" json:"pageNum"`
PageSize int64 `form:"pageSize" json:"pageSize"`
TagId string `form:"tagId" json:"tagId"`
}
type ComicsTitlePullResp struct {
List []ComicsTitleInfo `json:"list"`
}
type ComicsTitleInfo struct {
Id string `json:"id"`
Title string `json:"title"`
}
type ComicsTitlePushReq struct {
TagId string `json:"tagId"`
List []ComicsTitlePushInfo `json:"list"`
}
type ComicsTitlePushInfo struct {
Id string `json:"id"`
Title string `json:"title"`
}
type ComicsTitlePushRes struct{}
type PullReq struct {
AppId string `form:"appId" json:"appId" binding:"required"` //应用标识,与平台配置一致
Sign string `form:"sign" json:"sign" binding:"required"` //签名
Limit int `form:"limit" json:"limit" binding:"omitempty"` //单次拉取数量,默认 20,最大 100
Status string `form:"status" json:"status" binding:"omitempty"` //评论状态,固定传 "pending"
}
type PullResp struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data []PullComment `json:"data"`
}
type PullComment struct {
Id string `json:"id"` //评论唯一 ID
UserId string `json:"user_id"` //发布者用户 ID
Nickname string `json:"nickname"` //发布者昵称
Content string `json:"content"` //评论正文
CreatedAt string `json:"created_at"` //发布时间,ISO 8601 格式
Ip string `json:"ip"` //发布者 IP
Context Context `json:"context"` //评论正文
}
type Context struct {
ContentType int `json:"content_type"` //帖子类型 1=帖子 2=视频 3=漫画
ContentId string `json:"content_id"` //所属内容业务 ID
ContentTitle string `json:"content_title"` //所属内容标题
}
type ApproveReq struct {
Reviews []Review `json:"reviews"`
}
type AppIdJson struct {
AppId string `form:"appId" json:"appId"`
}
type Review struct {
CommentId string `form:"comment_id" json:"comment_id" binding:"omitempty"` //评论 ID,与拉取接口返回的 id 一致
Action string `form:"action" json:"action" binding:"omitempty" ` //审核动作:approve 通过,reject 拒绝
Category string `form:"category" json:"category" binding:"omitempty"` //拒绝原因简述
Reason string `form:"reason" json:"reason" binding:"omitempty"` //违规类别:abuse/politics/ad/spam/competitor/foreign/link/complaint/minor
}
type RepliesReq struct {
Replies []ReplyReq `json:"replies"`
}
type ReplyReq struct {
CommentId string `form:"comment_id" json:"comment_id" binding:"omitempty"` //被回复评论的id
Content string `form:"content" json:"content" binding:"omitempty"` // 被回复评论的内容
}
type ReplyResp struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
type SignBody struct {
AppID string `json:"appId" binding:"required"`
Sign string `json:"sign" binding:"required"`
}
type VideoCommentSubmitReq struct {
AppID string `json:"appId" binding:"required"`
Sign string `json:"sign" binding:"required"`
Videos []VideoCommentItem `json:"videos" binding:"required"`
}
type VideoCommentItem struct {
VideoID string `json:"videoId" binding:"required"`
Title string `json:"title" binding:"required"`
Tags []string `json:"tags,omitempty"`
Description string `json:"description,omitempty"`
Subtitle string `json:"subtitle,omitempty"`
CommentCount int `json:"commentCount" binding:"required"`
}
type VideoCommentSubmitResp struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data VideoCommentSubmitRespData `json:"data"`
}
type VideoCommentSubmitRespData struct {
Results []VideoCommentSubmitResult `json:"results"`
}
type VideoCommentSubmitResult struct {
ID string `json:"id"`
VideoID string `json:"videoId"`
}
type VideoCommentResultReq struct {
AppID string `json:"appId" binding:"required"`
Sign string `json:"sign" binding:"required"`
IDs []string `json:"ids" binding:"required"`
}
type VideoCommentResultResp struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data VideoCommentResultRespData `json:"data"`
}
type VideoCommentResultRespData struct {
Results []VideoCommentResultItem `json:"results"`
}
type VideoCommentResultItem struct {
ID string `json:"id"`
VideoID string `json:"videoId"`
Comments []GeneratedVideoComment `json:"comments"`
ErrorMsg string `json:"errorMsg,omitempty"`
}
type GeneratedVideoComment struct {
Type string `json:"type"`
Text string `json:"text"`
}
+173
View File
@@ -0,0 +1,173 @@
package cmtmod
import (
"91porn-server/models/v/usermod"
"go.mongodb.org/mongo-driver/bson/primitive"
"time"
)
// ParentRespList 列表响应信息(父评论)
type ParentRespList struct {
//全局唯一评论ID
ID string `form:"id" json:"id"`
//评论对象的ID
ObjID string `form:"objID" json:"objID"`
//发表评论的 用户ID
UserID uint64 `form:"userID" json:"userID"`
//发表评论的 用户昵称
UserName string `form:"userName" json:"userName"`
//头像 URL
UserPortrait string `form:"userPortrait" json:"userPortrait" `
//评论内容
Content string `form:"content" json:"content"`
Image string `form:"image" json:"image"`
LinkStr string `form:"linkStr" json:"linkStr" bson:"linkStr"` //跳转配置
LinkType int `form:"linkType" json:"linkType"` //1:内链,2:外链
SearchKeyword string `form:"searchKeyword" json:"searchKeyword"` //搜索关键字
//此评论点赞次数
LikeCount int `form:"likeCount" json:"likeCount"`
//此评论的评论数
CommCount int `form:"commCount" json:"commCount"`
//此评论的评论数,冗余
CommCountBurden int `form:"commCountBurden" json:"commCountBurden"`
//是否是作者
IsAuthor bool `form:"isAuthor" json:"isAuthor" `
//是否点过赞
IsLike bool `form:"isLike" json:"isLike"`
//评论者是否已关注
IsFollow bool `form:"isFollow" json:"isFollow"`
//是否已删除
IsDelete bool `form:"isDelete" json:"isDelete"`
IsGodComment bool `form:"isGodComment" json:"isGodComment"` //是否是神评论
//性别
Gender string `form:"gender" json:"gender"`
//此评论的状态
Status int `form:"status" json:"status"`
//评论地点
City string `form:"city" json:"city"`
//评论时间
CreatedAt time.Time `form:"createdAt" json:"createdAt"`
//年龄
Age int `json:"age"`
// 引用类型 vid视频 col用户播单 sec官方播单 cover图集
QuoteType string `json:"quoteType"`
// 引用id
QuoteID ObjectID `json:"quoteID"`
// 引用资源图片
QuoteImg string `json:"quoteImg"`
// 引用资源标题
QuoteTitle string `json:"quoteTitle"`
//用户vip等级
Level int `json:"level"`
VipLevel int `json:"vipLevel"`
Awards []int `json:"awards"` //用户奖章
AwardsExpire []usermod.AwardsExpireResp `json:"awardsExpire" bson:"awardsExpire"` //奖章是否有效
SuperUser bool `json:"superUser" bson:"superUser"` //是否大V
VipExpireDate time.Time `json:"vipExpireDate" bson:"vipExpireDate"`
Info []ChildRespList
}
// ChildRespList 列表响应信息(子评论)
type ChildRespList struct {
ID string `form:"id" json:"id"` //全局唯一评论ID
ObjID string `form:"objID" json:"objID"` //评论对象的ID
CID string `form:"cid" json:"cid"` //评论的id
UserID uint64 `form:"userID" json:"userID"` //发表评论的 用户ID
UserName string `form:"userName" json:"userName"` //发表评论的 用户昵称
UserPortrait string `form:"userPortrait" json:"userPortrait"` //头像 URL
ToUserID uint64 `form:"toUserID" json:"toUserID"` //对某用户回复评论 用户ID
ToUserName string `form:"toUserName" json:"toUserName"` //对某用户回复评论 用户昵称
Content string `form:"content" json:"content"` //评论内容
Image string `form:"image" json:"image"`
LinkStr string `form:"linkStr" json:"linkStr" bson:"linkStr"` //跳转配置
LikeCount int `form:"likeCount" json:"likeCount"` //此评论点赞次数
IsLike bool `form:"isLike" json:"isLike"` //是否点过赞
IsAuthor bool `form:"isAuthor" json:"isAuthor"` //是否是作者
IsFollow bool `form:"isFollow" json:"isFollow"` //评论者是否已关注
IsDelete bool `form:"isDelete" json:"isDelete"` //是否已删除
Gender string `form:"gender" json:"gender"` //性别
Status int `form:"status" json:"status"` //此评论的状态
City string `form:"city" json:"city"` //评论地点
QuoteType string `json:"quoteType"` // 引用类型 vid视频 col用户播单 sec官方播单
QuoteID ObjectID `json:"quoteID"` // 引用id
QuoteImg string `json:"quoteImg"` // 引用资源图片
QuoteTitle string `json:"quoteTitle"` // 引用资源标题
CreatedAt time.Time `form:"createdAt" json:"createdAt"` //评论时间
Age int `json:"age"` //年龄
Level int `json:"level"` //用户评论层级 1:一级评论 2:二级评论
VipLevel int `json:"vipLevel"` //用户vip等级
Awards []int `json:"awards"` //用户奖章
AwardsExpire []usermod.AwardsExpireResp `json:"awardsExpire" bson:"awardsExpire"` //奖章是否有效
SuperUser bool `json:"superUser" bson:"superUser"` //是否大V
VipExpireDate time.Time `json:"vipExpireDate" bson:"vipExpireDate"`
}
type PublishReqInfo struct {
ObjID ObjectID `form:"objID" json:"objID"` // 评论对象的ID
ObjType string `form:"objType" json:"objType"` // 评论对象类型 video:视频(默认) cartoon:动漫 AiPlaza:ai广场
CID string `form:"cid" json:"cid"` // 此评论是对某条评论的评论或回复,如果为空,则为对该视频的评论
RID string `form:"rid" json:"rid"` // 被回复评论的id
ToUserID uint64 `form:"toUserID" json:"toUserID"` // 对某用户回复评论 用户ID
Content string `form:"content" json:"content"` // 评论内容
Level int `form:"level" json:"level"` // 评论层级 1:一级评论 2:二级评论
Image string `json:"image" form:"image"` // 图片
QuoteType string `form:"quoteType" json:"quoteType"` // 引用类型 vid视频 col用户播单 sec官方播单 cover图集
QuoteID ObjectID `form:"quoteID" json:"quoteID"` // 引用id
QuoteImg string `form:"quoteImg" json:"quoteImg"` // 引用资源图片
QuoteTitle string `form:"quoteTitle" json:"quoteTitle"` // 引用资源标题
}
// CmtRespList 列表响应信息
type CmtRespList struct {
//全局唯一评论ID
ID ObjectID `form:"id" json:"id" bson:"_id"`
//评论对象的ID
ObjID string `form:"objID" json:"objID"`
CID string `form:"cid json:"cid"` //二级评论时,为被评论的评论id
//发表评论的 用户ID
UserID uint64 `form:"userID" json:"userID"`
//发表评论的 用户昵称
UserName string `form:"userName" json:"userName"`
//头像 URL
UserPortrait string `form:"userPortrait" json:"userPortrait" `
//是否认证
SuperUser int `form:"superUser" json:"superUser"`
//评论内容
Content string `form:"content" json:"content"`
//此评论点赞次数
LikeCount int `form:"likeCount" json:"likeCount"`
//是否点过赞
IsLike bool `form:"isLike" json:"isLike"`
VipExpireDate time.Time `json:"vipExpireDate" bson:"vipExpireDate"`
//评论时间
CreatedAt time.Time `form:"createdAt" json:"createdAt"`
//用户vip等级
Level int `json:"level"`
VipLevel int `json:"vipLevel" bson:"vipLevel"`
Info []CmtRespList
}
// MyCmtResp 列表响应信息(父评论)
type MyCmtResp struct {
List []MyCmt `json:"list"`
HasNext bool `json:"hasNext"`
}
type MyCmt struct {
// 全局唯一评论ID
ID primitive.ObjectID `bson:"_id" json:"id"`
// 评论对象的ID 帖子id
ObjID primitive.ObjectID `bson:"objID" json:"objID"`
// 评论内容
Content string `bson:"content" json:"content"`
// 此评论点赞次数
LikeCount int `bson:"likeCount" json:"likeCount"`
// 是否是神评论
IsGodComment bool `bson:"isGodComment" json:"isGodComment"`
// 帖子标题
VidTitle string `json:"vidTitle"`
// 帖子封面
VidCover string `json:"vidCover"`
//评论时间
CreatedAt time.Time `bson:"createdAt" json:"createdAt"`
}
File diff suppressed because it is too large Load Diff
+63
View File
@@ -0,0 +1,63 @@
package cmtmod
import (
"91porn-server/common/pageopt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
type Matcher = pageopt.Matcher
// ToUserIDMatch
type ToUserIDMatch struct {
ToUserID *uint64
}
func (t *ToUserIDMatch) New() Matcher {
return pageopt.NewAssignMatch("toUserID", t.ToUserID)
}
// PublisherIDMatch
type PublisherIDMatch struct {
PublisherID *uint64
}
func (t *PublisherIDMatch) New() Matcher {
return pageopt.NewAssignMatch("publisherID", t.PublisherID)
}
type CreatedAtGTEMatch struct {
GTE *time.Time
}
func (c *CreatedAtGTEMatch) New() Matcher {
return pageopt.NewGTEMatch("createdAt", c.GTE)
}
// List
func List(sort bson.D, skip, limit int64, matchers ...Matcher) ([]Comment, error) {
filter := pageopt.MergeM(matchers)
opt := &options.FindOptions{}
if len(sort) != 0 {
opt.SetSort(sort)
}
opt.SetSkip(skip)
opt.SetLimit(limit)
list := make([]Comment, 0, limit)
err := coll(nil).Find(&list, filter, opt)
if err != nil {
return nil, err
}
return list, nil
}
// Count
func Count(matchers ...Matcher) (int64, error) {
filter := pageopt.MergeM(matchers)
count, err := coll(nil).Count(filter)
if err != nil {
return 0, err
}
return count, nil
}
+82
View File
@@ -0,0 +1,82 @@
package cmtmod
import (
"91porn-server/common/db"
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type ObjectID = primitive.ObjectID
func Init() {
mdb = db.Init(table)
initIndex()
}
type CmtType string
const (
CmtTypeVideo CmtType = "VIDEO"
CmtTypeComment CmtType = "CMET"
CmtTypeReply CmtType = "REPLY"
CmtAt CmtType = "AT"
CmtNoVideo CmtType = "NOVIDEO"
)
type OType = string
const (
OTypeVideo OType = "video" //视频
OTypeCartoon OType = "cartoon" //漫画
OTypeDrama OType = "drama" //短剧
OTypeAiPlaza OType = "AiPlaza" //ai广场
)
// Comment 评论
type Comment struct {
ID ObjectID `bson:"_id,omitempty"` // 全局唯一ID
ObjID ObjectID `bson:"objID"` // 评论对象的ID
ObjType OType `bson:"objType"` // 评论对象类型 video:视频 cartoon:动漫
Title string `bson:"title"` // 如果是视频/动漫 填充对应标题
CID ObjectID `bson:"cid,omitempty"` // 评论id
RID ObjectID `bson:"rid,omitempty"` // 被回复的评论id
GID ObjectID `bson:"gid,omitempty"` // 二级评论的主评论id,用于分组聚集评论的回复
Type CmtType `bson:"type"` // 评论类型 video:对视频发表评论 comment:对评论发表评论 reply:对子评论的回复 noVideo:非视频帖子评论
PublisherID uint64 `bson:"publisherID"` // 字段Type指定资源的发布者
AuthorMark bool `bson:"authorMark"` // 如果是做的评论,其跟随回复全部置为true,便于获取作者的评论及其回复
SortCnt int64 `bson:"sortCnt,omitempty"` // 热门排序标记,同组的值一致,用于排序热门评论,存主评论的点赞数,点赞时更新数据
UserID uint64 `bson:"userID"` // 发表评论的 用户ID
ToUserID uint64 `bson:"toUserID,omitempty"` // 对某用户回复评论 用户ID
ToUserName string `form:"toUserName" json:"toUserName"` // 对某用户回复评论 用户昵称
LikeCount int `bson:"likeCount"` // 点赞数
CommentCount int `bson:"commentCount"` // 评论数
IsGodComment bool `bson:"isGodComment"` // 是否是神评论
GodCommentAward bool `bson:"godCommentAward,omitempty"` // 是否已经发放过神评奖励
IsAuthor bool `bson:"isAuthor"` // 是否是作者
IsRobot bool `bson:"isRobot"` // 是否是机器人
QuoteType string `json:"quoteType" bson:"quoteType"` // 引用类型 vid视频 col用户播单 sec官方播单 cover图集
QuoteID primitive.ObjectID `json:"quoteID" bson:"quoteID"` // 引用id
QuoteImg string `json:"quoteImg" bson:"quoteImg"` // 引用资源图片
QuoteTitle string `json:"quoteTitle" bson:"quoteTitle"` // 引用资源标题
Content string `bson:"content"` // 评论内容
OrgContent string `bson:"orgContent"` // 评论原文
Image string `bson:"image"` // 评论图片
Level int `bson:"level"` // 评论层级 1:一级评论 2:二级评论
IPAddr string `bson:"ipAddr"` // 发表评论的ip地址
Status int `bson:"status"` // 评论状态 1:通过审核 2:未审核 3:被自动过滤 4:审核未通过
Reason string `bson:"reason"` // 评论未通过原因
Desc string `bson:"desc" json:"desc"` // 备注
City string `bson:"city"` // 发表评论的城市
LinkStr string `json:"linkStr" bson:"linkStr"` // 跳转配置
IsAdvertiser bool `json:"isAdvertiser" bson:"isAdvertiser"` // 是否是打广告用户
IsDelete bool `bson:"isDelete"` // true:已删除 false:未删除
CreatedAt time.Time `bson:"createdAt,omitempty"` // 评论发表时间
DeletedAt time.Time `bson:"deletedAt"` // 评论发表时间
}
// FstCmt 获取一级评论的第一条评论
type FstCmt struct {
ID ObjectID `bson:"_id"`
Data Comment
}
+82
View File
@@ -0,0 +1,82 @@
package cmtmod
import (
"91porn-server/models/commod"
"go.mongodb.org/mongo-driver/bson"
"time"
)
type WebCmtRespList struct {
ID ObjectID `json:"id"` // 全局唯一ID
ObjID ObjectID `json:"objID"` // 评论对象的ID
UserID uint64 `json:"userID"` // 发表评论的 用户ID
LikeCount int `json:"likeCount"` // 点赞数
Content string `json:"content"` // 评论内容
Level int `json:"level"` // 评论层级 1:一级评论 2:二级评论
Status int `json:"status"` // 评论状态 1:通过审核 2:未审核 3:被自动过滤
IsDelete bool `json:"isDelete"` // true:已删除 false:未删除
IsBaned bool `json:"isBaned"` // true:已禁言 false:未禁言
IsGodComment bool `json:"isGodComment"` // 是否是神评论
IsRobot bool `bson:"isRobot"` // 是否是机器人
Portrait string `json:"portrait"` // 用户头像
Name string `json:"name"` // 用户昵称
LinkStr string `json:"linkStr"` // 跳转配置
CreatedAt time.Time `json:"createdAt"` // 评论发表时间
HasLocked bool `json:"hasLocked"` // 用户是否封禁
IsAdvertiser bool `json:"isAdvertiser"` // 是否是打广告用户
Image string `json:"image"` // 评论图片
}
type WebCmtListReqInfo struct {
VidID string `form:"vidID" json:"vidID" binding:"omitempty"` // 视频id
UID uint64 `form:"uid" json:"uid" binding:"omitempty"` // 用户id
Content string `form:"content" json:"content" binding:"omitempty"` // 搜索内容
IsRobot *bool `form:"isRobot" json:"isRobot"` // 是否机器人
IsAdvertiser *bool `form:"isAdvertiser" json:"isAdvertiser"` // 是否是打广告用户
Status *int `form:"status" bson:"status"` // 评论状态 1:通过审核 2:未审核 3:被自动过滤
Page commod.Page
}
type WebCmtDeleteReqInfo struct {
IDS []ObjectID `form:"ids" json:"ids" binding:"omitempty"`
UID uint64 `form:"uid" json:"uid" binding:"omitempty"`
Content string `form:"content" json:"content" binding:"omitempty"`
}
type WebCmtReqInfo struct {
ID ObjectID `form:"id" json:"id"`
}
type BatchPassReqInfo struct {
IDS []ObjectID `form:"ids" json:"ids"` // 评论IDS
Status int `form:"status" json:"status" binding:"required"` // 状态
}
type EditCond struct {
ID ObjectID `form:"id" json:"id"` // 评论ID
IsGodComment *bool `form:"isGodComment" json:"isGodComment"` // 是否神评论
LinkStr *string `form:"linkStr" json:"linkStr"` // 评论跳转链接
GodCommentAward bool `json:"-" form:"-"` // 是否需要给神评奖励
LikeCount *int `json:"likeCount" form:"likeCount"` // 点赞数
}
func (receiver *EditCond) Filter() bson.M {
return bson.M{"_id": receiver.ID}
}
func (receiver *EditCond) Update() bson.M {
var update = bson.M{}
if receiver.IsGodComment != nil {
update["isGodComment"] = receiver.IsGodComment
}
if receiver.GodCommentAward == true {
update["godCommentAward"] = true
}
if receiver.LinkStr != nil {
update["linkStr"] = receiver.LinkStr
}
if receiver.LikeCount != nil {
update["likeCount"] = receiver.LikeCount
}
return bson.M{"$set": update}
}
+38
View File
@@ -0,0 +1,38 @@
package collectmod
import (
"91porn-server/models/v/locmod"
"91porn-server/models/v/vidmod"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// CInfo 查询返回的收藏结构
type CInfo struct {
Video []primitive.ObjectID `bson:"video"`
Tags []primitive.ObjectID `bson:"tags"`
Place []primitive.ObjectID `bson:"place"`
VideoTC int64 `bson:"videoTC"`
TagsTC int64 `bson:"tagsTC"`
PlaceTC int64 `bson:"placeTC"`
}
// ICollectResp 我的收藏回复
type ICollectResp struct {
VInfos []*vidmod.VideoInfo
TInfos []vidmod.TagInfo
LInfos []locmod.Location
VideoTC int64 `bson:"videoTC"`
TagsTC int64 `bson:"tagsTC"`
PlaceTC int64 `bson:"placeTC"`
}
type DoCollectReqInfo struct {
ObjID primitive.ObjectID `form:"objID" json:"objID" binding:"required"` // 收藏的对象的ID
Type string `form:"type" json:"type" binding:"required"` // 收藏类型 SP:长视频 SHORT:短视频 COVER:图文帖子 PIC:图集帖子 SEED_LINK:种子/黄油帖子
IsCollect bool `form:"isCollect" json:"isCollect"` // 收藏or取消收藏
}
type DoBatchCancelCollectReq struct {
ObjIDs []primitive.ObjectID `form:"objIDs" json:"objIDs" binding:"required"` // 取消收藏的ID的合集数组
Type string `form:"type" json:"type" binding:"required"` // 收藏类型 SP:长视频 SHORT:短视频 COVER:图文帖子 PIC:图集帖子 SEED_LINK:种子/黄油帖子
}

Some files were not shown because too many files have changed in this diff Show More