Files
1818web-hoduan/POINTS_AND_MODELS_SUMMARY.md
2025-11-14 17:41:15 +08:00

13 KiB
Raw Blame History

积分系统与AI模型管理完整功能总结

📋 目录

  1. 积分消费查询功能
  2. AI模型列表查询功能
  3. 数据库迁移脚本
  4. API接口列表
  5. 前端调用示例

1. 积分消费查询功能

功能概述

用户可以查看自己的积分余额、消费明细和统计信息。

核心接口

1.1 获取积分余额

GET /user/points/consumption/balance
Authorization: Bearer {token}

响应示例:

{
  "code": 200,
  "message": "success",
  "data": {
    "currentPoints": 1500,
    "pointsExpiresAt": "2025-12-31T23:59:59",
    "willExpireSoon": false,
    "daysUntilExpire": 120
  }
}

1.2 获取积分消费记录(分页)

GET /user/points/consumption/logs?page=1&size=10&changeType=consume
Authorization: Bearer {token}

参数说明:

  • page: 页码默认1
  • size: 每页数量默认10最大100
  • changeType: 变动类型(可选)
    • recharge: 充值
    • consume: 消费
    • refund: 退款
    • admin_adjust: 管理员调整

响应示例:

{
  "code": 200,
  "message": "success",
  "data": {
    "records": [
      {
        "id": 1,
        "taskNo": "TASK202510221234567890",
        "changeType": "consume",
        "changeTypeName": "消费",
        "changeAmount": -10,
        "balanceBefore": 1510,
        "balanceAfter": 1500,
        "description": "AI图片生成消费",
        "createTime": "2025-10-22T10:30:00"
      }
    ],
    "total": 100,
    "page": 1,
    "size": 10,
    "totalPages": 10
  }
}

1.3 获取积分统计

GET /user/points/consumption/stats
Authorization: Bearer {token}

响应示例:

{
  "code": 200,
  "message": "success",
  "data": {
    "currentPoints": 1500,
    "totalRechargePoints": 2000,
    "totalConsumePoints": 500,
    "totalRefundPoints": 0,
    "pointsExpiresAt": "2025-12-31T23:59:59"
  }
}

2. AI模型列表查询功能

功能概述

用户可以查看系统中所有可用的AI模型支持按任务类型、厂商分组查询。

任务类型分类

细致分类(数据库 task_type 字段)

  • text_to_image: 文生图
  • image_to_image: 图生图
  • text_to_video: 文生视频
  • image_to_video: 图生视频
  • llm: 大语言模型
  • text_to_audio: 文生音频
  • image_to_text: 图生文
  • other: 其他

粗略分类(兼容旧接口)

  • image: 图片生成(包括 text_to_image 和 image_to_image
  • video: 视频生成(包括 text_to_video 和 image_to_video
  • audio: 音频生成
  • text: 文本生成

核心接口

2.1 获取模型列表(支持筛选)

GET /user/ai/models?taskType=text_to_image&provider=openai&enabledOnly=true

参数说明:

  • taskType: 任务类型(可选)
  • provider: 服务提供商可选openai/runninghub
  • enabledOnly: 是否只返回已启用的模型默认true

响应示例:

{
  "code": 200,
  "message": "success",
  "data": [
    {
      "id": 1,
      "modelName": "sora_image",
      "displayName": "Sora高质量图片生成",
      "description": "Sora高质量图片生成",
      "pointsCost": 11,
      "providerType": "openai",
      "taskType": "text_to_image",
      "isEnabled": true,
      "extendedConfig": {}
    }
  ]
}

2.2 按任务类型分组获取模型

GET /user/ai/models/group-by-type?provider=&enabledOnly=true

响应示例:

{
  "code": 200,
  "message": "success",
  "data": [
    {
      "taskType": "text_to_image",
      "taskTypeName": "文生图",
      "models": [
        {
          "id": 1,
          "modelName": "sora_image",
          "displayName": "Sora高质量图片生成",
          "pointsCost": 11,
          "providerType": "openai",
          "taskType": "text_to_image",
          "isEnabled": true
        }
      ],
      "count": 2
    },
    {
      "taskType": "text_to_video",
      "taskTypeName": "文生视频",
      "models": [...],
      "count": 4
    }
  ]
}

2.3 按厂商分组获取模型

GET /user/ai/models/group-by-provider?taskType=&enabledOnly=true

响应示例:

{
  "code": 200,
  "message": "success",
  "data": [
    {
      "providerType": "openai",
      "providerName": "OpenAI",
      "models": [...],
      "count": 3
    },
    {
      "providerType": "runninghub",
      "providerName": "RunningHub",
      "models": [...],
      "count": 5
    }
  ]
}

2.4 获取模型统计

GET /user/ai/models/stats

响应示例:

{
  "code": 200,
  "message": "success",
  "data": {
    "totalModels": 10,
    "enabledModels": 8,
    "countByType": {
      "text_to_image": 2,
      "text_to_video": 4,
      "image_to_video": 1,
      "llm": 1
    },
    "countByProvider": {
      "openai": 3,
      "runninghub": 5
    }
  }
}

3. 数据库迁移脚本

V6: 积分充值系统

  • 创建 points_package 表(积分套餐)
  • 扩展 order 表支持积分订单
  • 更新 points_consumption_log 表支持充值类型

V7: 任务类型细分

  • points_config 表添加 task_type 字段
  • 根据现有模型名称更新任务类型
  • 添加多种模型类型示例数据
  • 添加索引优化查询性能

4. API接口列表

4.1 积分消费查询(需要登录)

接口 方法 路径 说明
获取积分余额 GET /user/points/consumption/balance 当前积分和过期时间
获取消费记录 GET /user/points/consumption/logs 分页查询消费明细
获取积分统计 GET /user/points/consumption/stats 累计充值、消费、退款

4.2 AI模型查询公开访问

接口 方法 路径 说明
获取模型列表 GET /user/ai/models 支持筛选和过滤
按类型分组 GET /user/ai/models/group-by-type 按任务类型分组
按厂商分组 GET /user/ai/models/group-by-provider 按服务提供商分组
获取统计信息 GET /user/ai/models/stats 模型数量统计

5. 前端调用示例

5.1 Vue 3 + TypeScript 示例

// api/points.ts
import request from '@/utils/request'

// 获取积分余额
export function getPointsBalance() {
  return request({
    url: '/user/points/consumption/balance',
    method: 'get'
  })
}

// 获取积分消费记录
export function getConsumptionLogs(params: {
  page?: number
  size?: number
  changeType?: 'recharge' | 'consume' | 'refund' | 'admin_adjust'
}) {
  return request({
    url: '/user/points/consumption/logs',
    method: 'get',
    params
  })
}

// 获取积分统计
export function getConsumptionStats() {
  return request({
    url: '/user/points/consumption/stats',
    method: 'get'
  })
}

// api/models.ts
import request from '@/utils/request'

// 获取所有模型
export function getAllModels(params: {
  taskType?: string
  provider?: string
  enabledOnly?: boolean
}) {
  return request({
    url: '/user/ai/models',
    method: 'get',
    params
  })
}

// 按类型分组获取模型
export function getModelsByType(params: {
  provider?: string
  enabledOnly?: boolean
}) {
  return request({
    url: '/user/ai/models/group-by-type',
    method: 'get',
    params
  })
}

// 按厂商分组获取模型
export function getModelsByProvider(params: {
  taskType?: string
  enabledOnly?: boolean
}) {
  return request({
    url: '/user/ai/models/group-by-provider',
    method: 'get',
    params
  })
}

// 获取模型统计
export function getModelStats() {
  return request({
    url: '/user/ai/models/stats',
    method: 'get'
  })
}

5.2 React 示例

// hooks/usePoints.ts
import { useState, useEffect } from 'react'
import { getPointsBalance, getConsumptionLogs } from '@/api/points'

export function usePointsBalance() {
  const [balance, setBalance] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    getPointsBalance().then(res => {
      setBalance(res.data)
      setLoading(false)
    })
  }, [])

  return { balance, loading }
}

// hooks/useModels.ts
import { useState, useEffect } from 'react'
import { getModelsByType } from '@/api/models'

export function useModelsByType(provider?: string) {
  const [models, setModels] = useState([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    getModelsByType({ provider, enabledOnly: true }).then(res => {
      setModels(res.data)
      setLoading(false)
    })
  }, [provider])

  return { models, loading }
}

5.3 使用场景示例

<!-- PointsBalance.vue -->
<template>
  <div class="points-balance">
    <div class="balance-card">
      <h3>当前积分</h3>
      <p class="points">{{ balance?.currentPoints || 0 }}</p>
      <p class="expire-info" v-if="balance?.pointsExpiresAt">
        {{ balance.willExpireSoon ? '即将过期' : '有效期至' }}
        {{ formatDate(balance.pointsExpiresAt) }}
      </p>
    </div>
    
    <div class="consumption-logs">
      <h3>消费记录</h3>
      <div v-for="log in logs.records" :key="log.id" class="log-item">
        <span>{{ log.changeTypeName }}</span>
        <span>{{ log.description }}</span>
        <span :class="log.changeAmount > 0 ? 'increase' : 'decrease'">
          {{ log.changeAmount > 0 ? '+' : '' }}{{ log.changeAmount }}
        </span>
        <span>{{ formatDate(log.createTime) }}</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { getPointsBalance, getConsumptionLogs } from '@/api/points'

const balance = ref(null)
const logs = ref({ records: [], total: 0 })

onMounted(async () => {
  const [balanceRes, logsRes] = await Promise.all([
    getPointsBalance(),
    getConsumptionLogs({ page: 1, size: 10 })
  ])
  balance.value = balanceRes.data
  logs.value = logsRes.data
})
</script>
<!-- ModelSelector.vue -->
<template>
  <div class="model-selector">
    <div class="filter">
      <select v-model="selectedType">
        <option value="">全部类型</option>
        <option value="text_to_image">文生图</option>
        <option value="text_to_video">文生视频</option>
        <option value="image_to_video">图生视频</option>
      </select>
      
      <select v-model="selectedProvider">
        <option value="">全部厂商</option>
        <option value="openai">OpenAI</option>
        <option value="runninghub">RunningHub</option>
      </select>
    </div>
    
    <div class="models-grid">
      <div v-for="model in filteredModels" :key="model.id" class="model-card">
        <h4>{{ model.displayName }}</h4>
        <p>{{ model.description }}</p>
        <div class="model-footer">
          <span class="cost">{{ model.pointsCost }} 积分</span>
          <span class="provider">{{ model.providerType }}</span>
        </div>
        <button @click="selectModel(model)">选择</button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { getAllModels } from '@/api/models'

const selectedType = ref('')
const selectedProvider = ref('')
const allModels = ref([])

const filteredModels = computed(() => {
  return allModels.value.filter(model => {
    const typeMatch = !selectedType.value || model.taskType === selectedType.value
    const providerMatch = !selectedProvider.value || model.providerType === selectedProvider.value
    return typeMatch && providerMatch
  })
})

onMounted(async () => {
  const res = await getAllModels({ enabledOnly: true })
  allModels.value = res.data
})

const selectModel = (model) => {
  // 选择模型逻辑
  console.log('Selected model:', model)
}
</script>

📌 总结

已实现功能

  1. 用户积分余额查询
  2. 用户积分消费记录查询(分页、筛选)
  3. 用户积分统计信息
  4. AI模型列表查询支持筛选
  5. 按任务类型分组查询模型
  6. 按厂商分组查询模型
  7. 模型统计信息

技术特点

  • 支持细致的任务类型分类(文生图、图生图、图生视频等)
  • 向后兼容粗略分类image、video等
  • 公开访问的模型列表接口,无需登录
  • 需要登录的积分查询接口,保护用户隐私
  • 完整的分页支持
  • 灵活的筛选和分组功能

数据库优化

  • 添加 task_type 字段用于精确分类
  • 添加索引提升查询性能
  • 支持逻辑删除

安全性

  • 积分相关接口需要用户认证
  • 模型列表接口公开访问,方便前端展示
  • 完整的权限控制配置

文档版本: v1.0
最后更新: 2025-10-22