162 lines
3.9 KiB
Go
162 lines
3.9 KiB
Go
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)))
|
|
}
|