Files
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

310 lines
8.5 KiB
Go

package modulesectionmod
import (
"91porn-server/common/log"
"fmt"
"time"
"91porn-server/common"
"91porn-server/common/db"
"91porn-server/common/stderr"
"91porn-server/models"
"91porn-server/models/commod"
"91porn-server/models/v/moduleconfmod"
"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.Section
var mdb *db.MongoDB
func initIndex() {
coll := coll(nil)
many := []mongo.IndexModel{
{
Keys: bson.D{{Key: "sectionName", Value: 1}, {Key: "subModuleID", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{
{Key: "subModuleID", Value: 1}, {Key: "status", Value: 1}, {Key: "sort", Value: -1}, {Key: "createdAt", 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 InsertOne(section Section) error {
section.CreatedAt = time.Now()
section.UpdatedAt = section.CreatedAt
ok, err := checkLimit(section.SubModuleID)
if err != nil {
return err
}
if !ok {
return stderr.ModuleConfLimitExceed
}
_, err = coll(nil).InsertOne(section)
return err
}
func UpdateOne(set EditSelector) error {
subModule, err := moduleconfmod.GetByID(*set.SubModuleID)
if err != nil {
return err
}
total, err := CountBySubModuleID(*set.SubModuleID)
if err != nil {
return err
}
if (set.Status != nil && *set.Status == 1) && total >= int64(subModule.SectionLimit) {
return stderr.ModuleConfLimitExceed
}
cond := bson.M{"updatedAt": time.Now()}
if set.Status != nil {
cond["status"] = set.Status
}
if set.Tags != nil && len(*set.Tags) > 0 {
cond["tags"] = set.Tags
} else {
cond["tags"] = []string{}
}
if set.TagIds != nil && len(set.TagIds) > 0 {
cond["tagIds"] = set.TagIds
} else {
cond["tagIds"] = []primitive.ObjectID{}
}
if set.SectionName != nil {
cond["sectionName"] = set.SectionName
}
if set.SubModuleID != nil {
cond["subModuleID"] = set.SubModuleID
}
if set.ShowType != nil {
cond["showType"] = set.ShowType
}
if set.Sort != nil {
cond["sort"] = set.Sort
}
if set.SectionCover != nil {
cond["sectionCover"] = set.SectionCover
}
if set.Hot != nil {
cond["hot"] = set.Hot
}
_, err = coll(nil).UpdateOne(bson.M{"_id": set.ID}, bson.M{"$set": cond})
return err
}
// DeleteOne 删除一条数据,仅作删除标记-deletedAt
func DeleteOne(id primitive.ObjectID) error {
now := time.Now()
status := uint8(0)
set := EditSelector{ID: id, DeletedAt: &now, Status: &status}
return UpdateOne(set)
}
func DeleteById(id primitive.ObjectID) (err error) {
_, err = coll(nil).DeleteOne(bson.M{"_id": id})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "DeleteById", table, "DeleteOne", err),
log.Any("id", id),
)
return
}
return
}
// GetBySectionID 根据专题ID获取专题详情
func GetBySectionByID(sectionID primitive.ObjectID) (section Section, err error) {
err = coll(nil).FindOne(&section, bson.M{"_id": sectionID})
return
}
// GetBySubModuleID 通过亚模块id获取专题列表
func GetBySubModuleID(subModuleID primitive.ObjectID, page commod.Page) (section []Section, hasNext bool, err error) {
opts := options.FindOptions{}
opts.SetSkip(int64(page.Skip())).SetLimit(int64(page.Limit()) + 1).SetSort(bson.D{{"sort", 1}, {"_id", -1}})
if err = coll(nil).Find(&section, bson.M{"subModuleID": subModuleID, "status": 1}, &opts); err != nil {
return
}
if uint64(len(section)) > page.Limit() {
hasNext = true
section = section[:page.Limit()]
}
return
}
func GetAllBySubModuleID(subModuleID primitive.ObjectID) (section []Section, err error) {
section = make([]Section, 0)
op := options.Find().SetSort(bson.D{{"sort", 1}})
err = coll(nil).Find(&section, bson.M{"subModuleID": subModuleID, "status": 1}, op)
return
}
func HomePageGetBySubModuleID(subModuleID primitive.ObjectID) (section []Section, err error) {
section = make([]Section, 0)
op := options.Find().SetSort(bson.D{{"sort", 1}}).SetLimit(50)
err = coll(nil).Find(&section, bson.M{"subModuleID": subModuleID, "status": 1}, op)
return
}
func CountBySubModuleID(subModuleID primitive.ObjectID) (int64, error) {
return coll(nil).Count(bson.M{"subModuleID": subModuleID, "status": 1})
}
func AllSections() (list []Section, err error) {
err = coll(nil).Find(&list, bson.M{"status": 1})
return
}
// AllSectionsModule 获取所有激活的专题,以及对应的模块信息
func AllSectionsModule() (list []SectionModule, err error) {
pipeline := []bson.M{
{"$match": bson.M{"status": 1}},
{"$lookup": bson.M{
"from": models.ModuleConf,
"localField": "subModuleID",
"foreignField": "_id",
"as": "sectionMoudle",
}},
}
err = coll(nil).Aggregate(&list, pipeline)
return
}
func GetByIDs(ids []primitive.ObjectID) (list []SectionModule, err error) {
pipeline := []bson.M{
{"$match": bson.M{"_id": bson.M{"$in": ids}}},
{"$lookup": bson.M{
"from": models.ModuleConf,
"localField": "subModuleID",
"foreignField": "_id",
"as": "sectionMoudle",
}},
}
err = coll(nil).Aggregate(&list, pipeline)
return
}
// TODO: 并发不安全
func checkLimit(subModuleID primitive.ObjectID) (ok bool, err error) {
subModule, err := moduleconfmod.GetByID(subModuleID)
if err != nil {
return
}
total, err := CountBySubModuleID(subModuleID)
if err != nil {
return
}
return subModule.SectionLimit == 0 || int(total) < subModule.SectionLimit, nil
}
// ListBySubModule returns topic metadata under one module. The hard limit keeps
// the merged system/custom topic response bounded even if historical data is malformed.
func ListBySubModule(subModuleID primitive.ObjectID, limit int64) ([]Section, error) {
if limit <= 0 || limit > 1000 {
limit = 1000
}
var list []Section
err := coll(nil).Find(&list, bson.M{
"subModuleID": subModuleID,
"deletedAt": nil,
}, options.Find().SetSort(bson.D{{Key: "sort", Value: -1}, {Key: "updatedAt", Value: -1}}).SetLimit(limit))
return list, err
}
// UpdateTopicFields updates a section only when it belongs to the expected module.
func UpdateTopicFields(t *db.MongoTool, id, subModuleID primitive.ObjectID, fields bson.M) (int64, error) {
fields["updatedAt"] = time.Now()
result, err := coll(t).UpdateOne(bson.M{
"_id": id, "subModuleID": subModuleID, "deletedAt": nil,
}, bson.M{"$set": fields})
if err != nil {
return 0, err
}
return result.MatchedCount, nil
}
func DeleteTopic(t *db.MongoTool, id, subModuleID primitive.ObjectID) (int64, error) {
result, err := coll(t).DeleteOne(bson.M{"_id": id, "subModuleID": subModuleID})
if err != nil {
return 0, err
}
return result.DeletedCount, nil
}
// Search 根据条件检索section
func Search(q QuerySelector, p commod.Page) (list []Section, hasNext bool, total int64, err error) {
skip := int64(p.Skip())
limit := int64(p.Limit() + 1)
opts := options.FindOptions{
Skip: &skip,
Limit: &limit,
Sort: append(p.GetSort(), bson.E{Key: "createdAt", Value: -1}),
}
filter, err := common.ToBsonM(q)
if err != nil {
return
}
if q.SectionName != nil {
filter["sectionName"] = primitive.Regex{
Pattern: *q.SectionName,
}
}
if err = coll(nil).Find(&list, filter, &opts); err != nil {
return
}
if total, err = coll(nil).Count(filter); err != nil {
return
}
if uint64(len(list)) > p.Limit() {
hasNext = true
list = list[:p.Limit()]
}
return
}
// GetBySectionByIDs 根据专题IDS获取专题详情
func GetBySectionByIDs(sectionIds []primitive.ObjectID) (section []Section, err error) {
err = coll(nil).Find(&section, bson.M{"_id": bson.M{"$in": sectionIds}})
return
}
// GetBySectionBySids 根据专题IDS获取专题详情
func GetBySectionBySids(sIds []primitive.ObjectID) (section []Section, err error) {
err = coll(nil).Find(&section, bson.M{"subModuleID": bson.M{"$in": sIds}, "status": 1})
return
}
// GetBySectionID 根据专题ID获取专题详情
func GetBySectionID(sectionID primitive.ObjectID) (section Section, err error) {
err = coll(nil).FindOne(&section, bson.M{"_id": sectionID})
return
}
// QueryAllList 分页查询文档
func QueryAllList(filter primitive.M, opts ...*options.FindOptions) (out []*Section, 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
}