@@ -0,0 +1,161 @@
|
||||
package activityclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"91porn-server/app/appg"
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/httputil"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models/v/usermod"
|
||||
"91porn-server/models/v/walletmod"
|
||||
)
|
||||
|
||||
const (
|
||||
ReplaceDomain = "https://activity.domain.com"
|
||||
)
|
||||
|
||||
// DomainItem 活动服域名项(与 activity-public-server 的 /api/app/domains 返回结构一致)
|
||||
type DomainItem struct {
|
||||
Domain string `json:"domain"` // 域名
|
||||
Remark string `json:"remark"` // 备注
|
||||
}
|
||||
|
||||
// domainsResp 活动服域名接口响应
|
||||
type domainsResp struct {
|
||||
Code int `json:"code"`
|
||||
Data []DomainItem `json:"data"`
|
||||
}
|
||||
|
||||
var (
|
||||
cachedDomains []DomainItem
|
||||
domainsMu sync.RWMutex
|
||||
)
|
||||
|
||||
// GetActivityDomains 获取缓存的活动服域名列表
|
||||
func GetActivityDomains() []DomainItem {
|
||||
domainsMu.RLock()
|
||||
defer domainsMu.RUnlock()
|
||||
return cachedDomains
|
||||
}
|
||||
|
||||
// GetActivityDomain 随机获取一个可用的活动服域名
|
||||
func GetActivityDomain() string {
|
||||
domainsMu.RLock()
|
||||
defer domainsMu.RUnlock()
|
||||
n := len(cachedDomains)
|
||||
if n > 0 {
|
||||
return cachedDomains[rand.Intn(n)].Domain
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ReplaceActivityDomain 替换活动服占位域名,并追加授权参数 appId、sign
|
||||
func ReplaceActivityDomain(rawURL string, user *usermod.User, w *walletmod.Wallet) string {
|
||||
if !strings.Contains(rawURL, ReplaceDomain) {
|
||||
return rawURL
|
||||
}
|
||||
domain := GetActivityDomain()
|
||||
if domain == "" {
|
||||
return rawURL
|
||||
}
|
||||
rawURL = strings.ReplaceAll(rawURL, ReplaceDomain, domain)
|
||||
|
||||
if user == nil {
|
||||
return rawURL
|
||||
}
|
||||
|
||||
conf := appg.Conf.ActivityServer
|
||||
now := time.Now()
|
||||
rechargeAmount := 0
|
||||
if w != nil {
|
||||
rechargeAmount = int(w.Consumption)
|
||||
}
|
||||
payload := &SignPayload{
|
||||
AppId: conf.AppId,
|
||||
UserId: strconv.FormatUint(user.UID, 10),
|
||||
Nickname: user.Name,
|
||||
Avatar: user.Portrait,
|
||||
Ts: now.Unix(),
|
||||
RegisteredAt: user.CreatedAt.Unix(),
|
||||
RechargeAmount: rechargeAmount,
|
||||
}
|
||||
sign, err := EncryptSign(conf.SecretKey, payload)
|
||||
if err != nil {
|
||||
log.Error("活动服-生成签名失败", log.E(err))
|
||||
return rawURL
|
||||
}
|
||||
|
||||
if strings.Contains(rawURL, "?") {
|
||||
rawURL += "&inner=1&appId=" + conf.AppId + "&sign=" + sign
|
||||
} else {
|
||||
rawURL += "?inner=1&appId=" + conf.AppId + "&sign=" + sign
|
||||
}
|
||||
return rawURL
|
||||
}
|
||||
|
||||
var hrefRe = regexp.MustCompile(`href="([^"]*)"`)
|
||||
|
||||
// ReplaceActivityDomainInHTML 替换富文本 HTML 中所有 href 里的活动服占位域名
|
||||
func ReplaceActivityDomainInHTML(htmlStr string, user *usermod.User, w *walletmod.Wallet) string {
|
||||
if !strings.Contains(htmlStr, ReplaceDomain) {
|
||||
return htmlStr
|
||||
}
|
||||
return hrefRe.ReplaceAllStringFunc(htmlStr, func(match string) string {
|
||||
url := match[6 : len(match)-1] // 去掉 href=" 前缀和 " 后缀
|
||||
return `href="` + ReplaceActivityDomain(url, user, w) + `"`
|
||||
})
|
||||
}
|
||||
|
||||
// startDomainSync 定时拉取活动服域名(每5分钟)
|
||||
func startDomainSync() {
|
||||
fetchDomains()
|
||||
common.Go(func() {
|
||||
ticker := time.NewTicker(5 * time.Minute)
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
fetchDomains()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// fetchDomains 从活动服拉取可用域名列表
|
||||
func fetchDomains() {
|
||||
conf := appg.Conf.ActivityServer
|
||||
apiUrl := conf.ApiUrl
|
||||
if apiUrl == "" {
|
||||
return
|
||||
}
|
||||
|
||||
const path = "/api/app/domains"
|
||||
url := apiUrl + path
|
||||
headers := BuildSvcHeaders(conf.AppId, conf.SecretKey, "GET", path, "", nil)
|
||||
_, body, err := httputil.DefaultClientGetBytes(url, headers)
|
||||
if err != nil {
|
||||
log.Error("活动服-拉取域名列表失败", log.Any("url", url), log.E(err))
|
||||
return
|
||||
}
|
||||
|
||||
var resp domainsResp
|
||||
if err := json.Unmarshal(body, &resp); err != nil {
|
||||
log.Error("活动服-解析域名列表失败", log.Any("body", string(body)), log.E(err))
|
||||
return
|
||||
}
|
||||
|
||||
if resp.Code != 200 {
|
||||
log.Warn("活动服-域名列表返回非成功状态", log.Any("code", resp.Code))
|
||||
return
|
||||
}
|
||||
|
||||
domainsMu.Lock()
|
||||
cachedDomains = resp.Data
|
||||
domainsMu.Unlock()
|
||||
|
||||
log.Info("活动服-域名列表更新成功", log.Any("count", len(resp.Data)))
|
||||
}
|
||||
Reference in New Issue
Block a user