重新迁移

This commit is contained in:
wanjia 2025-05-29 17:26:37 +08:00
parent 7898219d2c
commit a0ef3312d9
47 changed files with 199 additions and 1073 deletions

View File

@ -1,4 +1,4 @@
# Generated by Django 5.1.5 on 2025-05-19 08:40 # Generated by Django 5.2.1 on 2025-05-29 09:24
import django.db.models.deletion import django.db.models.deletion
import uuid import uuid
@ -36,7 +36,6 @@ class Migration(migrations.Migration):
options={ options={
'verbose_name': '品牌', 'verbose_name': '品牌',
'verbose_name_plural': '品牌', 'verbose_name_plural': '品牌',
'db_table': 'brands',
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
@ -68,13 +67,12 @@ class Migration(migrations.Migration):
options={ options={
'verbose_name': '产品', 'verbose_name': '产品',
'verbose_name_plural': '产品', 'verbose_name_plural': '产品',
'db_table': 'products',
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
name='Campaign', name='Campaign',
fields=[ fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='活动名称')), ('name', models.CharField(max_length=255, verbose_name='活动名称')),
('description', models.TextField(blank=True, null=True, verbose_name='活动描述')), ('description', models.TextField(blank=True, null=True, verbose_name='活动描述')),
('image_url', models.CharField(blank=True, max_length=255, null=True, verbose_name='活动图片')), ('image_url', models.CharField(blank=True, max_length=255, null=True, verbose_name='活动图片')),
@ -104,7 +102,6 @@ class Migration(migrations.Migration):
options={ options={
'verbose_name': '活动', 'verbose_name': '活动',
'verbose_name_plural': '活动', 'verbose_name_plural': '活动',
'db_table': 'campaigns',
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
@ -122,25 +119,24 @@ class Migration(migrations.Migration):
options={ options={
'verbose_name': '品牌聊天会话', 'verbose_name': '品牌聊天会话',
'verbose_name_plural': '品牌聊天会话', 'verbose_name_plural': '品牌聊天会话',
'db_table': 'brand_chat_sessions', 'indexes': [models.Index(fields=['brand'], name='brands_bran_brand_i_d22614_idx'), models.Index(fields=['session_id'], name='brands_bran_session_574261_idx'), models.Index(fields=['created_at'], name='brands_bran_created_c31416_idx')],
'indexes': [models.Index(fields=['brand'], name='brand_chat__brand_i_83752e_idx'), models.Index(fields=['session_id'], name='brand_chat__session_4bf9b0_idx'), models.Index(fields=['created_at'], name='brand_chat__created_957266_idx')],
}, },
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='product', model_name='product',
index=models.Index(fields=['brand'], name='products_brand_i_0d1950_idx'), index=models.Index(fields=['brand'], name='brands_prod_brand_i_e0821d_idx'),
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='product', model_name='product',
index=models.Index(fields=['dataset_id'], name='products_dataset_faf62a_idx'), index=models.Index(fields=['dataset_id'], name='brands_prod_dataset_c7f534_idx'),
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='product', model_name='product',
index=models.Index(fields=['is_active'], name='products_is_acti_cb485f_idx'), index=models.Index(fields=['is_active'], name='brands_prod_is_acti_fd82c6_idx'),
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='product', model_name='product',
index=models.Index(fields=['pid'], name='products_pid_99aab2_idx'), index=models.Index(fields=['pid'], name='brands_prod_pid_452ccb_idx'),
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='product', name='product',
@ -148,27 +144,27 @@ class Migration(migrations.Migration):
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='campaign', model_name='campaign',
index=models.Index(fields=['brand'], name='campaigns_brand_i_c2d4bd_idx'), index=models.Index(fields=['brand'], name='brands_camp_brand_i_51f26d_idx'),
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='campaign', model_name='campaign',
index=models.Index(fields=['dataset_id'], name='campaigns_dataset_bfbb68_idx'), index=models.Index(fields=['dataset_id'], name='brands_camp_dataset_9b31e4_idx'),
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='campaign', model_name='campaign',
index=models.Index(fields=['is_active'], name='campaigns_is_acti_6c57d0_idx'), index=models.Index(fields=['is_active'], name='brands_camp_is_acti_c09fdb_idx'),
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='campaign', model_name='campaign',
index=models.Index(fields=['start_date'], name='campaigns_start_d_5c2c6b_idx'), index=models.Index(fields=['start_date'], name='brands_camp_start_d_42e603_idx'),
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='campaign', model_name='campaign',
index=models.Index(fields=['end_date'], name='campaigns_end_dat_6aaba4_idx'), index=models.Index(fields=['end_date'], name='brands_camp_end_dat_97d26b_idx'),
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='campaign', model_name='campaign',
index=models.Index(fields=['status'], name='campaigns_status_a03570_idx'), index=models.Index(fields=['status'], name='brands_camp_status_41d2f4_idx'),
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='campaign', name='campaign',

View File

@ -1,18 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-19 10:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('brands', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='campaign',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
]

View File

@ -1,7 +1,6 @@
# Generated by Django 5.2 on 2025-05-07 03:40 # Generated by Django 5.2.1 on 2025-05-29 09:24
import django.db.models.deletion import django.db.models.deletion
import uuid
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -16,24 +15,6 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.CreateModel(
name='ConversationSummary',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('talent_email', models.EmailField(max_length=254, verbose_name='达人邮箱')),
('conversation_id', models.CharField(max_length=100, verbose_name='对话ID')),
('summary', models.TextField(verbose_name='对话总结')),
('is_active', models.BooleanField(default=True, verbose_name='是否激活')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='conversation_summaries', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': '对话总结',
'verbose_name_plural': '对话总结',
'db_table': 'conversation_summaries',
},
),
migrations.CreateModel( migrations.CreateModel(
name='ChatHistory', name='ChatHistory',
fields=[ fields=[
@ -51,9 +32,8 @@ class Migration(migrations.Migration):
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
], ],
options={ options={
'db_table': 'chat_history',
'ordering': ['created_at'], 'ordering': ['created_at'],
'indexes': [models.Index(fields=['conversation_id', 'created_at'], name='chat_histor_convers_33721a_idx'), models.Index(fields=['user', 'created_at'], name='chat_histor_user_id_aa050a_idx'), models.Index(fields=['conversation_id', 'is_deleted'], name='chat_histor_convers_89bc43_idx')], 'indexes': [models.Index(fields=['conversation_id', 'created_at'], name='chat_chathi_convers_90ca0c_idx'), models.Index(fields=['user', 'created_at'], name='chat_chathi_user_id_326d36_idx'), models.Index(fields=['conversation_id', 'is_deleted'], name='chat_chathi_convers_bcd094_idx')],
}, },
), ),
] ]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2 on 2025-05-15 10:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('chat', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='chathistory',
name='content',
field=models.TextField(help_text='消息内容,支持存储长文本', max_length=65535),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2 on 2025-05-20 09:21
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('chat', '0002_alter_chathistory_content'),
]
operations = [
migrations.AlterField(
model_name='chathistory',
name='content',
field=models.TextField(),
),
]

View File

@ -1,39 +0,0 @@
# Generated by Django 5.2 on 2025-05-21 04:30
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('chat', '0003_alter_chathistory_content'),
]
operations = [
migrations.RemoveField(
model_name='conversationsummary',
name='user',
),
migrations.RenameIndex(
model_name='chathistory',
new_name='chat_chathi_convers_90ca0c_idx',
old_name='chat_histor_convers_33721a_idx',
),
migrations.RenameIndex(
model_name='chathistory',
new_name='chat_chathi_user_id_326d36_idx',
old_name='chat_histor_user_id_aa050a_idx',
),
migrations.RenameIndex(
model_name='chathistory',
new_name='chat_chathi_convers_bcd094_idx',
old_name='chat_histor_convers_89bc43_idx',
),
migrations.AlterModelTable(
name='chathistory',
table=None,
),
migrations.DeleteModel(
name='ConversationSummary',
),
]

View File

@ -1,6 +1,7 @@
# Generated by Django 5.1.5 on 2025-05-19 08:40 # Generated by Django 5.2.1 on 2025-05-29 09:24
import django.db.models.deletion import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -10,7 +11,7 @@ class Migration(migrations.Migration):
dependencies = [ dependencies = [
('brands', '0001_initial'), ('brands', '0001_initial'),
('user', '0002_remove_user_is_active'), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
] ]
operations = [ operations = [
@ -19,12 +20,23 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='达人名称')), ('name', models.CharField(max_length=255, verbose_name='达人名称')),
('avatar', models.ImageField(blank=True, null=True, upload_to='avatars/', verbose_name='头像图片')),
('avatar_url', models.TextField(blank=True, null=True, verbose_name='头像URL')), ('avatar_url', models.TextField(blank=True, null=True, verbose_name='头像URL')),
('platform_id', models.CharField(blank=True, max_length=255, null=True, verbose_name='Platform ID')),
('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='电子邮箱')), ('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='电子邮箱')),
('instagram', models.CharField(blank=True, max_length=255, null=True, verbose_name='Instagram账号')), ('instagram', models.CharField(blank=True, max_length=255, null=True, verbose_name='Instagram账号')),
('tiktok_link', models.URLField(blank=True, max_length=255, null=True, verbose_name='TikTok链接')),
('location', models.CharField(blank=True, max_length=100, null=True, verbose_name='位置')), ('location', models.CharField(blank=True, max_length=100, null=True, verbose_name='位置')),
('live_schedule', models.CharField(blank=True, max_length=255, null=True, verbose_name='直播时间表')), ('live_schedule', models.CharField(blank=True, max_length=255, null=True, verbose_name='直播时间表')),
('profile', models.CharField(choices=[('tiktok', 'TikTok'), ('instagram', 'Instagram'), ('youtube', 'YouTube'), ('other', '其他平台')], default='tiktok', max_length=20, verbose_name='达人平台')),
('hashtags', models.TextField(blank=True, help_text='以#分隔的标签,例如:#fashion#beauty#lifestyle', null=True, verbose_name='标签')),
('trends', models.TextField(blank=True, help_text='创作者相关的趋势关键词', null=True, verbose_name='趋势')),
('region', models.CharField(blank=True, max_length=100, null=True, verbose_name='地区')),
('tiktok_link', models.URLField(blank=True, max_length=500, null=True, verbose_name='主页链接')),
('us_creator_level', models.CharField(blank=True, max_length=50, null=True, verbose_name='对标美区达人等级')),
('price_gbp', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='报价(英镑)')),
('price_usd', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='报价(美金)')),
('gmv_gbp', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='GMV(英镑)')),
('link', models.URLField(blank=True, max_length=500, null=True, verbose_name='链接')),
('category', models.CharField(blank=True, choices=[('Phones & Electronics', '手机与电子产品'), ('Homes Supplies', '家居用品'), ('Kitchenware', '厨房用品'), ('Textiles & Soft Furnishings', '纺织品和软装'), ('Household Appliances', '家用电器'), ('Womenswear & Underwear', '女装和内衣'), ('Muslim Fashion', '穆斯林时尚'), ('Shoes', '鞋类'), ('Beauty & Personal Care', '美容和个人护理'), ('Computers & Office Equipment', '电脑和办公设备'), ('Pet Supplies', '宠物用品'), ('Baby & Maternity', '婴儿和孕妇用品'), ('Sports & Outdoor', '运动和户外'), ('Toys', '玩具'), ('Furniture', '家具'), ('Tools & Hardware', '工具和硬件'), ('Home Improvement', '家居装修'), ('Automotive & Motorcycle', '汽车和摩托车'), ('Fashion Accessories', '时尚配饰'), ('Food & Beverages', '食品和饮料'), ('Health', '健康'), ('Books, Magazines & Audio', '书籍、杂志和音频'), ('Kids Fashion', '儿童时尚'), ('Menswear & Underwear', '男装和内衣'), ('Luggage & Bags', '行李和包'), ('Pre-Owned Collections', '二手收藏'), ('Jewellery Accessories & Derivatives', '珠宝配饰及衍生品')], max_length=100, null=True, verbose_name='类别')), ('category', models.CharField(blank=True, choices=[('Phones & Electronics', '手机与电子产品'), ('Homes Supplies', '家居用品'), ('Kitchenware', '厨房用品'), ('Textiles & Soft Furnishings', '纺织品和软装'), ('Household Appliances', '家用电器'), ('Womenswear & Underwear', '女装和内衣'), ('Muslim Fashion', '穆斯林时尚'), ('Shoes', '鞋类'), ('Beauty & Personal Care', '美容和个人护理'), ('Computers & Office Equipment', '电脑和办公设备'), ('Pet Supplies', '宠物用品'), ('Baby & Maternity', '婴儿和孕妇用品'), ('Sports & Outdoor', '运动和户外'), ('Toys', '玩具'), ('Furniture', '家具'), ('Tools & Hardware', '工具和硬件'), ('Home Improvement', '家居装修'), ('Automotive & Motorcycle', '汽车和摩托车'), ('Fashion Accessories', '时尚配饰'), ('Food & Beverages', '食品和饮料'), ('Health', '健康'), ('Books, Magazines & Audio', '书籍、杂志和音频'), ('Kids Fashion', '儿童时尚'), ('Menswear & Underwear', '男装和内衣'), ('Luggage & Bags', '行李和包'), ('Pre-Owned Collections', '二手收藏'), ('Jewellery Accessories & Derivatives', '珠宝配饰及衍生品')], max_length=100, null=True, verbose_name='类别')),
('e_commerce_level', models.IntegerField(blank=True, choices=[(1, 'L1'), (2, 'L2'), (3, 'L3'), (4, 'L4'), (5, 'L5'), (6, 'L6'), (7, 'L7')], null=True, verbose_name='电商能力等级')), ('e_commerce_level', models.IntegerField(blank=True, choices=[(1, 'L1'), (2, 'L2'), (3, 'L3'), (4, 'L4'), (5, 'L5'), (6, 'L6'), (7, 'L7')], null=True, verbose_name='电商能力等级')),
('exposure_level', models.CharField(blank=True, choices=[('KOC-1', 'KOC-1'), ('KOC-2', 'KOC-2'), ('KOL-1', 'KOL-1'), ('KOL-2', 'KOL-2'), ('KOL-3', 'KOL-3')], max_length=10, null=True, verbose_name='曝光等级')), ('exposure_level', models.CharField(blank=True, choices=[('KOC-1', 'KOC-1'), ('KOC-2', 'KOC-2'), ('KOL-1', 'KOL-1'), ('KOL-2', 'KOL-2'), ('KOL-3', 'KOL-3')], max_length=10, null=True, verbose_name='曝光等级')),
@ -32,8 +44,7 @@ class Migration(migrations.Migration):
('gmv', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='GMV(千美元)')), ('gmv', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='GMV(千美元)')),
('items_sold', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='售出商品数量')), ('items_sold', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='售出商品数量')),
('avg_video_views', models.IntegerField(blank=True, default=0, null=True, verbose_name='平均视频浏览量')), ('avg_video_views', models.IntegerField(blank=True, default=0, null=True, verbose_name='平均视频浏览量')),
('pricing_min', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='最低个人定价')), ('pricing', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='个人定价')),
('pricing_max', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='最高个人定价')),
('pricing_package', models.CharField(blank=True, max_length=100, null=True, verbose_name='套餐定价')), ('pricing_package', models.CharField(blank=True, max_length=100, null=True, verbose_name='套餐定价')),
('collab_count', models.IntegerField(blank=True, default=0, null=True, verbose_name='合作次数')), ('collab_count', models.IntegerField(blank=True, default=0, null=True, verbose_name='合作次数')),
('latest_collab', models.CharField(blank=True, max_length=100, null=True, verbose_name='最新合作')), ('latest_collab', models.CharField(blank=True, max_length=100, null=True, verbose_name='最新合作')),
@ -154,7 +165,7 @@ class Migration(migrations.Migration):
('is_default', models.BooleanField(default=False, verbose_name='是否为默认库')), ('is_default', models.BooleanField(default=False, verbose_name='是否为默认库')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.ForeignKey(db_column='user_id', on_delete=django.db.models.deletion.CASCADE, related_name='private_creators', to='user.user', verbose_name='用户')), ('user', models.ForeignKey(db_column='user_id', on_delete=django.db.models.deletion.CASCADE, related_name='private_creators', to=settings.AUTH_USER_MODEL, verbose_name='用户')),
], ],
options={ options={
'verbose_name': '私有达人库', 'verbose_name': '私有达人库',
@ -244,7 +255,7 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('added_from_public', models.BooleanField(default=True, verbose_name='是否从公有库添加')), ('added_from_public', models.BooleanField(default=True, verbose_name='是否从公有库添加')),
('notes', models.TextField(blank=True, null=True, verbose_name='笔记')), ('notes', models.TextField(blank=True, null=True, verbose_name='笔记')),
('status', models.CharField(choices=[('active', '活跃'), ('archived', '已归档'), ('favorite', '收藏')], default='active', max_length=20, verbose_name='状态')), ('status', models.CharField(choices=[('active', '活跃'), ('archived', '已归档'), ('favorite', '收藏'), ('public_removed', '公有库已移除')], default='active', max_length=20, verbose_name='状态')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='添加时间')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='添加时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='private_pool_relations', to='daren_detail.creatorprofile', verbose_name='达人')), ('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='private_pool_relations', to='daren_detail.creatorprofile', verbose_name='达人')),

View File

@ -1,26 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-23 03:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('daren_detail', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='creatorprofile',
name='pricing_max',
),
migrations.RemoveField(
model_name='creatorprofile',
name='pricing_min',
),
migrations.AddField(
model_name='creatorprofile',
name='pricing',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='个人定价'),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-23 09:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('daren_detail', '0002_remove_creatorprofile_pricing_max_and_more'),
]
operations = [
migrations.AlterField(
model_name='privatecreatorrelation',
name='status',
field=models.CharField(choices=[('active', '活跃'), ('archived', '已归档'), ('favorite', '收藏'), ('public_removed', '公有库已移除')], default='active', max_length=20, verbose_name='状态'),
),
]

View File

@ -1,23 +0,0 @@
# Generated by Django 5.2.1 on 2025-05-23 08:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('daren_detail', '0002_remove_creatorprofile_pricing_max_and_more'),
]
operations = [
migrations.AddField(
model_name='creatorprofile',
name='hashtags',
field=models.TextField(blank=True, help_text='以#分隔的标签,例如:#fashion#beauty#lifestyle', null=True, verbose_name='标签'),
),
migrations.AddField(
model_name='creatorprofile',
name='trends',
field=models.TextField(blank=True, help_text='创作者相关的趋势关键词', null=True, verbose_name='趋势'),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-23 09:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('daren_detail', '0003_alter_privatecreatorrelation_status'),
]
operations = [
migrations.AddField(
model_name='creatorprofile',
name='avatar',
field=models.ImageField(blank=True, null=True, upload_to='avatars/', verbose_name='头像图片'),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2.1 on 2025-05-23 09:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('daren_detail', '0003_creatorprofile_hashtags_creatorprofile_trends'),
]
operations = [
migrations.AddField(
model_name='creatorprofile',
name='profile',
field=models.CharField(choices=[('tiktok', 'TikTok'), ('instagram', 'Instagram'), ('youtube', 'YouTube'), ('xiaohongshu', '小红书'), ('other', '其他平台')], default='tiktok', max_length=20, verbose_name='达人平台'),
),
]

View File

@ -1,14 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-23 11:23
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('daren_detail', '0004_creatorprofile_avatar'),
('daren_detail', '0004_creatorprofile_profile'),
]
operations = [
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-27 03:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('daren_detail', '0005_merge_20250523_1923'),
]
operations = [
migrations.AlterField(
model_name='creatorprofile',
name='profile',
field=models.CharField(choices=[('tiktok', 'TikTok'), ('instagram', 'Instagram'), ('youtube', 'YouTube'), ('other', '其他平台')], default='tiktok', max_length=20, verbose_name='达人平台'),
),
]

View File

@ -1,52 +0,0 @@
# Generated by Django 5.2.1 on 2025-05-28 08:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('daren_detail', '0006_alter_creatorprofile_profile'),
]
operations = [
migrations.RemoveField(
model_name='creatorprofile',
name='tiktok_link',
),
migrations.AddField(
model_name='creatorprofile',
name='gmv_gbp',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='GMV(英镑)'),
),
migrations.AddField(
model_name='creatorprofile',
name='homepage_link',
field=models.URLField(blank=True, max_length=500, null=True, verbose_name='主页链接'),
),
migrations.AddField(
model_name='creatorprofile',
name='link',
field=models.URLField(blank=True, max_length=500, null=True, verbose_name='链接'),
),
migrations.AddField(
model_name='creatorprofile',
name='price_gbp',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='报价(英镑)'),
),
migrations.AddField(
model_name='creatorprofile',
name='price_usd',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='报价(美金)'),
),
migrations.AddField(
model_name='creatorprofile',
name='region',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='地区'),
),
migrations.AddField(
model_name='creatorprofile',
name='us_creator_level',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='对标美区达人等级'),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2.1 on 2025-05-29 02:21
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('daren_detail', '0007_remove_creatorprofile_tiktok_link_and_more'),
]
operations = [
migrations.RenameField(
model_name='creatorprofile',
old_name='homepage_link',
new_name='tiktok_link',
),
]

View File

@ -1,7 +1,7 @@
# Generated by Django 5.2 on 2025-05-16 02:40 # Generated by Django 5.2.1 on 2025-05-29 09:24
import apps.discovery.models
import django.db.models.deletion import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models from django.db import migrations, models
@ -23,7 +23,7 @@ class Migration(migrations.Migration):
('avg_followers', models.FloatField(default=0, verbose_name='平均粉丝数')), ('avg_followers', models.FloatField(default=0, verbose_name='平均粉丝数')),
('avg_gmv', models.FloatField(default=0, verbose_name='平均GMV')), ('avg_gmv', models.FloatField(default=0, verbose_name='平均GMV')),
('avg_video_views', models.FloatField(default=0, verbose_name='平均视频观看量')), ('avg_video_views', models.FloatField(default=0, verbose_name='平均视频观看量')),
('date_created', models.DateField(default=django.utils.timezone.now, verbose_name='创建日期')), ('date_created', models.DateField(default=apps.discovery.models.get_current_date, verbose_name='创建日期')),
], ],
options={ options={
'verbose_name': '搜索会话', 'verbose_name': '搜索会话',
@ -46,6 +46,9 @@ class Migration(migrations.Migration):
('avg_video_views', models.FloatField(default=0, verbose_name='平均视频观看量')), ('avg_video_views', models.FloatField(default=0, verbose_name='平均视频观看量')),
('has_ecommerce', models.BooleanField(default=False, verbose_name='是否有电商')), ('has_ecommerce', models.BooleanField(default=False, verbose_name='是否有电商')),
('tiktok_url', models.URLField(blank=True, null=True, verbose_name='抖音链接')), ('tiktok_url', models.URLField(blank=True, null=True, verbose_name='抖音链接')),
('hashtags', models.TextField(blank=True, null=True, verbose_name='标签')),
('trends', models.TextField(blank=True, null=True, verbose_name='趋势')),
('profile', models.CharField(choices=[('tiktok', 'TikTok'), ('instagram', 'Instagram'), ('youtube', 'YouTube'), ('xiaohongshu', '小红书'), ('other', '其他平台')], default='tiktok', max_length=20, verbose_name='达人平台')),
('session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='creators', to='discovery.searchsession', verbose_name='所属会话')), ('session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='creators', to='discovery.searchsession', verbose_name='所属会话')),
], ],
options={ options={

View File

@ -1,19 +0,0 @@
# Generated by Django 5.2 on 2025-05-16 03:12
import apps.discovery.models
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('discovery', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='searchsession',
name='date_created',
field=models.DateField(default=apps.discovery.models.get_current_date, verbose_name='创建日期'),
),
]

View File

@ -1,23 +0,0 @@
# Generated by Django 5.2.1 on 2025-05-23 08:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('discovery', '0002_alter_searchsession_date_created'),
]
operations = [
migrations.AddField(
model_name='creator',
name='hashtags',
field=models.TextField(blank=True, null=True, verbose_name='标签'),
),
migrations.AddField(
model_name='creator',
name='trends',
field=models.TextField(blank=True, null=True, verbose_name='趋势'),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2.1 on 2025-05-23 09:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('discovery', '0003_creator_hashtags_creator_trends'),
]
operations = [
migrations.AddField(
model_name='creator',
name='profile',
field=models.CharField(choices=[('tiktok', 'TikTok'), ('instagram', 'Instagram'), ('youtube', 'YouTube'), ('xiaohongshu', '小红书'), ('other', '其他平台')], default='tiktok', max_length=20, verbose_name='达人平台'),
),
]

View File

@ -1,4 +1,4 @@
# Generated by Django 5.1.5 on 2025-05-19 08:40 # Generated by Django 5.2.1 on 2025-05-29 09:24
import django.db.models.deletion import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models
@ -9,31 +9,11 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('brands', '0001_initial'),
('daren_detail', '0001_initial'),
] ]
operations = [ operations = [
migrations.CreateModel(
name='Creator',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('sex', models.CharField(default='', max_length=10)),
('age', models.IntegerField(default=18)),
('category', models.CharField(max_length=50)),
('followers', models.IntegerField()),
],
),
migrations.CreateModel(
name='Product',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('category', models.CharField(max_length=50)),
('max_price', models.DecimalField(decimal_places=2, max_digits=10)),
('min_price', models.DecimalField(decimal_places=2, max_digits=10)),
('description', models.TextField(blank=True)),
],
),
migrations.CreateModel( migrations.CreateModel(
name='Negotiation', name='Negotiation',
fields=[ fields=[
@ -41,8 +21,8 @@ class Migration(migrations.Migration):
('status', models.CharField(choices=[('brand_review', '品牌回顾'), ('price_negotiation', '价格谈判'), ('contract_review', '合同确认'), ('draft_ready', '准备合同'), ('draft_approved', '合同提交'), ('accepted', '已接受'), ('abandoned', '已放弃')], default='price_negotiation', max_length=20)), ('status', models.CharField(choices=[('brand_review', '品牌回顾'), ('price_negotiation', '价格谈判'), ('contract_review', '合同确认'), ('draft_ready', '准备合同'), ('draft_approved', '合同提交'), ('accepted', '已接受'), ('abandoned', '已放弃')], default='price_negotiation', max_length=20)),
('current_round', models.IntegerField(default=1)), ('current_round', models.IntegerField(default=1)),
('context', models.JSONField(default=dict)), ('context', models.JSONField(default=dict)),
('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='expertproducts.creator')), ('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='daren_detail.creatorprofile')),
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='expertproducts.product')), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='brands.product')),
], ],
), ),
migrations.CreateModel( migrations.CreateModel(

View File

@ -1,29 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-20 04:36
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('brands', '0002_alter_campaign_id'),
('daren_detail', '0001_initial'),
('expertproducts', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='negotiation',
name='creator',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='daren_detail.creatorprofile'),
),
migrations.AlterField(
model_name='negotiation',
name='product',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='brands.product'),
),
migrations.DeleteModel(
name='Creator',
),
]

View File

@ -1,16 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-20 04:37
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('expertproducts', '0002_alter_negotiation_creator_alter_negotiation_product_and_more'),
]
operations = [
migrations.DeleteModel(
name='Product',
),
]

View File

@ -1,4 +1,4 @@
# Generated by Django 5.2 on 2025-05-07 03:43 # Generated by Django 5.2.1 on 2025-05-29 09:24
import uuid import uuid
from django.db import migrations, models from django.db import migrations, models
@ -46,7 +46,24 @@ class Migration(migrations.Migration):
options={ options={
'verbose_name': '创作者数据', 'verbose_name': '创作者数据',
'verbose_name_plural': '创作者数据', 'verbose_name_plural': '创作者数据',
'db_table': 'feishu_creators', },
),
migrations.CreateModel(
name='FeishuTableMapping',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('app_token', models.CharField(max_length=100, verbose_name='应用令牌')),
('table_id', models.CharField(max_length=100, verbose_name='表格ID')),
('table_url', models.TextField(verbose_name='表格URL')),
('table_name', models.CharField(max_length=100, verbose_name='数据库表名')),
('feishu_table_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='飞书表格名称')),
('last_sync_time', models.DateTimeField(auto_now=True, verbose_name='最后同步时间')),
('total_records', models.IntegerField(default=0, verbose_name='总记录数')),
],
options={
'verbose_name': '飞书表格映射',
'verbose_name_plural': '飞书表格映射',
'unique_together': {('app_token', 'table_id')},
}, },
), ),
] ]

View File

@ -1,39 +0,0 @@
# Generated by Django 5.2 on 2025-05-14 04:30
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('feishu', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='FeishuAuth',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('open_id', models.CharField(blank=True, max_length=100, null=True, verbose_name='飞书Open ID')),
('union_id', models.CharField(blank=True, max_length=100, null=True, verbose_name='飞书Union ID')),
('access_token', models.CharField(max_length=512, verbose_name='访问令牌')),
('refresh_token', models.CharField(max_length=512, verbose_name='刷新令牌')),
('expires_at', models.DateTimeField(verbose_name='令牌过期时间')),
('is_active', models.BooleanField(default=True, verbose_name='是否有效')),
('scopes', models.JSONField(blank=True, default=list, verbose_name='授权范围')),
('metadata', models.JSONField(blank=True, default=dict, verbose_name='授权元数据')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feishu_auths', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': '飞书授权',
'verbose_name_plural': '飞书授权',
'db_table': 'feishu_auths',
},
),
]

View File

@ -1,35 +0,0 @@
# Generated by Django 5.2 on 2025-05-14 09:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('feishu', '0002_feishuauth'),
]
operations = [
migrations.CreateModel(
name='FeishuTableMapping',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('app_token', models.CharField(max_length=100, verbose_name='应用令牌')),
('table_id', models.CharField(max_length=100, verbose_name='表格ID')),
('table_url', models.TextField(verbose_name='表格URL')),
('table_name', models.CharField(max_length=100, verbose_name='数据库表名')),
('feishu_table_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='飞书表格名称')),
('last_sync_time', models.DateTimeField(auto_now=True, verbose_name='最后同步时间')),
('total_records', models.IntegerField(default=0, verbose_name='总记录数')),
],
options={
'verbose_name': '飞书表格映射',
'verbose_name_plural': '飞书表格映射',
'db_table': 'feishu_table_mapping',
'unique_together': {('app_token', 'table_id')},
},
),
migrations.DeleteModel(
name='FeishuAuth',
),
]

View File

@ -1,21 +0,0 @@
# Generated by Django 5.2 on 2025-05-21 04:30
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('feishu', '0003_feishutablemapping_delete_feishuauth'),
]
operations = [
migrations.AlterModelTable(
name='feishucreator',
table=None,
),
migrations.AlterModelTable(
name='feishutablemapping',
table=None,
),
]

View File

@ -1,7 +1,7 @@
# Generated by Django 5.2 on 2025-05-13 06:43 # Generated by Django 5.2.1 on 2025-05-29 09:24
import django.db.models.deletion import django.db.models.deletion
import django.utils.timezone import uuid
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -19,14 +19,16 @@ class Migration(migrations.Migration):
name='GmailConversation', name='GmailConversation',
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('user_email', models.EmailField(help_text='用户Gmail邮箱', max_length=254)), ('conversation_id', models.CharField(help_text='Unique conversation identifier', max_length=100, unique=True)),
('influencer_email', models.EmailField(help_text='达人Gmail邮箱', max_length=254)), ('user_email', models.EmailField(help_text="User's Gmail address", max_length=254)),
('conversation_id', models.CharField(help_text='关联到chat_history的会话ID', max_length=100, unique=True)), ('influencer_email', models.EmailField(help_text="Influencer's email address", max_length=254)),
('title', models.CharField(default='Gmail对话', help_text='对话标题', max_length=100)), ('title', models.CharField(help_text='Conversation title', max_length=255)),
('last_sync_time', models.DateTimeField(default=django.utils.timezone.now, help_text='最后同步时间')),
('created_at', models.DateTimeField(auto_now_add=True)), ('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)), ('updated_at', models.DateTimeField(auto_now=True)),
('is_active', models.BooleanField(default=True)), ('last_sync_time', models.DateTimeField(blank=True, help_text='Last time conversation was synced with Gmail', null=True)),
('is_active', models.BooleanField(default=True, help_text='Whether this conversation is active')),
('has_sent_greeting', models.BooleanField(default=False, help_text='Whether a greeting message has been sent to this conversation')),
('metadata', models.JSONField(blank=True, help_text='Additional metadata for the conversation', null=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gmail_conversations', to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gmail_conversations', to=settings.AUTH_USER_MODEL)),
], ],
options={ options={
@ -39,7 +41,7 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email_message_id', models.CharField(help_text='Gmail邮件ID', max_length=100)), ('email_message_id', models.CharField(help_text='Gmail邮件ID', max_length=100)),
('attachment_id', models.CharField(help_text='Gmail附件ID', max_length=100)), ('attachment_id', models.TextField(help_text='Gmail附件的唯一标识符可能很长')),
('filename', models.CharField(help_text='原始文件名', max_length=255)), ('filename', models.CharField(help_text='原始文件名', max_length=255)),
('file_path', models.CharField(help_text='保存在服务器上的路径', max_length=255)), ('file_path', models.CharField(help_text='保存在服务器上的路径', max_length=255)),
('content_type', models.CharField(help_text='MIME类型', max_length=100)), ('content_type', models.CharField(help_text='MIME类型', max_length=100)),
@ -53,6 +55,107 @@ class Migration(migrations.Migration):
'ordering': ['-created_at'], 'ordering': ['-created_at'],
}, },
), ),
migrations.CreateModel(
name='ConversationSummary',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('content', models.TextField(verbose_name='摘要内容')),
('last_message_id', models.CharField(blank=True, max_length=255, null=True, verbose_name='最后处理的消息ID或ChatHistory的ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('conversation', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='summary', to='gmail.gmailconversation')),
],
options={
'verbose_name': 'Gmail对话摘要',
'verbose_name_plural': 'Gmail对话摘要',
'db_table': 'gmail_conversation_summaries',
},
),
migrations.CreateModel(
name='ProcessedPushNotification',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('message_id', models.CharField(help_text='Pub/Sub消息ID', max_length=255, unique=True)),
('email_address', models.EmailField(help_text='通知关联的Gmail邮箱', max_length=254)),
('history_id', models.CharField(help_text='Gmail历史ID', max_length=100)),
('processed_at', models.DateTimeField(auto_now_add=True, help_text='处理时间')),
('is_successful', models.BooleanField(default=True, help_text='处理是否成功')),
('metadata', models.JSONField(blank=True, default=dict, help_text='额外信息')),
],
options={
'verbose_name': '已处理推送通知',
'verbose_name_plural': '已处理推送通知',
'db_table': 'gmail_processed_push_notifications',
'ordering': ['-processed_at'],
'indexes': [models.Index(fields=['message_id'], name='gmail_proce_message_912a0c_idx'), models.Index(fields=['email_address', 'history_id'], name='gmail_proce_email_a_2e3770_idx')],
},
),
migrations.CreateModel(
name='UnmatchedEmail',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('message_id', models.CharField(help_text='Gmail邮件ID', max_length=255, unique=True)),
('user_id', models.CharField(help_text='用户ID (UUID字符串形式)', max_length=36)),
('user_email', models.EmailField(help_text='用户Gmail邮箱', max_length=254)),
('from_email', models.EmailField(help_text='发件人邮箱', max_length=254)),
('to_email', models.EmailField(help_text='收件人邮箱', max_length=254)),
('subject', models.CharField(blank=True, help_text='邮件主题', max_length=500)),
('processed_at', models.DateTimeField(auto_now_add=True, help_text='处理时间')),
],
options={
'verbose_name': '未匹配邮件',
'verbose_name_plural': '未匹配邮件',
'db_table': 'gmail_unmatched_emails',
'ordering': ['-processed_at'],
'indexes': [models.Index(fields=['message_id'], name='gmail_unmat_message_c1924d_idx'), models.Index(fields=['user_id'], name='gmail_unmat_user_id_ee06fe_idx'), models.Index(fields=['user_email', 'from_email'], name='gmail_unmat_user_em_a096af_idx')],
},
),
migrations.CreateModel(
name='UserGoal',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('description', models.TextField(verbose_name='目标描述')),
('status', models.CharField(choices=[('pending', '待处理'), ('in_progress', '进行中'), ('completed', '已完成'), ('failed', '失败')], default='pending', max_length=20, verbose_name='目标状态')),
('is_active', models.BooleanField(default=True, verbose_name='是否激活')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('completion_time', models.DateTimeField(blank=True, null=True, verbose_name='完成时间')),
('last_activity_time', models.DateTimeField(blank=True, null=True, verbose_name='最后活动时间')),
('metadata', models.JSONField(blank=True, default=dict, help_text='存储额外信息', null=True)),
('conversation', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='goals', to='gmail.gmailconversation')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='goals', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': '用户目标',
'verbose_name_plural': '用户目标',
'ordering': ['-updated_at'],
},
),
migrations.CreateModel(
name='AutoReplyConfig',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('user_email', models.EmailField(help_text='用户Gmail邮箱', max_length=254)),
('influencer_email', models.EmailField(help_text='达人Gmail邮箱', max_length=254)),
('is_enabled', models.BooleanField(default=True, help_text='是否启用自动回复')),
('goal_description', models.TextField(help_text='AI回复时参考的目标', verbose_name='自动回复的目标描述')),
('reply_template', models.TextField(blank=True, help_text='回复模板可选为空则由AI生成', null=True)),
('max_replies', models.IntegerField(default=5, help_text='最大自动回复次数')),
('current_replies', models.IntegerField(default=0, help_text='当前已自动回复次数')),
('last_reply_time', models.DateTimeField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('metadata', models.JSONField(blank=True, default=dict, help_text='存储额外信息如已处理的消息ID等', null=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auto_reply_configs', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Gmail自动回复配置',
'verbose_name_plural': 'Gmail自动回复配置',
'db_table': 'gmail_auto_reply_configs',
'ordering': ['-updated_at'],
'unique_together': {('user', 'user_email', 'influencer_email')},
},
),
migrations.CreateModel( migrations.CreateModel(
name='GmailCredential', name='GmailCredential',
fields=[ fields=[
@ -63,6 +166,7 @@ class Migration(migrations.Migration):
('created_at', models.DateTimeField(auto_now_add=True)), ('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)), ('updated_at', models.DateTimeField(auto_now=True)),
('is_valid', models.BooleanField(default=True, help_text='Whether the credential is valid')), ('is_valid', models.BooleanField(default=True, help_text='Whether the credential is valid')),
('last_history_id', models.CharField(blank=True, help_text='Last processed Gmail history ID', max_length=50, null=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gmail_credentials', to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gmail_credentials', to=settings.AUTH_USER_MODEL)),
], ],
options={ options={

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2 on 2025-05-13 08:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='gmailcredential',
name='last_history_id',
field=models.CharField(blank=True, help_text='Last processed Gmail history ID', max_length=50, null=True),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2 on 2025-05-13 09:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0002_gmailcredential_last_history_id'),
]
operations = [
migrations.AddField(
model_name='gmailconversation',
name='metadata',
field=models.JSONField(blank=True, default=dict, help_text='存储额外信息如已处理的消息ID等', null=True),
),
]

View File

@ -1,31 +0,0 @@
# Generated by Django 5.2 on 2025-05-13 10:11
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0003_gmailconversation_metadata'),
]
operations = [
migrations.CreateModel(
name='ConversationSummary',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('content', models.TextField(verbose_name='摘要内容')),
('last_message_id', models.CharField(blank=True, max_length=255, null=True, verbose_name='最后处理的消息ID或ChatHistory的ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('conversation', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='summary', to='gmail.gmailconversation')),
],
options={
'verbose_name': 'Gmail对话摘要',
'verbose_name_plural': 'Gmail对话摘要',
'db_table': 'gmail_conversation_summaries',
},
),
]

View File

@ -1,34 +0,0 @@
# Generated by Django 5.2 on 2025-05-14 02:52
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0004_conversationsummary'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='UserGoal',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('description', models.TextField(verbose_name='目标描述')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('is_active', models.BooleanField(default=True, verbose_name='是否激活')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='goals', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': '用户目标',
'verbose_name_plural': '用户目标',
'db_table': 'user_goals',
'ordering': ['-updated_at'],
},
),
]

View File

@ -1,39 +0,0 @@
# Generated by Django 5.2 on 2025-05-14 09:45
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0005_usergoal'),
]
operations = [
migrations.AddField(
model_name='usergoal',
name='completion_time',
field=models.DateTimeField(blank=True, null=True, verbose_name='完成时间'),
),
migrations.AddField(
model_name='usergoal',
name='conversation',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='goals', to='gmail.gmailconversation'),
),
migrations.AddField(
model_name='usergoal',
name='last_activity_time',
field=models.DateTimeField(blank=True, null=True, verbose_name='最后活动时间'),
),
migrations.AddField(
model_name='usergoal',
name='metadata',
field=models.JSONField(blank=True, default=dict, help_text='存储额外信息', null=True),
),
migrations.AddField(
model_name='usergoal',
name='status',
field=models.CharField(choices=[('pending', '待处理'), ('in_progress', '进行中'), ('completed', '已完成'), ('failed', '失败')], default='pending', max_length=20, verbose_name='目标状态'),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2 on 2025-05-19 07:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0006_usergoal_completion_time_usergoal_conversation_and_more'),
]
operations = [
migrations.AlterField(
model_name='gmailattachment',
name='attachment_id',
field=models.CharField(help_text='Gmail附件的唯一标识符可能很长', max_length=255),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2 on 2025-05-19 07:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0007_alter_gmailattachment_attachment_id'),
]
operations = [
migrations.AlterField(
model_name='gmailattachment',
name='attachment_id',
field=models.TextField(help_text='Gmail附件的唯一标识符可能很长'),
),
]

View File

@ -1,82 +0,0 @@
# Generated by Django 5.2 on 2025-05-20 06:52
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0008_alter_gmailattachment_attachment_id'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='gmailconversation',
name='has_sent_greeting',
field=models.BooleanField(default=False, help_text='Whether a greeting message has been sent to this conversation'),
),
migrations.AlterField(
model_name='gmailconversation',
name='conversation_id',
field=models.CharField(help_text='Unique conversation identifier', max_length=100, unique=True),
),
migrations.AlterField(
model_name='gmailconversation',
name='influencer_email',
field=models.EmailField(help_text="Influencer's email address", max_length=254),
),
migrations.AlterField(
model_name='gmailconversation',
name='is_active',
field=models.BooleanField(default=True, help_text='Whether this conversation is active'),
),
migrations.AlterField(
model_name='gmailconversation',
name='last_sync_time',
field=models.DateTimeField(blank=True, help_text='Last time conversation was synced with Gmail', null=True),
),
migrations.AlterField(
model_name='gmailconversation',
name='metadata',
field=models.JSONField(blank=True, help_text='Additional metadata for the conversation', null=True),
),
migrations.AlterField(
model_name='gmailconversation',
name='title',
field=models.CharField(help_text='Conversation title', max_length=255),
),
migrations.AlterField(
model_name='gmailconversation',
name='user_email',
field=models.EmailField(help_text="User's Gmail address", max_length=254),
),
migrations.CreateModel(
name='AutoReplyConfig',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('user_email', models.EmailField(help_text='用户Gmail邮箱', max_length=254)),
('influencer_email', models.EmailField(help_text='达人Gmail邮箱', max_length=254)),
('is_enabled', models.BooleanField(default=True, help_text='是否启用自动回复')),
('goal_description', models.TextField(help_text='AI回复时参考的目标', verbose_name='自动回复的目标描述')),
('reply_template', models.TextField(blank=True, help_text='回复模板可选为空则由AI生成', null=True)),
('max_replies', models.IntegerField(default=5, help_text='最大自动回复次数')),
('current_replies', models.IntegerField(default=0, help_text='当前已自动回复次数')),
('last_reply_time', models.DateTimeField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('metadata', models.JSONField(blank=True, default=dict, help_text='存储额外信息如已处理的消息ID等', null=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='auto_reply_configs', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Gmail自动回复配置',
'verbose_name_plural': 'Gmail自动回复配置',
'db_table': 'gmail_auto_reply_configs',
'ordering': ['-updated_at'],
'unique_together': {('user', 'user_email', 'influencer_email')},
},
),
]

View File

@ -1,53 +0,0 @@
# Generated by Django 5.2 on 2025-05-20 09:21
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0009_gmailconversation_has_sent_greeting_and_more'),
]
operations = [
migrations.CreateModel(
name='ProcessedPushNotification',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('message_id', models.CharField(help_text='Pub/Sub消息ID', max_length=255, unique=True)),
('email_address', models.EmailField(help_text='通知关联的Gmail邮箱', max_length=254)),
('history_id', models.CharField(help_text='Gmail历史ID', max_length=100)),
('processed_at', models.DateTimeField(auto_now_add=True, help_text='处理时间')),
('is_successful', models.BooleanField(default=True, help_text='处理是否成功')),
('metadata', models.JSONField(blank=True, default=dict, help_text='额外信息')),
],
options={
'verbose_name': '已处理推送通知',
'verbose_name_plural': '已处理推送通知',
'db_table': 'gmail_processed_push_notifications',
'ordering': ['-processed_at'],
'indexes': [models.Index(fields=['message_id'], name='gmail_proce_message_912a0c_idx'), models.Index(fields=['email_address', 'history_id'], name='gmail_proce_email_a_2e3770_idx')],
},
),
migrations.CreateModel(
name='UnmatchedEmail',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('message_id', models.CharField(help_text='Gmail邮件ID', max_length=255, unique=True)),
('user_id', models.IntegerField(help_text='用户ID')),
('user_email', models.EmailField(help_text='用户Gmail邮箱', max_length=254)),
('from_email', models.EmailField(help_text='发件人邮箱', max_length=254)),
('to_email', models.EmailField(help_text='收件人邮箱', max_length=254)),
('subject', models.CharField(blank=True, help_text='邮件主题', max_length=500)),
('processed_at', models.DateTimeField(auto_now_add=True, help_text='处理时间')),
],
options={
'verbose_name': '未匹配邮件',
'verbose_name_plural': '未匹配邮件',
'db_table': 'gmail_unmatched_emails',
'ordering': ['-processed_at'],
'indexes': [models.Index(fields=['message_id'], name='gmail_unmat_message_c1924d_idx'), models.Index(fields=['user_id'], name='gmail_unmat_user_id_ee06fe_idx'), models.Index(fields=['user_email', 'from_email'], name='gmail_unmat_user_em_a096af_idx')],
},
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.2 on 2025-05-20 09:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gmail', '0010_processedpushnotification_unmatchedemail'),
]
operations = [
migrations.AlterField(
model_name='unmatchedemail',
name='user_id',
field=models.CharField(help_text='用户ID (UUID字符串形式)', max_length=36),
),
]

View File

@ -1,17 +0,0 @@
# Generated by Django 5.2 on 2025-05-21 04:22
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('gmail', '0011_alter_unmatchedemail_user_id'),
]
operations = [
migrations.AlterModelTable(
name='usergoal',
table=None,
),
]

View File

@ -1,4 +1,4 @@
# Generated by Django 5.2 on 2025-05-07 03:40 # Generated by Django 5.2.1 on 2025-05-29 09:24
import django.db.models.deletion import django.db.models.deletion
import uuid import uuid
@ -31,8 +31,7 @@ class Migration(migrations.Migration):
('update_time', models.DateTimeField(auto_now=True)), ('update_time', models.DateTimeField(auto_now=True)),
], ],
options={ options={
'db_table': 'knowledge_bases', 'indexes': [models.Index(fields=['type'], name='knowledge_b_type_7a8dcc_idx'), models.Index(fields=['department'], name='knowledge_b_departm_8f1cf3_idx'), models.Index(fields=['group'], name='knowledge_b_group_ae45d4_idx')],
'indexes': [models.Index(fields=['type'], name='knowledge_b_type_0439e7_idx'), models.Index(fields=['department'], name='knowledge_b_departm_e739fd_idx'), models.Index(fields=['group'], name='knowledge_b_group_3dcf34_idx')],
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
@ -51,8 +50,7 @@ class Migration(migrations.Migration):
options={ options={
'verbose_name': '知识库文档', 'verbose_name': '知识库文档',
'verbose_name_plural': '知识库文档', 'verbose_name_plural': '知识库文档',
'db_table': 'knowledge_base_documents', 'indexes': [models.Index(fields=['knowledge_base', 'status'], name='knowledge_b_knowled_6653e6_idx'), models.Index(fields=['document_id'], name='knowledge_b_documen_1fd896_idx'), models.Index(fields=['external_id'], name='knowledge_b_externa_ae1a97_idx')],
'indexes': [models.Index(fields=['knowledge_base', 'status'], name='knowledge_b_knowled_a4db1b_idx'), models.Index(fields=['document_id'], name='knowledge_b_documen_dab90f_idx'), models.Index(fields=['external_id'], name='knowledge_b_externa_b0060c_idx')],
'unique_together': {('knowledge_base', 'document_id')}, 'unique_together': {('knowledge_base', 'document_id')},
}, },
), ),

View File

@ -1,51 +0,0 @@
# Generated by Django 5.2 on 2025-05-21 04:30
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('knowledge_base', '0001_initial'),
]
operations = [
migrations.RenameIndex(
model_name='knowledgebase',
new_name='knowledge_b_type_7a8dcc_idx',
old_name='knowledge_b_type_0439e7_idx',
),
migrations.RenameIndex(
model_name='knowledgebase',
new_name='knowledge_b_departm_8f1cf3_idx',
old_name='knowledge_b_departm_e739fd_idx',
),
migrations.RenameIndex(
model_name='knowledgebase',
new_name='knowledge_b_group_ae45d4_idx',
old_name='knowledge_b_group_3dcf34_idx',
),
migrations.RenameIndex(
model_name='knowledgebasedocument',
new_name='knowledge_b_knowled_6653e6_idx',
old_name='knowledge_b_knowled_a4db1b_idx',
),
migrations.RenameIndex(
model_name='knowledgebasedocument',
new_name='knowledge_b_documen_1fd896_idx',
old_name='knowledge_b_documen_dab90f_idx',
),
migrations.RenameIndex(
model_name='knowledgebasedocument',
new_name='knowledge_b_externa_ae1a97_idx',
old_name='knowledge_b_externa_b0060c_idx',
),
migrations.AlterModelTable(
name='knowledgebase',
table=None,
),
migrations.AlterModelTable(
name='knowledgebasedocument',
table=None,
),
]

View File

@ -1,4 +1,4 @@
# Generated by Django 5.1.5 on 2025-05-19 08:40 # Generated by Django 5.2.1 on 2025-05-29 09:24
import django.db.models.deletion import django.db.models.deletion
from django.db import migrations, models from django.db import migrations, models

View File

@ -1,5 +1,7 @@
# Generated by Django 5.1.5 on 2025-05-16 09:05 # Generated by Django 5.2.1 on 2025-05-29 09:24
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -21,7 +23,9 @@ class Migration(migrations.Migration):
('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='用户姓名')), ('name', models.CharField(blank=True, max_length=255, null=True, verbose_name='用户姓名')),
('is_first_login', models.BooleanField(default=True, verbose_name='是否首次登录')), ('is_first_login', models.BooleanField(default=True, verbose_name='是否首次登录')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='最近登录时间')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='最近登录时间')),
('is_active', models.BooleanField(default=True, verbose_name='是否活跃')), ('is_active', models.BooleanField(default=True)),
('is_staff', models.BooleanField(default=False)),
('is_superuser', models.BooleanField(default=False, verbose_name='超级用户状态')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
], ],
@ -31,4 +35,17 @@ class Migration(migrations.Migration):
'db_table': 'users', 'db_table': 'users',
}, },
), ),
migrations.CreateModel(
name='UserToken',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('token', models.CharField(max_length=40, unique=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('expired_at', models.DateTimeField()),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tokens', to=settings.AUTH_USER_MODEL)),
],
options={
'db_table': 'user_token',
},
),
] ]

View File

@ -1,17 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-19 04:33
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('user', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='user',
name='is_active',
),
]

View File

@ -1,27 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-20 03:49
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user', '0002_remove_user_is_active'),
]
operations = [
migrations.CreateModel(
name='UserToken',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('token', models.CharField(max_length=40, unique=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('expired_at', models.DateTimeField()),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tokens', to='user.user')),
],
options={
'db_table': 'user_token',
},
),
]

View File

@ -1,23 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-20 03:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user', '0003_usertoken'),
]
operations = [
migrations.AddField(
model_name='user',
name='is_active',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='user',
name='is_staff',
field=models.BooleanField(default=False),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 5.1.5 on 2025-05-23 09:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user', '0004_user_is_active_user_is_staff'),
]
operations = [
migrations.AddField(
model_name='user',
name='is_superuser',
field=models.BooleanField(default=False, verbose_name='超级用户状态'),
),
]