feat(admin): add watermark table list APIs (#44)

This commit is contained in:
root
2026-03-10 17:02:53 +08:00
parent 6f1f75d983
commit 2ddb2403e4
3 changed files with 562 additions and 0 deletions
+347
View File
@@ -0,0 +1,347 @@
package service
import (
"context"
"strings"
"time"
"wx_service/internal/model"
rmmodel "wx_service/internal/remove_watermark/model"
)
type ListVideoParseLogsQuery struct {
Page int
PageSize int
MiniProgramID uint
UserID uint
FreeQuotaUsed *bool
Keyword string
DateFrom *time.Time
DateTo *time.Time
}
type VideoParseLogItem struct {
ID uint `json:"id"`
MiniProgramID uint `json:"mini_program_id"`
MiniProgramName string `json:"mini_program_name"`
UserID uint `json:"user_id"`
RequestContent string `json:"request_content"`
ParsedURL string `json:"parsed_url"`
ThirdPartyStatus int `json:"third_party_status"`
FreeQuotaUsed bool `json:"free_quota_used"`
DurationMs int `json:"duration_ms"`
ErrorMessage string `json:"error_message"`
CreatedAt time.Time `json:"created_at"`
ThirdPartyPayload string `json:"third_party_payload"`
}
type ListVideoParseLogsResult struct {
List []VideoParseLogItem `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
type ListVideoParseUnlocksQuery struct {
Page int
PageSize int
MiniProgramID uint
UserID uint
DateFrom *time.Time
DateTo *time.Time
}
type VideoParseUnlockItem struct {
ID uint `json:"id"`
MiniProgramID uint `json:"mini_program_id"`
MiniProgramName string `json:"mini_program_name"`
UserID uint `json:"user_id"`
UnlockDate time.Time `json:"unlock_date"`
AdWatchedAt time.Time `json:"ad_watched_at"`
CreatedAt time.Time `json:"created_at"`
}
type ListVideoParseUnlocksResult struct {
List []VideoParseUnlockItem `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
type ListVideoDownloadFailuresQuery struct {
Page int
PageSize int
Domain string
Keyword string
DateFrom *time.Time
DateTo *time.Time
}
type VideoDownloadFailureItem struct {
ID uint `json:"id"`
Domain string `json:"domain"`
FailedURL string `json:"failed_url"`
ErrorMessage string `json:"error_message"`
ReportedAt time.Time `json:"reported_at"`
UserAgent string `json:"user_agent"`
ClientIP string `json:"client_ip"`
CreatedAt time.Time `json:"created_at"`
}
type ListVideoDownloadFailuresResult struct {
List []VideoDownloadFailureItem `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
func (s *Service) ListVideoParseLogs(ctx context.Context, query ListVideoParseLogsQuery) (*ListVideoParseLogsResult, error) {
query.Page, query.PageSize = normalizePage(query.Page, query.PageSize)
query.Keyword = strings.TrimSpace(query.Keyword)
dbQuery := s.db.WithContext(ctx).Model(&rmmodel.VideoParseLog{})
if query.MiniProgramID > 0 {
dbQuery = dbQuery.Where("mini_program_id = ?", query.MiniProgramID)
}
if query.UserID > 0 {
dbQuery = dbQuery.Where("user_id = ?", query.UserID)
}
if query.FreeQuotaUsed != nil {
dbQuery = dbQuery.Where("free_quota_used = ?", *query.FreeQuotaUsed)
}
if query.Keyword != "" {
likeKeyword := "%" + query.Keyword + "%"
dbQuery = dbQuery.Where("request_content LIKE ? OR parsed_url LIKE ? OR error_message LIKE ?", likeKeyword, likeKeyword, likeKeyword)
}
if query.DateFrom != nil {
dbQuery = dbQuery.Where("created_at >= ?", *query.DateFrom)
}
if query.DateTo != nil {
dbQuery = dbQuery.Where("created_at <= ?", *query.DateTo)
}
var total int64
if err := dbQuery.Count(&total).Error; err != nil {
return nil, err
}
rows := make([]rmmodel.VideoParseLog, 0)
if total > 0 {
if err := dbQuery.Order("id DESC").
Limit(query.PageSize).
Offset((query.Page - 1) * query.PageSize).
Find(&rows).Error; err != nil {
return nil, err
}
}
miniProgramNameMap, err := s.loadMiniProgramNameMap(ctx, extractMiniProgramIDsFromLogs(rows))
if err != nil {
return nil, err
}
items := make([]VideoParseLogItem, 0, len(rows))
for _, row := range rows {
items = append(items, VideoParseLogItem{
ID: row.ID,
MiniProgramID: row.MiniProgramID,
MiniProgramName: miniProgramNameMap[row.MiniProgramID],
UserID: row.UserID,
RequestContent: row.RequestContent,
ParsedURL: row.ParsedURL,
ThirdPartyStatus: row.ThirdPartyStatus,
FreeQuotaUsed: row.FreeQuotaUsed,
DurationMs: row.DurationMs,
ErrorMessage: row.ErrorMessage,
CreatedAt: row.CreatedAt,
ThirdPartyPayload: string(row.ThirdPartyPayload),
})
}
return &ListVideoParseLogsResult{
List: items,
Total: total,
Page: query.Page,
PageSize: query.PageSize,
}, nil
}
func (s *Service) ListVideoParseUnlocks(ctx context.Context, query ListVideoParseUnlocksQuery) (*ListVideoParseUnlocksResult, error) {
query.Page, query.PageSize = normalizePage(query.Page, query.PageSize)
dbQuery := s.db.WithContext(ctx).Model(&rmmodel.VideoParseUnlock{})
if query.MiniProgramID > 0 {
dbQuery = dbQuery.Where("mini_program_id = ?", query.MiniProgramID)
}
if query.UserID > 0 {
dbQuery = dbQuery.Where("user_id = ?", query.UserID)
}
if query.DateFrom != nil {
dbQuery = dbQuery.Where("unlock_date >= ?", query.DateFrom.Format("2006-01-02"))
}
if query.DateTo != nil {
dbQuery = dbQuery.Where("unlock_date <= ?", query.DateTo.Format("2006-01-02"))
}
var total int64
if err := dbQuery.Count(&total).Error; err != nil {
return nil, err
}
rows := make([]rmmodel.VideoParseUnlock, 0)
if total > 0 {
if err := dbQuery.Order("id DESC").
Limit(query.PageSize).
Offset((query.Page - 1) * query.PageSize).
Find(&rows).Error; err != nil {
return nil, err
}
}
miniProgramNameMap, err := s.loadMiniProgramNameMap(ctx, extractMiniProgramIDsFromUnlocks(rows))
if err != nil {
return nil, err
}
items := make([]VideoParseUnlockItem, 0, len(rows))
for _, row := range rows {
items = append(items, VideoParseUnlockItem{
ID: row.ID,
MiniProgramID: row.MiniProgramID,
MiniProgramName: miniProgramNameMap[row.MiniProgramID],
UserID: row.UserID,
UnlockDate: row.UnlockDate,
AdWatchedAt: row.AdWatchedAt,
CreatedAt: row.CreatedAt,
})
}
return &ListVideoParseUnlocksResult{
List: items,
Total: total,
Page: query.Page,
PageSize: query.PageSize,
}, nil
}
func (s *Service) ListVideoDownloadFailures(ctx context.Context, query ListVideoDownloadFailuresQuery) (*ListVideoDownloadFailuresResult, error) {
query.Page, query.PageSize = normalizePage(query.Page, query.PageSize)
query.Domain = strings.TrimSpace(query.Domain)
query.Keyword = strings.TrimSpace(query.Keyword)
dbQuery := s.db.WithContext(ctx).Model(&rmmodel.VideoDownloadFailure{})
if query.Domain != "" {
dbQuery = dbQuery.Where("domain = ?", query.Domain)
}
if query.Keyword != "" {
likeKeyword := "%" + query.Keyword + "%"
dbQuery = dbQuery.Where("failed_url LIKE ? OR error_message LIKE ? OR user_agent LIKE ?", likeKeyword, likeKeyword, likeKeyword)
}
if query.DateFrom != nil {
dbQuery = dbQuery.Where("reported_at >= ?", *query.DateFrom)
}
if query.DateTo != nil {
dbQuery = dbQuery.Where("reported_at <= ?", *query.DateTo)
}
var total int64
if err := dbQuery.Count(&total).Error; err != nil {
return nil, err
}
rows := make([]rmmodel.VideoDownloadFailure, 0)
if total > 0 {
if err := dbQuery.Order("id DESC").
Limit(query.PageSize).
Offset((query.Page - 1) * query.PageSize).
Find(&rows).Error; err != nil {
return nil, err
}
}
items := make([]VideoDownloadFailureItem, 0, len(rows))
for _, row := range rows {
items = append(items, VideoDownloadFailureItem{
ID: row.ID,
Domain: row.Domain,
FailedURL: row.FailedURL,
ErrorMessage: row.ErrorMessage,
ReportedAt: row.ReportedAt,
UserAgent: row.UserAgent,
ClientIP: row.ClientIP,
CreatedAt: row.CreatedAt,
})
}
return &ListVideoDownloadFailuresResult{
List: items,
Total: total,
Page: query.Page,
PageSize: query.PageSize,
}, nil
}
func (s *Service) loadMiniProgramNameMap(ctx context.Context, ids []uint) (map[uint]string, error) {
nameMap := map[uint]string{}
if len(ids) == 0 {
return nameMap, nil
}
rows := make([]model.MiniProgram, 0)
if err := s.db.WithContext(ctx).
Select("id", "name").
Where("id IN ?", ids).
Find(&rows).Error; err != nil {
return nil, err
}
for _, row := range rows {
nameMap[row.ID] = row.Name
}
return nameMap, nil
}
func extractMiniProgramIDsFromLogs(rows []rmmodel.VideoParseLog) []uint {
set := map[uint]struct{}{}
ids := make([]uint, 0, len(rows))
for _, row := range rows {
if row.MiniProgramID == 0 {
continue
}
if _, ok := set[row.MiniProgramID]; ok {
continue
}
set[row.MiniProgramID] = struct{}{}
ids = append(ids, row.MiniProgramID)
}
return ids
}
func extractMiniProgramIDsFromUnlocks(rows []rmmodel.VideoParseUnlock) []uint {
set := map[uint]struct{}{}
ids := make([]uint, 0, len(rows))
for _, row := range rows {
if row.MiniProgramID == 0 {
continue
}
if _, ok := set[row.MiniProgramID]; ok {
continue
}
set[row.MiniProgramID] = struct{}{}
ids = append(ids, row.MiniProgramID)
}
return ids
}
func normalizePage(page, pageSize int) (int, int) {
if page < 1 {
page = 1
}
if pageSize < 1 {
pageSize = 20
}
if pageSize > 100 {
pageSize = 100
}
return page, pageSize
}