feat: add async image task API
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# Generated by Django 5.2.15 on 2026-07-08 13:44
|
||||
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('billing', '0007_alter_pointsledger_change_type_signupbonusgrant'),
|
||||
('users', '0005_alter_apikey_created_at_alter_apikey_key_hash_and_more'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ImageGenerationTask',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('task_id', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='任务 ID')),
|
||||
('status', models.CharField(choices=[('queued', '排队中'), ('running', '处理中'), ('succeeded', '成功'), ('failed', '失败'), ('expired', '已过期')], default='queued', max_length=20, verbose_name='状态')),
|
||||
('idempotency_key', models.CharField(blank=True, max_length=128, verbose_name='幂等键')),
|
||||
('idempotency_key_hash', models.CharField(blank=True, editable=False, max_length=64, null=True, verbose_name='幂等键哈希')),
|
||||
('request_hash', models.CharField(max_length=64, verbose_name='请求哈希')),
|
||||
('request_payload', models.JSONField(blank=True, default=dict, verbose_name='请求快照')),
|
||||
('input_image', models.FileField(blank=True, upload_to='generated/task_inputs/%Y/%m/%d/', verbose_name='输入图片')),
|
||||
('result_url', models.TextField(blank=True, verbose_name='结果 URL')),
|
||||
('error_code', models.CharField(blank=True, max_length=64, verbose_name='错误码')),
|
||||
('error_message', models.TextField(blank=True, verbose_name='错误信息')),
|
||||
('points_balance_after_charge', models.BigIntegerField(default=0, verbose_name='扣费后余额')),
|
||||
('started_at', models.DateTimeField(blank=True, null=True, verbose_name='开始时间')),
|
||||
('finished_at', models.DateTimeField(blank=True, null=True, verbose_name='完成时间')),
|
||||
('expires_at', models.DateTimeField(blank=True, null=True, verbose_name='任务元数据过期时间')),
|
||||
('locked_at', models.DateTimeField(blank=True, null=True, verbose_name='锁定时间')),
|
||||
('lease_expires_at', models.DateTimeField(blank=True, null=True, verbose_name='租约过期时间')),
|
||||
('heartbeat_at', models.DateTimeField(blank=True, null=True, verbose_name='心跳时间')),
|
||||
('worker_id', models.CharField(blank=True, max_length=128, verbose_name='Worker ID')),
|
||||
('attempt_count', models.PositiveIntegerField(default=0, verbose_name='尝试次数')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
|
||||
('api_key', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='image_generation_tasks', to='users.apikey', verbose_name='API 密钥')),
|
||||
('call_record', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='image_generation_task', to='billing.callrecord', verbose_name='调用记录')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='image_generation_tasks', to=settings.AUTH_USER_MODEL, verbose_name='用户')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '图片生成任务',
|
||||
'verbose_name_plural': '图片生成任务',
|
||||
'db_table': 'image_generation_task',
|
||||
'ordering': ('-created_at', '-id'),
|
||||
'indexes': [models.Index(fields=['user', 'created_at'], name='image_gener_user_id_1e7164_idx'), models.Index(fields=['api_key', 'created_at'], name='image_gener_api_key_30d9ad_idx'), models.Index(fields=['status', 'created_at'], name='image_gener_status_727db2_idx'), models.Index(fields=['status', 'lease_expires_at'], name='image_gener_status_7a7bd1_idx'), models.Index(fields=['worker_id', 'status'], name='image_gener_worker__f9e534_idx'), models.Index(fields=['expires_at'], name='image_gener_expires_545a78_idx')],
|
||||
'constraints': [models.UniqueConstraint(fields=('api_key', 'idempotency_key_hash'), name='unique_image_task_idempotency_hash_per_api_key'), models.CheckConstraint(condition=models.Q(('points_balance_after_charge__gte', 0)), name='image_task_balance_after_charge_non_negative')],
|
||||
},
|
||||
),
|
||||
]
|
||||
Reference in New Issue
Block a user