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
+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()
}