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
+139
View File
@@ -0,0 +1,139 @@
package newactivity
import (
"time"
"91porn-server/common/timeutil"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func BulkAddModels(insertSqls []mongo.WriteModel) error {
if len(insertSqls) > 0 {
_, err := collModel(nil).Bulk(insertSqls)
return err
}
return nil
}
// 嫩模列表
func ModelList() (res ListRes, err error) {
res = ListRes{}
if err = collModel(nil).Aggregate(&res.Models, []bson.M{
{
"$group": bson.M{
"_id": "$location",
"models": bson.M{
"$push": bson.M{
"id": "$id",
"name": "$name",
"location": "$location",
"bgImg": "$bgImg",
"video": "$video",
},
},
},
},
{
"$project": bson.M{
"location": "$_id",
"models": 1,
"_id": 0,
},
},
{
"$sort": bson.M{
"models.id": 1,
},
},
}); err != nil {
return
}
num := struct {
JoinPersons int64 `bson:"num"` //参与人数
}{}
err = collJoin(nil).FindOne(&num, bson.M{})
res.JoinPersons = num.JoinPersons
return
}
// 单个嫩模
func FindOne(modelId uint32) (res FindOneRes, err error) {
res = FindOneRes{}
date := timeutil.BeginningOfDay(time.Now())
if time.Now().Hour() >= 20 {
date = date.Add(24 * time.Hour)
}
if err = collModel(nil).AggregateDecode(&res, []bson.M{
{
"$match": bson.M{
"id": modelId,
},
},
{
"$lookup": bson.M{
"from": "activity_gift_stock",
"pipeline": []bson.M{
{
"$match": bson.M{
"modelId": modelId,
"date": date,
},
},
{"$project": bson.M{
"_id": 0,
"giftLeft": 1,
"soldOut": 1,
}},
},
"as": "gift_stock",
},
},
{
"$unwind": bson.M{
"path": "$gift_stock",
"preserveNullAndEmptyArrays": true,
},
},
{
"$project": bson.M{
"_id": 0,
"id": 1,
"name": 1,
"bgImg": 1,
"location": 1,
"video": 1,
"giftLeft": "$gift_stock.giftLeft",
"soldOut": "$gift_stock.soldOut",
},
},
}); err != nil {
return
}
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
conf := bson.M{
"modelId": modelId,
"date": date,
}
if res.SoldOut {
conf["soldOut"] = true
}
err = collSold(nil).Find(&res.SoldList, conf, opts)
return
}
// 嫩模列表
func UpdateJoinNum(num int64) error {
_, err := collJoin(nil).UpsertOne(bson.M{}, bson.M{"$set": bson.M{"num": num}})
return err
}
// 获取参与人数
func GetJoinNum() (int64, error) {
num := struct {
JoinPersons int64 `bson:"num"` //参与人数
}{}
return num.JoinPersons, collJoin(nil).FindOne(&num, bson.M{})
}
+78
View File
@@ -0,0 +1,78 @@
package newactivity
import (
"fmt"
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
func ExistsOrder(num uint32, req WinRecords) (exists bool, err error) {
conf := bson.M{
"date": req.Date,
"userId": req.UserId,
"modelId": req.ModelId,
}
if num == 0 {
conf["soldOut"] = true
} else {
conf["serials"] = num
}
count, err := collSold(nil).Count(conf)
return count > 0, err
}
func BuyPage(req BuyPageReq) (res BuyPageRes, err error) {
conf := bson.M{}
if req.ModelId != nil {
conf["modelId"] = req.ModelId
}
if req.UserId != nil {
conf["userId"] = req.UserId
}
if req.UserName != nil {
conf["userName"] = bson.M{"$regex": req.UserName}
}
if !req.Date.IsZero() {
conf["date"] = req.Date
}
if !req.Start.IsZero() && !req.End.IsZero() {
conf["createdAt"] = bson.M{"$gte": req.Start, "$lt": req.End}
}
res = BuyPageRes{}
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
opts.SetSkip((req.Page - 1) * req.PageSize)
opts.SetLimit(req.PageSize)
if err = collSold(nil).Find(&res.Data, conf, opts); err != nil {
return
}
res.Total, err = collSold(nil).Count(conf)
if err != nil {
return
}
num := struct {
Num int64 `bson:"num"`
}{}
err = collJoin(nil).FindOne(&num, bson.M{})
res.JoinPersons = num.Num
return
}
// 嫩模列表
func InsertSoldLog(t *db.MongoTool, log *SoldRecord) (id primitive.ObjectID, err error) {
log.CreatedAt = time.Now()
log.UpdatedAt = time.Now()
result, err := collSold(t).InsertOne(log)
if err != nil {
fmt.Println("insert error", err)
return
}
if id, ok := result.InsertedID.(primitive.ObjectID); ok {
return id, nil
}
return
}
+52
View File
@@ -0,0 +1,52 @@
package newactivity
import (
"errors"
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func BulkStocks(insertSqls []mongo.WriteModel) (err error) {
if len(insertSqls) > 0 {
_, err = collStock(nil).Bulk(insertSqls)
}
return
}
// 嫩模列表
func UpdateStock(t *db.MongoTool, req BuyReq, date time.Time) (giftLeft uint32, location string, err error) {
res := struct {
GiftLeft uint32 `bson:"giftLeft"` //剩余礼物数目
Location string `bson:"location"` //模特地区
}{}
conf := bson.M{
"modelId": req.ModelId,
"date": date,
"soldOut": false,
}
var update bson.M
if req.BuyOut {
update = bson.M{"$set": bson.M{"soldOut": true}}
} else {
conf["giftLeft"] = bson.M{"$gte": req.Quantity}
update = bson.M{"$inc": bson.M{"giftLeft": -req.Quantity}}
}
opts := options.FindOneAndUpdate().SetProjection(bson.M{
"_id": 0,
"giftLeft": 1,
"location": 1,
})
if err = collStock(t).FindOneAndUpdateReturnTiny(&res, conf, update, false, opts); err != nil {
if err == mongo.ErrNoDocuments {
err = errors.New("礼物卖完了😯")
}
}
giftLeft = res.GiftLeft
location = res.Location
return
}
+46
View File
@@ -0,0 +1,46 @@
package newactivity
import (
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
func AddWinRecord(req WinRecords) error {
_, err := collWin(nil).UpsertOne(bson.M{
"date": req.Date,
"modelId": req.ModelId,
}, bson.M{"$set": req})
return err
}
func WinRecordsByDate(date time.Time) ([]WinRecords, error) {
list := make([]WinRecords, 0)
return list, collWin(nil).Find(&list, bson.M{"date": date})
}
func WinRecordPage(req WinRcdPageReq) (res WinRcdPageRes, err error) {
conf := bson.M{}
if req.ModelId != nil {
conf["modelId"] = req.ModelId
}
if req.UserId != nil {
conf["userId"] = req.UserId
}
if req.UserName != nil {
conf["userName"] = bson.M{"$regex": req.UserName}
}
if !req.Date.IsZero() {
conf["date"] = req.Date
}
res = WinRcdPageRes{}
opts := options.Find().SetSort(bson.D{{Key: "createdAt", Value: -1}})
opts.SetSkip((req.Page - 1) * req.PageSize)
opts.SetLimit(req.PageSize)
if err = collWin(nil).Find(&res.Data, conf, opts); err != nil {
return
}
res.Total, err = collWin(nil).Count(conf)
return
}
+164
View File
@@ -0,0 +1,164 @@
package newactivity
import (
"time"
"91porn-server/common/db"
"91porn-server/models"
)
var (
mdb *db.MongoDB
stockdb *db.MongoDB
solddb *db.MongoDB
windb *db.MongoDB
joindb *db.MongoDB
)
const (
activity_model_table = models.ActivityModels
activity_gift_stock = models.ActivityGitStock
activity_sold_record = models.ActivitySoldRecord
activity_win_record = models.ActivityWinRecord
activity_join_persons = models.ActivityJoinPersons
)
func collModel(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(activity_model_table)
}
return t.Coll(activity_model_table)
}
func collStock(t *db.MongoTool) *db.MongoTool {
if t == nil {
return stockdb.Coll(activity_gift_stock)
}
return t.Coll(activity_gift_stock)
}
func collSold(t *db.MongoTool) *db.MongoTool {
if t == nil {
return solddb.Coll(activity_sold_record)
}
return t.Coll(activity_sold_record)
}
func collWin(t *db.MongoTool) *db.MongoTool {
if t == nil {
return windb.Coll(activity_win_record)
}
return t.Coll(activity_win_record)
}
func collJoin(t *db.MongoTool) *db.MongoTool {
if t == nil {
return joindb.Coll(activity_join_persons)
}
return t.Coll(activity_join_persons)
}
type Model struct {
Id uint32 `json:"id" bson:"id"` //id
Name string `json:"name" bson:"name"` //名字
BgImg []string `json:"bgImg" bson:"bgImg"` //背景大图
Location string `json:"location" bson:"location"` //地区
Video string `json:"video" bson:"video"` //视频
}
type ListRes struct {
JoinPersons int64 `json:"JoinPersons" bson:"JoinPersons"` //活动参与人数
Models []LocationModels `json:"models" bson:"models"` //模特
}
type LocationModels struct {
Location string `json:"location" bson:"location"` //地区
Models []Model `json:"models" bson:"models"` //模特
}
type FindOneRes struct {
Id uint32 `json:"id" bson:"id"` //id
Name string `json:"name" bson:"name"` //名字
BgImg []string `json:"bgImg" bson:"bgImg"` //背景大图
Location string `json:"location" bson:"location"` //地区
Video string `json:"video" bson:"video"` //视频
GiftLeft int32 `json:"giftLeft" bson:"giftLeft"` //剩余礼物数目
SoldOut bool `json:"soldOut" bson:"soldOut"` //是否已被买断
SoldList []SoldRecord `json:"soldList" bson:"soldList"` //卖出礼物清单
}
type GiftStock struct {
ModelId uint32 `json:"modelId" bson:"modelId"` //模特id
Date time.Time `json:"date" bson:"date"` //日期
GiftLeft int32 `json:"giftLeft" bson:"giftLeft"` //剩余礼物数目
SoldOut bool `json:"soldOut" bson:"soldOut"` //是否已被买断
}
type SoldRecord struct {
Date time.Time `json:"date" bson:"date"` //日期
ModelId uint32 `json:"modelId" bson:"modelId"` //模特id
UserId uint32 `json:"userId" bson:"userId"` //用户Id
UserName string `json:"userName" bson:"userName"` //用户昵称
UserLogo string `json:"userLogo" bson:"userLogo"` //用户头像
Quantity int32 `json:"quantity" bson:"quantity"` //礼物数目
SoldOut bool `json:"soldOut" bson:"soldOut"` //是否是买断
Serials []uint32 `json:"serials" bson:"serials"` //礼物序号
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` //更新时间
}
type BuyReq struct {
ModelId uint32 `json:"modelId"` //模特id
Quantity int32 `json:"quantity"` //礼物数目
BuyOut bool `json:"buyOut"` //是否买断
}
type BuyPageReq struct {
Page int64 `json:"page"` //页码
PageSize int64 `json:"pageSize"` //条数
UserId *uint32 `json:"userId"` //用户id
UserName *string `json:"userName"` //用户昵称
ModelId *uint32 `json:"modelId"` //模特id
Date time.Time `json:"date"` //期号
Start time.Time `json:"start"` //开始时间
End time.Time `json:"end"` //结束时间
}
type BuyPageRes struct {
Total int64 `json:"total"` //页码
Data []SoldRecord `json:"data"` //页码
JoinPersons int64 `json:"joinPersons"` //参与人数
}
type WinRecords struct {
Date time.Time `json:"date" bson:"date"` //日期
UserId uint32 `json:"userId" bson:"userId"` //用户id
UserName string `json:"userName" bson:"userName"` //用户昵称
UserLogo string `json:"userLogo" bson:"userLogo"` //用户头像
WinNum uint32 `json:"winNum" bson:"winNum"` //中奖号码
ModelId uint32 `json:"modelId" bson:"modelId"` //模特Id
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //创建时间
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` //更新时间
}
type WinRcdPageReq struct {
Page int64 `json:"page"` //页码
PageSize int64 `json:"pageSize"` //条数
UserId *uint32 `json:"userId"` //用户id
UserName *string `json:"userName"` //用户昵称
ModelId *uint32 `json:"modelId"` //模特id
Date time.Time `json:"date"` //期号
}
type WinRcdPageRes struct {
Total int64 `json:"total"` //页码
Data []WinRecords `json:"data"` //页码
}
func Init() {
mdb = db.Init(activity_model_table)
stockdb = db.Init(activity_gift_stock)
joindb = db.Init(activity_join_persons)
solddb = db.Init(activity_sold_record)
windb = db.Init(activity_win_record)
}