Files
AIGC/demo/POINTS_FREEZE_SYSTEM_README.md
AIGC Developer 1e71ae6a26 feat: 系统优化和功能完善
主要更新:
- 调整并发配置为50人(数据库连接池30,Tomcat线程150,异步线程池5/20)
- 实现无界阻塞队列(LinkedBlockingQueue)任务处理
- 实现分镜视频保存功能(保存到uploads目录)
- 统一管理页面导航栏和右上角样式
- 添加日活用户统计功能
- 优化视频拼接和保存逻辑
- 添加部署文档和快速部署指南
- 更新.gitignore排除敏感配置文件
2025-11-07 19:09:50 +08:00

7.0 KiB
Raw Blame History

积分冻结系统

概述

积分冻结系统实现了任务提交时冻结积分、任务完成时扣除、任务失败时返还的完整积分管理流程。

系统特性

🔒 积分状态管理

  • 正常积分: 用户可以自由使用的积分
  • 冻结积分: 任务提交时临时冻结的积分,不可使用
  • 可用积分: 正常积分 - 冻结积分

📋 冻结记录管理

  • 完整的积分冻结记录追踪
  • 支持多种冻结状态:已冻结、已扣除、已返还、已过期
  • 自动处理过期冻结记录24小时

自动积分处理

  • 任务提交: 自动冻结相应积分
  • 任务完成: 自动扣除冻结积分
  • 任务失败: 自动返还冻结积分
  • 任务取消: 自动返还冻结积分
  • 任务超时: 自动返还冻结积分

数据库结构

用户表修改

-- 添加冻结积分字段
ALTER TABLE users ADD COLUMN frozen_points INT NOT NULL DEFAULT 0 COMMENT '冻结积分';

积分冻结记录表

CREATE TABLE points_freeze_records (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(100) NOT NULL COMMENT '用户名',
    task_id VARCHAR(50) NOT NULL UNIQUE COMMENT '任务ID',
    task_type ENUM('TEXT_TO_VIDEO', 'IMAGE_TO_VIDEO') NOT NULL COMMENT '任务类型',
    freeze_points INT NOT NULL COMMENT '冻结的积分数量',
    status ENUM('FROZEN', 'DEDUCTED', 'RETURNED', 'EXPIRED') NOT NULL DEFAULT 'FROZEN' COMMENT '冻结状态',
    freeze_reason VARCHAR(200) COMMENT '冻结原因',
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    completed_at DATETIME COMMENT '完成时间'
);

API接口

获取积分信息

GET /api/points/info
Authorization: Bearer <token>

Response:
{
  "success": true,
  "data": {
    "totalPoints": 1000,
    "frozenPoints": 80,
    "availablePoints": 920
  }
}

获取冻结记录

GET /api/points/freeze-records
Authorization: Bearer <token>

Response:
{
  "success": true,
  "data": [
    {
      "id": 1,
      "username": "user1",
      "taskId": "txt2vid_123",
      "taskType": "TEXT_TO_VIDEO",
      "freezePoints": 80,
      "status": "FROZEN",
      "freezeReason": "任务提交冻结积分 - 文生视频",
      "createdAt": "2024-01-01T10:00:00",
      "updatedAt": "2024-01-01T10:00:00"
    }
  ]
}

处理过期记录(管理员)

POST /api/points/process-expired
Authorization: Bearer <token>

Response:
{
  "success": true,
  "message": "处理过期记录完成",
  "processedCount": 5
}

服务方法

UserService 积分冻结方法

冻结积分

PointsFreezeRecord freezePoints(String username, String taskId, 
    PointsFreezeRecord.TaskType taskType, Integer points, String reason)

扣除冻结积分(任务完成)

void deductFrozenPoints(String taskId)

返还冻结积分(任务失败)

void returnFrozenPoints(String taskId)

获取可用积分

Integer getAvailablePoints(String username)

获取冻结积分

Integer getFrozenPoints(String username)

获取冻结记录

List<PointsFreezeRecord> getPointsFreezeRecords(String username)

处理过期记录

int processExpiredFrozenRecords()

积分计算规则

默认积分消耗

  • 文生视频: 80积分
  • 图生视频: 90积分

积分检查逻辑

  1. 检查用户可用积分是否足够
  2. 冻结相应积分
  3. 创建冻结记录
  4. 添加到任务队列

定时任务

过期记录处理

  • 频率: 每小时执行一次
  • 功能: 自动处理超过24小时的冻结记录
  • 处理方式: 返还冻结积分,更新记录状态为"已过期"

工作流程

1. 任务提交流程

用户提交任务 → 检查可用积分 → 冻结积分 → 创建冻结记录 → 添加到队列

2. 任务完成流程

任务完成 → 扣除冻结积分 → 更新冻结记录状态 → 更新原始任务状态

3. 任务失败流程

任务失败 → 返还冻结积分 → 更新冻结记录状态 → 更新原始任务状态

4. 任务取消流程

用户取消任务 → 返还冻结积分 → 更新冻结记录状态 → 更新原始任务状态

异常处理

积分不足

  • 检查可用积分时如果不足,抛出异常
  • 异常信息包含当前可用积分和所需积分

冻结记录不存在

  • 扣除或返还积分时如果记录不存在,抛出异常
  • 确保数据一致性

状态不正确

  • 操作冻结记录时检查状态是否正确
  • 防止重复操作

监控和日志

关键日志

  • 积分冻结成功/失败
  • 积分扣除成功/失败
  • 积分返还成功/失败
  • 过期记录处理

监控指标

  • 冻结积分总量
  • 过期记录数量
  • 积分操作成功率

安全考虑

数据一致性

  • 使用事务确保积分和记录状态一致
  • 防止并发操作导致的数据不一致

权限控制

  • 只有任务所有者可以操作相关积分
  • 管理员可以处理过期记录

异常恢复

  • 完善的异常处理机制
  • 自动重试和恢复机制

扩展功能

未来可扩展的功能

  1. 动态积分计算: 根据任务参数动态计算所需积分
  2. 积分优惠: 会员等级影响积分消耗
  3. 积分返还策略: 不同失败原因的不同返还策略
  4. 积分统计: 详细的积分使用统计和分析
  5. 积分预警: 积分不足时的预警机制

使用示例

前端集成示例

// 获取用户积分信息
const getPointsInfo = async () => {
  const response = await fetch('/api/points/info', {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });
  const data = await response.json();
  return data.data;
};

// 获取冻结记录
const getFreezeRecords = async () => {
  const response = await fetch('/api/points/freeze-records', {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });
  const data = await response.json();
  return data.data;
};

后端集成示例

// 在任务创建时自动冻结积分
@Transactional
public TaskQueue addTextToVideoTask(String username, String taskId) {
    // 计算所需积分
    Integer requiredPoints = calculateRequiredPoints(TaskQueue.TaskType.TEXT_TO_VIDEO);
    
    // 冻结积分
    userService.freezePoints(username, taskId, 
        PointsFreezeRecord.TaskType.TEXT_TO_VIDEO, requiredPoints, 
        "任务提交冻结积分 - 文生视频");
    
    // 添加到队列
    return addTaskToQueue(username, taskId, TaskQueue.TaskType.TEXT_TO_VIDEO);
}

注意事项

  1. 积分检查: 在冻结积分前必须检查可用积分是否足够
  2. 状态管理: 确保冻结记录状态与任务状态保持一致
  3. 异常处理: 完善的异常处理确保积分不会丢失
  4. 定时清理: 定期清理过期的冻结记录
  5. 监控告警: 监控积分冻结系统的运行状态