新应用aitool:POST /api/aitool/upscale(登录扣2积分、事务行锁防并发超扣,失败退款+failed记录);产物存MEDIA_ROOT/aitool/upscale,返回可下载URL;provider默认本地Pillow,第三方网关走环境变量不落库。
57 lines
2.4 KiB
Python
57 lines
2.4 KiB
Python
"""C-04 AI 工具:图片放大(upscale)最小闭环。
|
||
|
||
设计:
|
||
- Provider 抽象:BaseProvider + PillowProvider(本地 LANCZOS 2x/4x,
|
||
零 key、零外部依赖,mock 链路即生产链路)+ HTTPProvider(预留第三方网关,
|
||
baseURL/key 全走环境变量,绝不落库、不进响应)。
|
||
- 钱包打通:调用前按 AITOOL_UPSCALE_COST 扣积分(事务 + 行锁),处理失败自动回滚。
|
||
- 产物存储:MEDIA_ROOT/aitool/upscale/,返回可下载 URL。
|
||
- 与钱包打通仅做方案不落地计费:真实扣费走积分(存量 PointTransaction),
|
||
不引入支付网关;y币/现金计费留待商业化评审(见 PROGRESS_C-04)。
|
||
"""
|
||
from django.conf import settings
|
||
from django.db import models
|
||
|
||
|
||
class AIToolRecord(models.Model):
|
||
TOOL_CHOICES = [
|
||
('upscale', '图片放大'),
|
||
('matting', '抠图(预留)'),
|
||
('id-photo', '证件照(预留)'),
|
||
('text2img', '文生图(预留)'),
|
||
]
|
||
STATUS_CHOICES = [
|
||
('success', '成功'),
|
||
('failed', '失败'),
|
||
('refunded', '已回滚'),
|
||
]
|
||
|
||
user = models.ForeignKey(
|
||
settings.AUTH_USER_MODEL,
|
||
on_delete=models.SET_NULL,
|
||
null=True,
|
||
blank=True,
|
||
related_name='aitool_records',
|
||
verbose_name='用户',
|
||
)
|
||
tool = models.CharField(max_length=20, choices=TOOL_CHOICES, default='upscale', verbose_name='工具')
|
||
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='success', verbose_name='状态')
|
||
cost = models.IntegerField(default=0, verbose_name='扣减积分')
|
||
scale = models.IntegerField(default=2, verbose_name='放大倍数')
|
||
input_size = models.BigIntegerField(default=0, verbose_name='输入字节')
|
||
output_size = models.BigIntegerField(default=0, verbose_name='输出字节')
|
||
file_path = models.CharField(max_length=500, blank=True, default='', verbose_name='产物路径')
|
||
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||
|
||
class Meta:
|
||
ordering = ['-created_at']
|
||
verbose_name = 'AI工具调用记录'
|
||
verbose_name_plural = 'AI工具调用记录'
|
||
indexes = [
|
||
models.Index(fields=['user', '-created_at']),
|
||
models.Index(fields=['tool', '-created_at']),
|
||
]
|
||
|
||
def __str__(self):
|
||
return f'{self.tool} x{self.scale} ({self.status})'
|