585 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			585 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package cache
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/redis/go-redis/v9"
 | |
| 
 | |
| 	"tyapi-server/internal/domains/statistics/entities"
 | |
| )
 | |
| 
 | |
| // RedisStatisticsCache Redis统计缓存实现
 | |
| type RedisStatisticsCache struct {
 | |
| 	client *redis.Client
 | |
| 	prefix string
 | |
| }
 | |
| 
 | |
| // NewRedisStatisticsCache 创建Redis统计缓存
 | |
| func NewRedisStatisticsCache(client *redis.Client) *RedisStatisticsCache {
 | |
| 	return &RedisStatisticsCache{
 | |
| 		client: client,
 | |
| 		prefix: "statistics:",
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // ================ 指标缓存 ================
 | |
| 
 | |
| // SetMetric 设置指标缓存
 | |
| func (c *RedisStatisticsCache) SetMetric(ctx context.Context, metric *entities.StatisticsMetric, expiration time.Duration) error {
 | |
| 	if metric == nil {
 | |
| 		return fmt.Errorf("统计指标不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getMetricKey(metric.ID)
 | |
| 	data, err := json.Marshal(metric)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("序列化指标失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	err = c.client.Set(ctx, key, data, expiration).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("设置指标缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // GetMetric 获取指标缓存
 | |
| func (c *RedisStatisticsCache) GetMetric(ctx context.Context, metricID string) (*entities.StatisticsMetric, error) {
 | |
| 	if metricID == "" {
 | |
| 		return nil, fmt.Errorf("指标ID不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getMetricKey(metricID)
 | |
| 	data, err := c.client.Get(ctx, key).Result()
 | |
| 	if err != nil {
 | |
| 		if err == redis.Nil {
 | |
| 			return nil, nil // 缓存未命中
 | |
| 		}
 | |
| 		return nil, fmt.Errorf("获取指标缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	var metric entities.StatisticsMetric
 | |
| 	err = json.Unmarshal([]byte(data), &metric)
 | |
| 	if err != nil {
 | |
| 		return nil, fmt.Errorf("反序列化指标失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return &metric, nil
 | |
| }
 | |
| 
 | |
| // DeleteMetric 删除指标缓存
 | |
| func (c *RedisStatisticsCache) DeleteMetric(ctx context.Context, metricID string) error {
 | |
| 	if metricID == "" {
 | |
| 		return fmt.Errorf("指标ID不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getMetricKey(metricID)
 | |
| 	err := c.client.Del(ctx, key).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("删除指标缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // SetMetricsByType 设置按类型分组的指标缓存
 | |
| func (c *RedisStatisticsCache) SetMetricsByType(ctx context.Context, metricType string, metrics []*entities.StatisticsMetric, expiration time.Duration) error {
 | |
| 	if metricType == "" {
 | |
| 		return fmt.Errorf("指标类型不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getMetricsByTypeKey(metricType)
 | |
| 	data, err := json.Marshal(metrics)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("序列化指标列表失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	err = c.client.Set(ctx, key, data, expiration).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("设置指标列表缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // GetMetricsByType 获取按类型分组的指标缓存
 | |
| func (c *RedisStatisticsCache) GetMetricsByType(ctx context.Context, metricType string) ([]*entities.StatisticsMetric, error) {
 | |
| 	if metricType == "" {
 | |
| 		return nil, fmt.Errorf("指标类型不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getMetricsByTypeKey(metricType)
 | |
| 	data, err := c.client.Get(ctx, key).Result()
 | |
| 	if err != nil {
 | |
| 		if err == redis.Nil {
 | |
| 			return nil, nil // 缓存未命中
 | |
| 		}
 | |
| 		return nil, fmt.Errorf("获取指标列表缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	var metrics []*entities.StatisticsMetric
 | |
| 	err = json.Unmarshal([]byte(data), &metrics)
 | |
| 	if err != nil {
 | |
| 		return nil, fmt.Errorf("反序列化指标列表失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return metrics, nil
 | |
| }
 | |
| 
 | |
| // DeleteMetricsByType 删除按类型分组的指标缓存
 | |
| func (c *RedisStatisticsCache) DeleteMetricsByType(ctx context.Context, metricType string) error {
 | |
| 	if metricType == "" {
 | |
| 		return fmt.Errorf("指标类型不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getMetricsByTypeKey(metricType)
 | |
| 	err := c.client.Del(ctx, key).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("删除指标列表缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ================ 实时指标缓存 ================
 | |
| 
 | |
| // SetRealtimeMetrics 设置实时指标缓存
 | |
| func (c *RedisStatisticsCache) SetRealtimeMetrics(ctx context.Context, metricType string, metrics map[string]float64, expiration time.Duration) error {
 | |
| 	if metricType == "" {
 | |
| 		return fmt.Errorf("指标类型不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getRealtimeMetricsKey(metricType)
 | |
| 	data, err := json.Marshal(metrics)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("序列化实时指标失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	err = c.client.Set(ctx, key, data, expiration).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("设置实时指标缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // GetRealtimeMetrics 获取实时指标缓存
 | |
| func (c *RedisStatisticsCache) GetRealtimeMetrics(ctx context.Context, metricType string) (map[string]float64, error) {
 | |
| 	if metricType == "" {
 | |
| 		return nil, fmt.Errorf("指标类型不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getRealtimeMetricsKey(metricType)
 | |
| 	data, err := c.client.Get(ctx, key).Result()
 | |
| 	if err != nil {
 | |
| 		if err == redis.Nil {
 | |
| 			return nil, nil // 缓存未命中
 | |
| 		}
 | |
| 		return nil, fmt.Errorf("获取实时指标缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	var metrics map[string]float64
 | |
| 	err = json.Unmarshal([]byte(data), &metrics)
 | |
| 	if err != nil {
 | |
| 		return nil, fmt.Errorf("反序列化实时指标失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return metrics, nil
 | |
| }
 | |
| 
 | |
| // UpdateRealtimeMetric 更新实时指标
 | |
| func (c *RedisStatisticsCache) UpdateRealtimeMetric(ctx context.Context, metricType, metricName string, value float64, expiration time.Duration) error {
 | |
| 	if metricType == "" || metricName == "" {
 | |
| 		return fmt.Errorf("指标类型和名称不能为空")
 | |
| 	}
 | |
| 
 | |
| 	// 获取现有指标
 | |
| 	metrics, err := c.GetRealtimeMetrics(ctx, metricType)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("获取实时指标失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	if metrics == nil {
 | |
| 		metrics = make(map[string]float64)
 | |
| 	}
 | |
| 
 | |
| 	// 更新指标值
 | |
| 	metrics[metricName] = value
 | |
| 
 | |
| 	// 保存更新后的指标
 | |
| 	err = c.SetRealtimeMetrics(ctx, metricType, metrics, expiration)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("更新实时指标失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ================ 报告缓存 ================
 | |
| 
 | |
| // SetReport 设置报告缓存
 | |
| func (c *RedisStatisticsCache) SetReport(ctx context.Context, report *entities.StatisticsReport, expiration time.Duration) error {
 | |
| 	if report == nil {
 | |
| 		return fmt.Errorf("统计报告不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getReportKey(report.ID)
 | |
| 	data, err := json.Marshal(report)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("序列化报告失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	err = c.client.Set(ctx, key, data, expiration).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("设置报告缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // GetReport 获取报告缓存
 | |
| func (c *RedisStatisticsCache) GetReport(ctx context.Context, reportID string) (*entities.StatisticsReport, error) {
 | |
| 	if reportID == "" {
 | |
| 		return nil, fmt.Errorf("报告ID不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getReportKey(reportID)
 | |
| 	data, err := c.client.Get(ctx, key).Result()
 | |
| 	if err != nil {
 | |
| 		if err == redis.Nil {
 | |
| 			return nil, nil // 缓存未命中
 | |
| 		}
 | |
| 		return nil, fmt.Errorf("获取报告缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	var report entities.StatisticsReport
 | |
| 	err = json.Unmarshal([]byte(data), &report)
 | |
| 	if err != nil {
 | |
| 		return nil, fmt.Errorf("反序列化报告失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return &report, nil
 | |
| }
 | |
| 
 | |
| // DeleteReport 删除报告缓存
 | |
| func (c *RedisStatisticsCache) DeleteReport(ctx context.Context, reportID string) error {
 | |
| 	if reportID == "" {
 | |
| 		return fmt.Errorf("报告ID不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getReportKey(reportID)
 | |
| 	err := c.client.Del(ctx, key).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("删除报告缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ================ 仪表板缓存 ================
 | |
| 
 | |
| // SetDashboard 设置仪表板缓存
 | |
| func (c *RedisStatisticsCache) SetDashboard(ctx context.Context, dashboard *entities.StatisticsDashboard, expiration time.Duration) error {
 | |
| 	if dashboard == nil {
 | |
| 		return fmt.Errorf("统计仪表板不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getDashboardKey(dashboard.ID)
 | |
| 	data, err := json.Marshal(dashboard)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("序列化仪表板失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	err = c.client.Set(ctx, key, data, expiration).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("设置仪表板缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // GetDashboard 获取仪表板缓存
 | |
| func (c *RedisStatisticsCache) GetDashboard(ctx context.Context, dashboardID string) (*entities.StatisticsDashboard, error) {
 | |
| 	if dashboardID == "" {
 | |
| 		return nil, fmt.Errorf("仪表板ID不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getDashboardKey(dashboardID)
 | |
| 	data, err := c.client.Get(ctx, key).Result()
 | |
| 	if err != nil {
 | |
| 		if err == redis.Nil {
 | |
| 			return nil, nil // 缓存未命中
 | |
| 		}
 | |
| 		return nil, fmt.Errorf("获取仪表板缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	var dashboard entities.StatisticsDashboard
 | |
| 	err = json.Unmarshal([]byte(data), &dashboard)
 | |
| 	if err != nil {
 | |
| 		return nil, fmt.Errorf("反序列化仪表板失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return &dashboard, nil
 | |
| }
 | |
| 
 | |
| // DeleteDashboard 删除仪表板缓存
 | |
| func (c *RedisStatisticsCache) DeleteDashboard(ctx context.Context, dashboardID string) error {
 | |
| 	if dashboardID == "" {
 | |
| 		return fmt.Errorf("仪表板ID不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getDashboardKey(dashboardID)
 | |
| 	err := c.client.Del(ctx, key).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("删除仪表板缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // SetDashboardData 设置仪表板数据缓存
 | |
| func (c *RedisStatisticsCache) SetDashboardData(ctx context.Context, userRole string, data interface{}, expiration time.Duration) error {
 | |
| 	if userRole == "" {
 | |
| 		return fmt.Errorf("用户角色不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getDashboardDataKey(userRole)
 | |
| 	jsonData, err := json.Marshal(data)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("序列化仪表板数据失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	err = c.client.Set(ctx, key, jsonData, expiration).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("设置仪表板数据缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // GetDashboardData 获取仪表板数据缓存
 | |
| func (c *RedisStatisticsCache) GetDashboardData(ctx context.Context, userRole string) (interface{}, error) {
 | |
| 	if userRole == "" {
 | |
| 		return nil, fmt.Errorf("用户角色不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getDashboardDataKey(userRole)
 | |
| 	data, err := c.client.Get(ctx, key).Result()
 | |
| 	if err != nil {
 | |
| 		if err == redis.Nil {
 | |
| 			return nil, nil // 缓存未命中
 | |
| 		}
 | |
| 		return nil, fmt.Errorf("获取仪表板数据缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	var result interface{}
 | |
| 	err = json.Unmarshal([]byte(data), &result)
 | |
| 	if err != nil {
 | |
| 		return nil, fmt.Errorf("反序列化仪表板数据失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return result, nil
 | |
| }
 | |
| 
 | |
| // DeleteDashboardData 删除仪表板数据缓存
 | |
| func (c *RedisStatisticsCache) DeleteDashboardData(ctx context.Context, userRole string) error {
 | |
| 	if userRole == "" {
 | |
| 		return fmt.Errorf("用户角色不能为空")
 | |
| 	}
 | |
| 
 | |
| 	key := c.getDashboardDataKey(userRole)
 | |
| 	err := c.client.Del(ctx, key).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("删除仪表板数据缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ================ 缓存键生成 ================
 | |
| 
 | |
| // getMetricKey 获取指标缓存键
 | |
| func (c *RedisStatisticsCache) getMetricKey(metricID string) string {
 | |
| 	return c.prefix + "metric:" + metricID
 | |
| }
 | |
| 
 | |
| // getMetricsByTypeKey 获取按类型分组的指标缓存键
 | |
| func (c *RedisStatisticsCache) getMetricsByTypeKey(metricType string) string {
 | |
| 	return c.prefix + "metrics:type:" + metricType
 | |
| }
 | |
| 
 | |
| // getRealtimeMetricsKey 获取实时指标缓存键
 | |
| func (c *RedisStatisticsCache) getRealtimeMetricsKey(metricType string) string {
 | |
| 	return c.prefix + "realtime:" + metricType
 | |
| }
 | |
| 
 | |
| // getReportKey 获取报告缓存键
 | |
| func (c *RedisStatisticsCache) getReportKey(reportID string) string {
 | |
| 	return c.prefix + "report:" + reportID
 | |
| }
 | |
| 
 | |
| // getDashboardKey 获取仪表板缓存键
 | |
| func (c *RedisStatisticsCache) getDashboardKey(dashboardID string) string {
 | |
| 	return c.prefix + "dashboard:" + dashboardID
 | |
| }
 | |
| 
 | |
| // getDashboardDataKey 获取仪表板数据缓存键
 | |
| func (c *RedisStatisticsCache) getDashboardDataKey(userRole string) string {
 | |
| 	return c.prefix + "dashboard:data:" + userRole
 | |
| }
 | |
| 
 | |
| // ================ 批量操作 ================
 | |
| 
 | |
| // BatchDeleteMetrics 批量删除指标缓存
 | |
| func (c *RedisStatisticsCache) BatchDeleteMetrics(ctx context.Context, metricIDs []string) error {
 | |
| 	if len(metricIDs) == 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	keys := make([]string, len(metricIDs))
 | |
| 	for i, id := range metricIDs {
 | |
| 		keys[i] = c.getMetricKey(id)
 | |
| 	}
 | |
| 
 | |
| 	err := c.client.Del(ctx, keys...).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("批量删除指标缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // BatchDeleteReports 批量删除报告缓存
 | |
| func (c *RedisStatisticsCache) BatchDeleteReports(ctx context.Context, reportIDs []string) error {
 | |
| 	if len(reportIDs) == 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	keys := make([]string, len(reportIDs))
 | |
| 	for i, id := range reportIDs {
 | |
| 		keys[i] = c.getReportKey(id)
 | |
| 	}
 | |
| 
 | |
| 	err := c.client.Del(ctx, keys...).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("批量删除报告缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // BatchDeleteDashboards 批量删除仪表板缓存
 | |
| func (c *RedisStatisticsCache) BatchDeleteDashboards(ctx context.Context, dashboardIDs []string) error {
 | |
| 	if len(dashboardIDs) == 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	keys := make([]string, len(dashboardIDs))
 | |
| 	for i, id := range dashboardIDs {
 | |
| 		keys[i] = c.getDashboardKey(id)
 | |
| 	}
 | |
| 
 | |
| 	err := c.client.Del(ctx, keys...).Err()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("批量删除仪表板缓存失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ================ 缓存清理 ================
 | |
| 
 | |
| // ClearAllStatisticsCache 清理所有统计缓存
 | |
| func (c *RedisStatisticsCache) ClearAllStatisticsCache(ctx context.Context) error {
 | |
| 	pattern := c.prefix + "*"
 | |
| 	keys, err := c.client.Keys(ctx, pattern).Result()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("获取缓存键失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	if len(keys) > 0 {
 | |
| 		err = c.client.Del(ctx, keys...).Err()
 | |
| 		if err != nil {
 | |
| 			return fmt.Errorf("清理统计缓存失败: %w", err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ClearMetricsCache 清理指标缓存
 | |
| func (c *RedisStatisticsCache) ClearMetricsCache(ctx context.Context) error {
 | |
| 	pattern := c.prefix + "metric:*"
 | |
| 	keys, err := c.client.Keys(ctx, pattern).Result()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("获取指标缓存键失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	if len(keys) > 0 {
 | |
| 		err = c.client.Del(ctx, keys...).Err()
 | |
| 		if err != nil {
 | |
| 			return fmt.Errorf("清理指标缓存失败: %w", err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ClearRealtimeCache 清理实时缓存
 | |
| func (c *RedisStatisticsCache) ClearRealtimeCache(ctx context.Context) error {
 | |
| 	pattern := c.prefix + "realtime:*"
 | |
| 	keys, err := c.client.Keys(ctx, pattern).Result()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("获取实时缓存键失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	if len(keys) > 0 {
 | |
| 		err = c.client.Del(ctx, keys...).Err()
 | |
| 		if err != nil {
 | |
| 			return fmt.Errorf("清理实时缓存失败: %w", err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ClearReportsCache 清理报告缓存
 | |
| func (c *RedisStatisticsCache) ClearReportsCache(ctx context.Context) error {
 | |
| 	pattern := c.prefix + "report:*"
 | |
| 	keys, err := c.client.Keys(ctx, pattern).Result()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("获取报告缓存键失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	if len(keys) > 0 {
 | |
| 		err = c.client.Del(ctx, keys...).Err()
 | |
| 		if err != nil {
 | |
| 			return fmt.Errorf("清理报告缓存失败: %w", err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ClearDashboardsCache 清理仪表板缓存
 | |
| func (c *RedisStatisticsCache) ClearDashboardsCache(ctx context.Context) error {
 | |
| 	pattern := c.prefix + "dashboard:*"
 | |
| 	keys, err := c.client.Keys(ctx, pattern).Result()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("获取仪表板缓存键失败: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	if len(keys) > 0 {
 | |
| 		err = c.client.Del(ctx, keys...).Err()
 | |
| 		if err != nil {
 | |
| 			return fmt.Errorf("清理仪表板缓存失败: %w", err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 |