313 lines
7.5 KiB
Go
313 lines
7.5 KiB
Go
package sourcemod
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"91porn-server/app/appg"
|
|
"91porn-server/common"
|
|
"91porn-server/common/cachev2"
|
|
"91porn-server/common/constant/redisconst"
|
|
"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.Source
|
|
|
|
const (
|
|
pingListCacheKey = "source:ping-list:v1"
|
|
pingListCacheTTL = time.Minute
|
|
)
|
|
|
|
type pingListCache struct {
|
|
Domains []string `json:"domains"`
|
|
Sources []*SourceRes `json:"sources"`
|
|
}
|
|
|
|
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: "type", Value: 1}},
|
|
Options: options.Index().SetUnique(true).SetSparse(true),
|
|
},
|
|
{
|
|
Keys: bson.D{{Key: "domain", Value: 1}},
|
|
},
|
|
{
|
|
Keys: bson.D{{Key: "isActive", 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))
|
|
}
|
|
}
|
|
|
|
// PingList 返回
|
|
func PingList() (rd []string, rs []*SourceRes) {
|
|
// 域名配置体积较大且更新频率低,通过共享缓存避免每次启动请求都读取 MongoDB。
|
|
result := pingListCache{}
|
|
_, err := cachev2.Classes().
|
|
CacheTime(pingListCacheTTL).
|
|
Key(pingListCacheKey).
|
|
ResBind(&result).
|
|
Cache(loadPingList)
|
|
if err != nil {
|
|
log.Error("PingList cache error", log.E(err))
|
|
result = loadPingList()
|
|
}
|
|
return result.Domains, result.Sources
|
|
}
|
|
|
|
func loadPingList() pingListCache {
|
|
return buildPingList(List())
|
|
}
|
|
|
|
func buildPingList(data []*SourceRes) pingListCache {
|
|
if len(data) == 0 {
|
|
return pingListCache{}
|
|
}
|
|
dataLen := len(data)
|
|
d := make([]string, 0, dataLen)
|
|
s := make([]*SourceRes, 0, dataLen)
|
|
for _, v := range data {
|
|
switch v.Type {
|
|
case Ping:
|
|
for _, v := range v.Domain {
|
|
d = append(d, v.Url)
|
|
}
|
|
case Image, Audio, Common, Group, Telegram, Guide, PROXYRULE, FAQ, QRCODE, WELFARE, ACT, PromoteURL, AppStore, BusinessCooperation, ShareURL, PreSaleBgImg:
|
|
s = append(s, v)
|
|
case Vid:
|
|
s = append(s, v)
|
|
}
|
|
}
|
|
d = d[:len(d):len(d)]
|
|
s = s[:len(s):len(s)]
|
|
return pingListCache{Domains: d, Sources: s}
|
|
}
|
|
|
|
func clearPingListCache() {
|
|
if _, err := cachev2.Classes().Delete(pingListCacheKey); err != nil {
|
|
log.Error("clear PingList cache error", log.E(err))
|
|
}
|
|
}
|
|
|
|
// GetCdnURL GetCdnURL
|
|
func GetCdnURL() (rd []Domain) {
|
|
data := List()
|
|
if len(data) == 0 {
|
|
return
|
|
}
|
|
var d []Domain
|
|
for _, v := range data {
|
|
switch v.Type {
|
|
case Common, Vid:
|
|
d = append(d, v.Domain...)
|
|
}
|
|
}
|
|
rd = d
|
|
return
|
|
}
|
|
|
|
// List 返回
|
|
func List() (array []*SourceRes) {
|
|
if err := coll(nil).Find(&array, bson.M{"isActive": true}); err != nil {
|
|
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "List", table, "Find", err))
|
|
}
|
|
return
|
|
}
|
|
|
|
// List 返回
|
|
func WebList() (array []*SourceRes) {
|
|
if err := coll(nil).Find(&array, bson.M{}); err != nil {
|
|
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "WebList", table, "Find", err))
|
|
}
|
|
return
|
|
}
|
|
|
|
// GetCustomerStat 获取客服状态
|
|
func GetCustomerStat() bool {
|
|
var s *SourceRes
|
|
if err := coll(nil).FindOne(&s, bson.M{"type": Customer}); err != nil {
|
|
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCustomerStat", table, "FindOne", err))
|
|
return true
|
|
}
|
|
if s == nil {
|
|
return true
|
|
}
|
|
return s.IsActive
|
|
}
|
|
|
|
// 随机获取推广页域名
|
|
func GetRandomPromotionURL() string {
|
|
if cnt, err := appg.Redis.SCard(redisconst.LandDomainCacheKey); cnt == 0 || err != nil {
|
|
purls := GetPromoteURLArray()
|
|
if len(purls) > 0 {
|
|
_, _ = appg.Redis.SAdd(redisconst.LandDomainCacheKey, purls)
|
|
}
|
|
}
|
|
purl, err := appg.Redis.SRandMember(redisconst.LandDomainCacheKey)
|
|
if err != nil {
|
|
return getPromoteURL()
|
|
}
|
|
return purl
|
|
}
|
|
|
|
// 获取推广url数组
|
|
func GetPromoteURLArray() []string {
|
|
data := GetPromoteURLList()
|
|
purls := make([]string, 0)
|
|
if data != nil {
|
|
purls = make([]string, 0, len(data.Domain))
|
|
for _, v := range data.Domain {
|
|
purls = append(purls, v.Url)
|
|
}
|
|
}
|
|
return purls
|
|
}
|
|
|
|
// GetPromoteURLList 返回
|
|
func GetPromoteURLList() (data *SourceWebRes) {
|
|
if err := coll(nil).FindOne(&data, bson.M{"type": PromoteURL, "isActive": true}); err != nil {
|
|
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetPromoteURLList", table, "FindOne", err))
|
|
}
|
|
return
|
|
}
|
|
|
|
// getPromoteURL 返回
|
|
func getPromoteURL() string {
|
|
var s *SourceRes
|
|
if err := coll(nil).FindOne(&s, bson.M{"type": PromoteURL, "isActive": true}); err != nil {
|
|
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "getPromoteURL", table, "FindOne", err))
|
|
}
|
|
if s != nil {
|
|
return s.Domain[0].Url
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Insert SourceInsert
|
|
func Insert(s *Source) error {
|
|
s.UpdatedAt = time.Now()
|
|
s.CreatedAt = time.Now()
|
|
if _, err := coll(nil).InsertOne(&s); err != nil {
|
|
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Insert", table, "InsertOne", err))
|
|
return err
|
|
}
|
|
clearPingListCache()
|
|
return nil
|
|
}
|
|
|
|
// Update 修改
|
|
func Update(id primitive.ObjectID, sType SourceType, set *SourceEdit) error {
|
|
set.UpdatedAt = time.Now()
|
|
if _, err := coll(nil).UpdateOne(bson.M{"_id": id, "type": sType}, bson.M{"$set": set}); err != nil {
|
|
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateOne", err),
|
|
log.Any("id", id),
|
|
log.Any("sType", sType),
|
|
log.Any("set", set),
|
|
)
|
|
return err
|
|
}
|
|
clearPingListCache()
|
|
return nil
|
|
}
|
|
|
|
// EditDomain 修改
|
|
func EditDomain(id primitive.ObjectID, edit *SourceEdit) error {
|
|
edit.UpdatedAt = time.Now()
|
|
update, _ := common.ToBsonM(edit)
|
|
if _, err := coll(nil).UpdateOne(bson.M{"_id": id}, bson.M{"$set": update}); err != nil {
|
|
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "EditDomain", table, "UpdateOne", err),
|
|
log.Any("id", id),
|
|
log.Any("edit", *edit),
|
|
)
|
|
return err
|
|
}
|
|
clearPingListCache()
|
|
return nil
|
|
}
|
|
|
|
// Remove SourceRemove
|
|
func Remove(ids []primitive.ObjectID) error {
|
|
if _, err := coll(nil).DeleteMany(bson.M{"_id": bson.M{"$in": ids}}); err != nil {
|
|
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Remove", table, "DeleteMany", err),
|
|
log.Any("ids", ids),
|
|
)
|
|
return err
|
|
}
|
|
clearPingListCache()
|
|
return nil
|
|
}
|
|
|
|
func GetWeightCdnURL() string {
|
|
var cho []common.Choice
|
|
data, err := appg.Redis.Get(redisconst.CdnCacheKey)
|
|
//不存在cdn缓存
|
|
if err != nil || data == nil {
|
|
var choice []common.Choice
|
|
cdn := GetCdnURL()
|
|
for _, v := range cdn {
|
|
if v.Weight == 0 {
|
|
continue
|
|
}
|
|
choice = append(choice, common.Choice{Weight: int(v.Weight), Item: v.Url})
|
|
}
|
|
cbyte, _ := json.Marshal(choice)
|
|
_ = appg.Redis.Set(redisconst.CdnCacheKey, cbyte, redisconst.CdnCacheExpire)
|
|
c, err := common.WeightedChoice(choice)
|
|
if err != nil {
|
|
if len(cdn) > 0 {
|
|
return cdn[0].Url
|
|
}
|
|
}
|
|
return c.Item.(string)
|
|
}
|
|
_ = json.Unmarshal([]byte(*data), &cho)
|
|
c, _ := common.WeightedChoice(cho)
|
|
return c.Item.(string)
|
|
}
|
|
|
|
func GetVideoAndImgCdn() (videoCdn []string, imgCdn []string) {
|
|
data := List()
|
|
if len(data) == 0 {
|
|
return
|
|
}
|
|
dataLen := len(data)
|
|
videoCdn = make([]string, 0, dataLen)
|
|
imgCdn = make([]string, 0, dataLen)
|
|
for _, v := range data {
|
|
if v.Type == Vid {
|
|
for _, d := range v.Domain {
|
|
videoCdn = append(videoCdn, d.Url)
|
|
}
|
|
}
|
|
if v.Type == Image {
|
|
for _, d := range v.Domain {
|
|
imgCdn = append(imgCdn, d.Url)
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|