init: web_hgdjc_server

This commit is contained in:
2026-11-07 10:46:18 +08:00
commit b2ff6ac8ff
707 changed files with 147645 additions and 0 deletions
+344
View File
@@ -0,0 +1,344 @@
package srv_videoslug
import (
"context"
"strings"
"videoweb/pub/common/slugx"
"videoweb/pub/common/srvdef"
"videoweb/pub/common/utils"
"videoweb/pub/models/videocategorymod"
"videoweb/pub/models/videocreatermod"
"videoweb/pub/models/videoinformationmod"
"videoweb/pub/models/videotagmod"
"videoweb/pub/models/videotopicmod"
"videoweb/web/api/proto"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
const (
syncSlugDefaultSize = int64(500)
syncSlugMaxSize = int64(2000)
)
func videoExists(ctx context.Context, slug string, excludeId int64) bool {
item, _ := videoinformationmod.FindOneVideoInformation(ctx, slugx.Filter(
videoinformationmod.FN.VideoInformation.Slug, videoinformationmod.FN.VideoInformation.Id, slug, excludeId))
return item != nil
}
func tagExists(ctx context.Context, slug string, excludeId int64) bool {
item, _ := videotagmod.FindOneVideoTagInfo(ctx, slugx.Filter(
videotagmod.FN.VideoTagInfo.Slug, videotagmod.FN.VideoTagInfo.Id, slug, excludeId))
return item != nil
}
func topicExists(ctx context.Context, slug string, excludeId int64) bool {
item, _ := videotopicmod.FindOneVideoTopicModel(ctx, slugx.Filter(
videotopicmod.FN.VideoTopicModel.Slug, videotopicmod.FN.VideoTopicModel.Id, slug, excludeId))
return item != nil
}
func createrExists(ctx context.Context, slug string, excludeId int64) bool {
item, _ := videocreatermod.FindOneVideoCreaterInfo(ctx, slugx.Filter(
videocreatermod.FN.VideoCreaterInfo.Slug, videocreatermod.FN.VideoCreaterInfo.Id, slug, excludeId))
return item != nil
}
func categoryExists(ctx context.Context, slug string, excludeId int64) bool {
item, _ := videocategorymod.FindOneVideoCategory(ctx, slugx.Filter(
videocategorymod.FN.VideoCategory.Slug, videocategorymod.FN.VideoCategory.Id, slug, excludeId))
return item != nil
}
func EnsureVideo(ctx context.Context, info *videoinformationmod.VideoInformation, excludeId int64) *srvdef.SrvErr {
if info == nil {
return nil
}
return slugx.Ensure(&info.Slug, utils.SlugSourceFromKeywordsOrTitle(info.Keyworld, info.Title),
func(s string) bool { return videoExists(ctx, s, excludeId) })
}
func PrepareVideoOnUpdate(ctx context.Context, info *videoinformationmod.VideoInformation, reqSlug *string, title string, keyworld []string) (string, bool, *srvdef.SrvErr) {
if info == nil {
return "", false, nil
}
return slugx.PrepareOnUpdate(info.Slug, reqSlug, utils.SlugSourceFromKeywordsOrTitle(keyworld, title),
func(s string) bool { return videoExists(ctx, s, info.Id) })
}
func EnsureTag(ctx context.Context, info *videotagmod.VideoTagInfo, excludeId int64) *srvdef.SrvErr {
if info == nil {
return nil
}
return slugx.Ensure(&info.Slug, utils.SlugSourceFromKeywordsOrTitle(info.SeoInfo.Keyworld, info.Title),
func(s string) bool { return tagExists(ctx, s, excludeId) })
}
func PrepareTagOnUpdate(ctx context.Context, info *videotagmod.VideoTagInfo, reqSlug *string, title string, keywords []string) (string, bool, *srvdef.SrvErr) {
if info == nil {
return "", false, nil
}
return slugx.PrepareOnUpdate(info.Slug, reqSlug, utils.SlugSourceFromKeywordsOrTitle(keywords, title),
func(s string) bool { return tagExists(ctx, s, info.Id) })
}
func EnsureTopic(ctx context.Context, info *videotopicmod.VideoTopicModel, excludeId int64) *srvdef.SrvErr {
if info == nil {
return nil
}
return slugx.Ensure(&info.Slug, utils.SlugSourceFromKeywordsOrTitle(info.SeoInfo.Keyworld, info.Name),
func(s string) bool { return topicExists(ctx, s, excludeId) })
}
func PrepareTopicOnUpdate(ctx context.Context, info *videotopicmod.VideoTopicModel, reqSlug *string, name string, keywords []string) (string, bool, *srvdef.SrvErr) {
if info == nil {
return "", false, nil
}
return slugx.PrepareOnUpdate(info.Slug, reqSlug, utils.SlugSourceFromKeywordsOrTitle(keywords, name),
func(s string) bool { return topicExists(ctx, s, info.Id) })
}
func EnsureCreater(ctx context.Context, info *videocreatermod.VideoCreaterInfo, excludeId int64) *srvdef.SrvErr {
if info == nil {
return nil
}
return slugx.Ensure(&info.Slug, utils.SlugSourceFromKeywordsOrTitle(info.SeoInfo.Keyworld, info.Name),
func(s string) bool { return createrExists(ctx, s, excludeId) })
}
func PrepareCreaterOnUpdate(ctx context.Context, info *videocreatermod.VideoCreaterInfo, reqSlug *string, name string, keywords []string) (string, bool, *srvdef.SrvErr) {
if info == nil {
return "", false, nil
}
return slugx.PrepareOnUpdate(info.Slug, reqSlug, utils.SlugSourceFromKeywordsOrTitle(keywords, name),
func(s string) bool { return createrExists(ctx, s, info.Id) })
}
func EnsureCategory(ctx context.Context, info *videocategorymod.VideoCategory, excludeId int64) *srvdef.SrvErr {
if info == nil {
return nil
}
return slugx.Ensure(&info.Slug, utils.SlugSourceFromKeywordsOrTitle(info.SeoInfo.Keyworld, info.Name),
func(s string) bool { return categoryExists(ctx, s, excludeId) })
}
func PrepareCategoryOnUpdate(ctx context.Context, info *videocategorymod.VideoCategory, reqSlug *string, name string, keywords []string) (string, bool, *srvdef.SrvErr) {
if info == nil {
return "", false, nil
}
return slugx.PrepareOnUpdate(info.Slug, reqSlug, utils.SlugSourceFromKeywordsOrTitle(keywords, name),
func(s string) bool { return categoryExists(ctx, s, info.Id) })
}
// SyncEmptySlugs 为视频、标签、题材、作者、分类中空 slug 自动生成。
func SyncEmptySlugs(ctx context.Context, req *proto.VideoSlugSyncReq) (*proto.VideoSlugSyncResp, *srvdef.SrvErr) {
maxSize := syncSlugDefaultSize
if req != nil && req.MaxSize > 0 {
maxSize = req.MaxSize
}
if maxSize > syncSlugMaxSize {
maxSize = syncSlugMaxSize
}
resp := &proto.VideoSlugSyncResp{}
remain := maxSize
categoryUpdated, categoryMore, err := syncCategoryEmptySlugs(ctx, remain)
if err != nil {
return nil, err
}
resp.CategoryUpdated = categoryUpdated
remain -= categoryUpdated
if remain <= 0 {
resp.HasMore = categoryMore || hasEmpty(ctx, "tag") || hasEmpty(ctx, "topic") || hasEmpty(ctx, "creater") || hasEmpty(ctx, "video")
return resp, nil
}
tagUpdated, tagMore, err := syncTagEmptySlugs(ctx, remain)
if err != nil {
return nil, err
}
resp.TagUpdated = tagUpdated
remain -= tagUpdated
if remain <= 0 {
resp.HasMore = tagMore || hasEmpty(ctx, "topic") || hasEmpty(ctx, "creater") || hasEmpty(ctx, "video")
return resp, nil
}
topicUpdated, topicMore, err := syncTopicEmptySlugs(ctx, remain)
if err != nil {
return nil, err
}
resp.TopicUpdated = topicUpdated
remain -= topicUpdated
if remain <= 0 {
resp.HasMore = topicMore || hasEmpty(ctx, "creater") || hasEmpty(ctx, "video")
return resp, nil
}
createrUpdated, createrMore, err := syncCreaterEmptySlugs(ctx, remain)
if err != nil {
return nil, err
}
resp.CreaterUpdated = createrUpdated
remain -= createrUpdated
if remain <= 0 {
resp.HasMore = createrMore || hasEmpty(ctx, "video")
return resp, nil
}
videoUpdated, videoMore, err := syncVideoEmptySlugs(ctx, remain)
if err != nil {
return nil, err
}
resp.VideoUpdated = videoUpdated
resp.HasMore = videoMore
return resp, nil
}
func hasEmpty(ctx context.Context, kind string) bool {
filter := slugx.EmptyFilter()
switch kind {
case "tag":
n, _ := videotagmod.CountVideoTagInfos(ctx, filter)
return n > 0
case "topic":
n, _ := videotopicmod.CountVideoTopicModels(ctx, filter)
return n > 0
case "creater":
n, _ := videocreatermod.CountVideoCreaterInfos(ctx, filter)
return n > 0
case "video":
n, _ := videoinformationmod.CountVideoInformations(ctx, filter)
return n > 0
default:
n, _ := videocategorymod.CountVideoCategorys(ctx, filter)
return n > 0
}
}
func syncCategoryEmptySlugs(ctx context.Context, maxSize int64) (int64, bool, *srvdef.SrvErr) {
list, err := videocategorymod.FindManyVideoCategorys(ctx, slugx.EmptyFilter(), options.Find().SetLimit(maxSize+1))
if err != nil {
return 0, false, err
}
more := int64(len(list)) > maxSize
if more {
list = list[:maxSize]
}
var updated int64
for _, item := range list {
if item == nil {
continue
}
if serr := EnsureCategory(ctx, item, item.Id); serr != nil || strings.TrimSpace(item.Slug) == "" {
continue
}
_ = videocategorymod.UpdateOneVideoCategory(ctx, bson.M{videocategorymod.FN.VideoCategory.Id: item.Id}, bson.M{
"$set": bson.M{videocategorymod.FN.VideoCategory.Slug: item.Slug},
})
updated++
}
return updated, more, nil
}
func syncTagEmptySlugs(ctx context.Context, maxSize int64) (int64, bool, *srvdef.SrvErr) {
list, err := videotagmod.FindManyVideoTagInfos(ctx, slugx.EmptyFilter(), options.Find().SetLimit(maxSize+1))
if err != nil {
return 0, false, err
}
more := int64(len(list)) > maxSize
if more {
list = list[:maxSize]
}
var updated int64
for _, item := range list {
if item == nil {
continue
}
if serr := EnsureTag(ctx, item, item.Id); serr != nil || strings.TrimSpace(item.Slug) == "" {
continue
}
_ = videotagmod.UpdateOneVideoTagInfo(ctx, bson.M{videotagmod.FN.VideoTagInfo.Id: item.Id}, bson.M{
"$set": bson.M{videotagmod.FN.VideoTagInfo.Slug: item.Slug},
})
updated++
}
return updated, more, nil
}
func syncTopicEmptySlugs(ctx context.Context, maxSize int64) (int64, bool, *srvdef.SrvErr) {
list, err := videotopicmod.FindManyVideoTopicModels(ctx, slugx.EmptyFilter(), options.Find().SetLimit(maxSize+1))
if err != nil {
return 0, false, err
}
more := int64(len(list)) > maxSize
if more {
list = list[:maxSize]
}
var updated int64
for _, item := range list {
if item == nil {
continue
}
if serr := EnsureTopic(ctx, item, item.Id); serr != nil || strings.TrimSpace(item.Slug) == "" {
continue
}
_ = videotopicmod.UpdateOneVideoTopicModel(ctx, bson.M{videotopicmod.FN.VideoTopicModel.Id: item.Id}, bson.M{
"$set": bson.M{videotopicmod.FN.VideoTopicModel.Slug: item.Slug},
})
updated++
}
return updated, more, nil
}
func syncCreaterEmptySlugs(ctx context.Context, maxSize int64) (int64, bool, *srvdef.SrvErr) {
list, err := videocreatermod.FindManyVideoCreaterInfos(ctx, slugx.EmptyFilter(), options.Find().SetLimit(maxSize+1))
if err != nil {
return 0, false, err
}
more := int64(len(list)) > maxSize
if more {
list = list[:maxSize]
}
var updated int64
for _, item := range list {
if item == nil {
continue
}
if serr := EnsureCreater(ctx, item, item.Id); serr != nil || strings.TrimSpace(item.Slug) == "" {
continue
}
_ = videocreatermod.UpdateOneVideoCreaterInfo(ctx, bson.M{videocreatermod.FN.VideoCreaterInfo.Id: item.Id}, bson.M{
"$set": bson.M{videocreatermod.FN.VideoCreaterInfo.Slug: item.Slug},
})
updated++
}
return updated, more, nil
}
func syncVideoEmptySlugs(ctx context.Context, maxSize int64) (int64, bool, *srvdef.SrvErr) {
list, err := videoinformationmod.FindManyVideoInformations(ctx, slugx.EmptyFilter(), options.Find().SetLimit(maxSize+1))
if err != nil {
return 0, false, err
}
more := int64(len(list)) > maxSize
if more {
list = list[:maxSize]
}
var updated int64
for _, item := range list {
if item == nil {
continue
}
if serr := EnsureVideo(ctx, item, item.Id); serr != nil || strings.TrimSpace(item.Slug) == "" {
continue
}
_ = videoinformationmod.UpdateOneVideoInformation(ctx, bson.M{videoinformationmod.FN.VideoInformation.Id: item.Id}, bson.M{
"$set": bson.M{videoinformationmod.FN.VideoInformation.Slug: item.Slug},
})
updated++
}
return updated, more, nil
}