103 lines
3.2 KiB
Go
103 lines
3.2 KiB
Go
package service
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"fmt"
|
||
"log"
|
||
"net/url"
|
||
"strings"
|
||
|
||
"affiliate_dash/internal/model"
|
||
)
|
||
|
||
// TokenPackageLinkResult 是 Token 所属上游打包页面的定位链接。
|
||
type TokenPackageLinkResult struct {
|
||
PackageID int64 `json:"package_id"`
|
||
ShareCode string `json:"share_code"`
|
||
URL string `json:"url"`
|
||
}
|
||
|
||
// TokenPackageLink 返回 Token 所属上游包页面的跳转链接。
|
||
// 只对本地已保存分享码的新包生效;历史包不向上游反查。
|
||
func (s *RockService) TokenPackageLink(ctx context.Context, tokenID uint) (*TokenPackageLinkResult, error) {
|
||
var token model.RockToken
|
||
if err := s.db.WithContext(ctx).First(&token, tokenID).Error; err != nil {
|
||
return nil, err
|
||
}
|
||
if token.PackageID == nil || *token.PackageID <= 0 {
|
||
return nil, errors.New("该 Token 没有关联上游打包记录,无法跳转上游")
|
||
}
|
||
cfg, err := s.GetConfig(ctx)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
shareCode := strings.TrimSpace(token.PackageShareCode)
|
||
if shareCode == "" {
|
||
shareCode, err = s.resolvePackageShareCode(ctx, *token.PackageID, cfg.BearerToken)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
// 反查成功后回填同包 Token,后续点击无需再请求上游。
|
||
if updateErr := s.db.WithContext(ctx).Model(&model.RockToken{}).
|
||
Where("package_id = ? AND package_share_code = ''", *token.PackageID).
|
||
Update("package_share_code", shareCode).Error; updateErr != nil {
|
||
log.Printf("[RockService] 回填 package_share_code 失败 package_id=%d: %v", *token.PackageID, updateErr)
|
||
}
|
||
}
|
||
|
||
base := strings.TrimRight(strings.TrimSpace(cfg.BaseURL), "/")
|
||
if base == "" {
|
||
base = model.RockDefaultBaseURL
|
||
}
|
||
|
||
return &TokenPackageLinkResult{
|
||
PackageID: *token.PackageID,
|
||
ShareCode: shareCode,
|
||
URL: fmt.Sprintf("%s/#/package/%s", base, url.PathEscape(shareCode)),
|
||
}, nil
|
||
}
|
||
|
||
// resolvePackageShareCode 在本地没有分享码时,按 package_id 从上游包列表反查。
|
||
// 历史 Token 只落了 package_id,package_share_code 是后续版本才开始保存的。
|
||
func (s *RockService) resolvePackageShareCode(ctx context.Context, packageID int64, bearerToken string) (string, error) {
|
||
if packageID <= 0 {
|
||
return "", errors.New("该 Token 没有关联上游打包记录,无法跳转上游")
|
||
}
|
||
bearer := strings.TrimSpace(bearerToken)
|
||
if bearer == "" {
|
||
return "", errors.New("该 Token 缺少上游包分享码,且未配置 0666.pro Bearer Token,无法反查上游包")
|
||
}
|
||
// 最多翻 20 页,防止上游分页异常导致死循环。
|
||
for page := 1; page <= 20; page++ {
|
||
resp, err := s.client.ListPackages(ctx, bearer, page, 100)
|
||
if err != nil {
|
||
return "", fmt.Errorf("反查上游包分享码失败: %w", err)
|
||
}
|
||
if resp == nil {
|
||
break
|
||
}
|
||
for _, pkg := range resp.Packages {
|
||
if pkg.ID != packageID {
|
||
continue
|
||
}
|
||
code := strings.TrimSpace(pkg.ShareCode)
|
||
if code == "" {
|
||
return "", errors.New("上游该包未返回分享码,无法跳转上游")
|
||
}
|
||
return code, nil
|
||
}
|
||
if resp.Pagination.TotalPages > 0 {
|
||
if page >= resp.Pagination.TotalPages {
|
||
break
|
||
}
|
||
continue
|
||
}
|
||
if len(resp.Packages) == 0 {
|
||
break
|
||
}
|
||
}
|
||
return "", errors.New("上游未找到该 Token 所属打包记录(可能已被清理),无法跳转上游")
|
||
}
|