Compare commits
1 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
c5347b01a9 | 3 years ago |
454 changed files with 24 additions and 182559 deletions
@ -1,9 +1,2 @@ |
||||
/venv/ |
||||
.idea |
||||
/dx/ |
||||
/logs/ |
||||
/logs/dingxin.log |
||||
*.log |
||||
/celerybeat-schedule.bak |
||||
/celerybeat-schedule.dat |
||||
/celerybeat-schedule.dir |
||||
.idea |
||||
@ -1,3 +0,0 @@ |
||||
from django.contrib import admin |
||||
|
||||
# Register your models here. |
||||
@ -1,6 +0,0 @@ |
||||
from django.apps import AppConfig |
||||
|
||||
|
||||
class ShowAiConfig(AppConfig): |
||||
default_auto_field = 'django.db.models.BigAutoField' |
||||
name = 'ai' |
||||
@ -1,51 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-08 07:20 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
initial = True |
||||
|
||||
dependencies = [ |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='AiShow', |
||||
fields=[ |
||||
('id', models.AutoField(primary_key=True, serialize=False)), |
||||
('cinema', models.CharField(max_length=50)), |
||||
('zz_code', models.CharField(max_length=50)), |
||||
('show_date', models.DateField()), |
||||
('is_ai_show', models.BooleanField(default=True)), |
||||
('show', models.TextField()), |
||||
('sales', models.CharField(max_length=50)), |
||||
('prompt', models.TextField()), |
||||
('result', models.TextField()), |
||||
('message', models.TextField()), |
||||
('created_at', models.DateTimeField(auto_now_add=True)), |
||||
], |
||||
options={ |
||||
'verbose_name': 'AI排片数据', |
||||
'verbose_name_plural': 'AI排片数据', |
||||
'db_table': 'ai_show_result', |
||||
}, |
||||
), |
||||
migrations.CreateModel( |
||||
name='TestCinema', |
||||
fields=[ |
||||
('id', models.AutoField(primary_key=True, serialize=False)), |
||||
('name', models.CharField(max_length=50)), |
||||
('zz_code', models.CharField(max_length=50)), |
||||
('db_config', models.TextField()), |
||||
('user_config', models.TextField()), |
||||
('is_active', models.BooleanField(default=True)), |
||||
], |
||||
options={ |
||||
'verbose_name': '测试影院', |
||||
'verbose_name_plural': '测试影院', |
||||
'db_table': 'ai_show_cinema', |
||||
}, |
||||
), |
||||
] |
||||
@ -1,23 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-08 10:37 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0001_initial'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='take_times', |
||||
field=models.IntegerField(default=0), |
||||
), |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='take_tokens', |
||||
field=models.CharField(default='', max_length=2000), |
||||
), |
||||
] |
||||
@ -1,28 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-09 02:00 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0002_aishow_take_times_aishow_take_tokens'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='PromptTemplate', |
||||
fields=[ |
||||
('id', models.AutoField(primary_key=True, serialize=False)), |
||||
('prompt_type', models.CharField(max_length=50)), |
||||
('prompt_key', models.CharField(max_length=50)), |
||||
('prompt_val', models.TextField()), |
||||
('del_flag', models.BooleanField(default=False)), |
||||
], |
||||
options={ |
||||
'verbose_name': '提示词', |
||||
'verbose_name_plural': '提示词', |
||||
'db_table': 'ai_prompt_template', |
||||
}, |
||||
), |
||||
] |
||||
@ -1,27 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-09 10:24 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0003_prompttemplate'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='CinemaHall', |
||||
fields=[ |
||||
('id', models.AutoField(primary_key=True, serialize=False)), |
||||
('cinema_code', models.CharField(max_length=50)), |
||||
('hall_id', models.CharField(max_length=50)), |
||||
('hall_name', models.CharField(max_length=50)), |
||||
], |
||||
options={ |
||||
'verbose_name': '影厅数据', |
||||
'verbose_name_plural': '影厅数据', |
||||
'db_table': 'ai_show_hall', |
||||
}, |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-10 07:52 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0004_cinemahall'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='aishow', |
||||
name='created_at', |
||||
field=models.DateTimeField(auto_now=True), |
||||
), |
||||
] |
||||
@ -1,23 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-10 07:55 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0005_alter_aishow_created_at'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='updated_at', |
||||
field=models.DateTimeField(auto_now=True), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='aishow', |
||||
name='created_at', |
||||
field=models.DateTimeField(auto_now_add=True), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-10 08:37 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0006_aishow_updated_at_alter_aishow_created_at'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='prompt_version', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
] |
||||
@ -1,23 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-16 01:22 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0007_aishow_prompt_version'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='temp_date', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='template', |
||||
field=models.TextField(default=''), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-17 07:12 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0008_aishow_temp_date_aishow_template'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='cinemahall', |
||||
name='hall_type', |
||||
field=models.CharField(default='', max_length=500), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-06-29 03:11 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0009_cinemahall_hall_type'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='target', |
||||
field=models.TextField(default=''), |
||||
), |
||||
] |
||||
@ -1,33 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-03 14:23 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0010_aishow_target'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='AiModel', |
||||
fields=[ |
||||
('id', models.AutoField(primary_key=True, serialize=False)), |
||||
('config_name', models.CharField(max_length=50)), |
||||
('base_url', models.CharField(max_length=100)), |
||||
('api_key', models.CharField(max_length=50)), |
||||
('model_name', models.CharField(default='', max_length=500)), |
||||
], |
||||
options={ |
||||
'verbose_name': '模型配置', |
||||
'verbose_name_plural': '模型配置', |
||||
'db_table': 'ai_model_configs', |
||||
}, |
||||
), |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='ai_model', |
||||
field=models.CharField(default='', max_length=100), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-04 13:33 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0011_aimodel_aishow_ai_model'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='aimodel', |
||||
name='delete_flag', |
||||
field=models.BooleanField(default=False), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-04 13:47 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0012_aimodel_delete_flag'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='aimodel', |
||||
name='current_used', |
||||
field=models.BooleanField(default=False), |
||||
), |
||||
] |
||||
@ -1,26 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-04 13:58 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0013_aimodel_current_used'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='AiRuntime', |
||||
fields=[ |
||||
('id', models.AutoField(primary_key=True, serialize=False)), |
||||
('runtime_key', models.CharField(max_length=50)), |
||||
('runtime_val', models.TextField()), |
||||
], |
||||
options={ |
||||
'verbose_name': 'AI运行时', |
||||
'verbose_name_plural': 'AI运行时', |
||||
'db_table': 'ai_runtime', |
||||
}, |
||||
), |
||||
] |
||||
@ -1,35 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-04 15:06 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0014_airuntime'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='MovieHotInfo', |
||||
fields=[ |
||||
('id', models.AutoField(primary_key=True, serialize=False)), |
||||
('movie_zz_code', models.CharField(max_length=50)), |
||||
('movie_name', models.CharField(max_length=50)), |
||||
('req_date', models.DateField()), |
||||
('api_response', models.TextField()), |
||||
('wants', models.CharField(max_length=50)), |
||||
('hots', models.CharField(max_length=50)), |
||||
('day_1', models.CharField(max_length=50)), |
||||
('day_2', models.CharField(max_length=50)), |
||||
('day_3', models.CharField(max_length=50)), |
||||
('day_4', models.CharField(max_length=50)), |
||||
('day_5', models.CharField(max_length=50)), |
||||
], |
||||
options={ |
||||
'verbose_name': 'AI影片热度信息', |
||||
'verbose_name_plural': 'AI影片热度信息', |
||||
'db_table': 'ai_movie_hot', |
||||
}, |
||||
), |
||||
] |
||||
@ -1,83 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-04 15:16 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0015_moviehotinfo'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_1', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_2', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_3', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_4', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_5', |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_1_date', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_1_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_2_date', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_2_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_3_date', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_3_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_4_date', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_4_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_5_date', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_5_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
] |
||||
@ -1,58 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-04 15:18 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0016_remove_moviehotinfo_day_1_remove_moviehotinfo_day_2_and_more'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_1_date', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_1_val', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_2_date', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_2_val', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_3_date', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_3_val', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_4_date', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_4_val', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_5_date', |
||||
), |
||||
migrations.RemoveField( |
||||
model_name='moviehotinfo', |
||||
name='day_5_val', |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day_data', |
||||
field=models.TextField(default=''), |
||||
), |
||||
] |
||||
@ -1,38 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-04 22:57 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0017_remove_moviehotinfo_day_1_date_and_more'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day1_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day2_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day3_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day4_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='day5_val', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
] |
||||
@ -1,28 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-04 23:00 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0018_moviehotinfo_day1_val_moviehotinfo_day2_val_and_more'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='title', |
||||
field=models.CharField(default='', max_length=1000), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='moviehotinfo', |
||||
name='hots', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='moviehotinfo', |
||||
name='wants', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-05 09:37 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0019_moviehotinfo_title_alter_moviehotinfo_hots_and_more'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='moviehotinfo', |
||||
name='show_type', |
||||
field=models.CharField(default='', max_length=500), |
||||
), |
||||
] |
||||
@ -1,28 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-09 10:12 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0020_moviehotinfo_show_type'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='NewMovieSuggestion', |
||||
fields=[ |
||||
('id', models.AutoField(primary_key=True, serialize=False)), |
||||
('movie_zz_code', models.CharField(max_length=50)), |
||||
('movie_name', models.CharField(max_length=50)), |
||||
('suggestion', models.CharField(max_length=50)), |
||||
('delete_flag', models.BooleanField(default=False)), |
||||
], |
||||
options={ |
||||
'verbose_name': '新片推荐排片数', |
||||
'verbose_name_plural': '新片推荐排片数', |
||||
'db_table': 'ai_new_movie_suggestion', |
||||
}, |
||||
), |
||||
] |
||||
@ -1,38 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-10 02:12 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0021_newmoviesuggestion'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='newmoviesuggestion', |
||||
name='cinema', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AddField( |
||||
model_name='newmoviesuggestion', |
||||
name='zz_code', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='newmoviesuggestion', |
||||
name='movie_name', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='newmoviesuggestion', |
||||
name='movie_zz_code', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='newmoviesuggestion', |
||||
name='suggestion', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
] |
||||
@ -1,31 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-10 06:53 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0022_newmoviesuggestion_cinema_newmoviesuggestion_zz_code_and_more'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='MovieGuidance', |
||||
fields=[ |
||||
('id', models.AutoField(primary_key=True, serialize=False)), |
||||
('cinema', models.CharField(default='', max_length=50)), |
||||
('zz_code', models.CharField(default='', max_length=50)), |
||||
('show_date', models.CharField(default='', max_length=50)), |
||||
('movie_zz_code', models.CharField(default='', max_length=50)), |
||||
('movie_name', models.CharField(default='', max_length=50)), |
||||
('guidance', models.CharField(default='', max_length=50)), |
||||
('delete_flag', models.BooleanField(default=False)), |
||||
], |
||||
options={ |
||||
'verbose_name': '集团排片指导', |
||||
'verbose_name_plural': '集团排片指导', |
||||
'db_table': 'ai_movie_guidance', |
||||
}, |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-13 02:53 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0023_movieguidance'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='is_manual_test', |
||||
field=models.BooleanField(default=False), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-15 02:13 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0024_aishow_is_manual_test'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='movieguidance', |
||||
name='type', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2026-07-16 04:19 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('ai', '0025_movieguidance_type'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='aishow', |
||||
name='create_datetime', |
||||
field=models.CharField(default='', max_length=50), |
||||
), |
||||
] |
||||
@ -1,196 +0,0 @@ |
||||
from django.db import models |
||||
|
||||
|
||||
# Create your models here. |
||||
class TestCinema(models.Model): |
||||
""" |
||||
用于存储测试影院基本信息、数据库配置信息 |
||||
user_config用于模拟用户设置情况 |
||||
is_active设置为False时不会自动生成影院的排片,需要手动生成 |
||||
""" |
||||
id = models.AutoField(primary_key=True) |
||||
name = models.CharField(max_length=50) |
||||
zz_code = models.CharField(max_length=50) |
||||
db_config = models.TextField() |
||||
user_config = models.TextField() |
||||
is_active = models.BooleanField(default=True) |
||||
|
||||
def __str__(self): |
||||
return self.name |
||||
|
||||
class Meta: |
||||
verbose_name = '测试影院' |
||||
verbose_name_plural = '测试影院' |
||||
db_table = 'ai_show_cinema' |
||||
|
||||
|
||||
class PromptTemplate(models.Model): |
||||
""" |
||||
分板块的提示词模板,用于动态调整提示词的内容和结构。 |
||||
ShowPromptVersion为当前提示词版本 |
||||
""" |
||||
id = models.AutoField(primary_key=True) |
||||
prompt_type = models.CharField(max_length=50) |
||||
prompt_key = models.CharField(max_length=50) |
||||
prompt_val = models.TextField() |
||||
del_flag = models.BooleanField(default=False) |
||||
|
||||
def __str__(self): |
||||
return self.prompt_key |
||||
|
||||
class Meta: |
||||
verbose_name = '提示词' |
||||
verbose_name_plural = '提示词' |
||||
db_table = 'ai_prompt_template' |
||||
|
||||
|
||||
class AiShow(models.Model): |
||||
""" |
||||
用于存储ai生成的结果已经影院真实排片 |
||||
temp_date: 模板数据日期 |
||||
target: 目标日期已排影片数据,csv格式 |
||||
show: 目标日期ai生成的排片数据,csv格式 |
||||
sales: ai排片预期收入 |
||||
prompt |
||||
""" |
||||
id = models.AutoField(primary_key=True) |
||||
cinema = models.CharField(max_length=50) |
||||
zz_code = models.CharField(max_length=50) |
||||
show_date = models.DateField() # 排片目标日期 |
||||
is_ai_show = models.BooleanField(default=True) # 当is_ai_show为True时,记录为ai生成的排片,否则为影院真实排片 |
||||
is_manual_test = models.BooleanField(default=False) # 为手动提交的提示词提供标记 |
||||
ai_model = models.CharField(default='', max_length=100) # ai生成排片时使用的模型 |
||||
template = models.TextField(default='') # ai生成排片时的模板日期排片数据,csv格式 |
||||
temp_date = models.CharField(max_length=50, default='') # 模板数据日期 |
||||
target = models.TextField(default='') # 目标日期已排影片数据,csv格式 |
||||
show = models.TextField() # 目标日期ai生成的排片数据,csv格式 |
||||
sales = models.CharField(max_length=50) # ai排片预期收入 |
||||
prompt = models.TextField() # 生成的用户提示词部分 |
||||
result = models.TextField() # ai返回结果中最终输出部分 |
||||
message = models.TextField() # ai返回结果的完整信息 |
||||
create_datetime = models.CharField(max_length=50, default='') # 生成的时间 |
||||
created_at = models.DateTimeField(auto_now_add=True) # ai返回结果的时间 |
||||
updated_at = models.DateTimeField(auto_now=True) |
||||
take_times = models.IntegerField(default=0) # 从提示词发给ai到取得返回结果的时间,单位秒 |
||||
take_tokens = models.CharField(default='', max_length=2000) # ai返回结果中token消耗部分的信息 |
||||
prompt_version = models.CharField(max_length=50, default='') # 使用的提示词版本 |
||||
|
||||
def __str__(self): |
||||
return self.cinema |
||||
|
||||
class Meta: |
||||
verbose_name = 'AI排片数据' |
||||
verbose_name_plural = 'AI排片数据' |
||||
db_table = 'ai_show_result' |
||||
|
||||
|
||||
class CinemaHall(models.Model): |
||||
id = models.AutoField(primary_key=True) |
||||
cinema_code = models.CharField(max_length=50) |
||||
hall_id = models.CharField(max_length=50) |
||||
hall_name = models.CharField(max_length=50) |
||||
hall_type = models.CharField(max_length=500, default='') |
||||
|
||||
def __str__(self): |
||||
return self.hall_name |
||||
|
||||
class Meta: |
||||
verbose_name = '影厅数据' |
||||
verbose_name_plural = '影厅数据' |
||||
db_table = 'ai_show_hall' |
||||
|
||||
|
||||
class AiModel(models.Model): |
||||
id = models.AutoField(primary_key=True) |
||||
config_name = models.CharField(max_length=50) |
||||
base_url = models.CharField(max_length=100) |
||||
api_key = models.CharField(max_length=50) |
||||
model_name = models.CharField(max_length=500, default='') |
||||
delete_flag = models.BooleanField(default=False) |
||||
current_used = models.BooleanField(default=False) |
||||
|
||||
def __str__(self): |
||||
return self.config_name |
||||
|
||||
class Meta: |
||||
verbose_name = '模型配置' |
||||
verbose_name_plural = '模型配置' |
||||
db_table = 'ai_model_configs' |
||||
|
||||
|
||||
class AiRuntime(models.Model): |
||||
id = models.AutoField(primary_key=True) |
||||
runtime_key = models.CharField(max_length=50) |
||||
runtime_val = models.TextField() |
||||
|
||||
def __str__(self): |
||||
return self.runtime_key |
||||
|
||||
class Meta: |
||||
verbose_name = 'AI运行时' |
||||
verbose_name_plural = 'AI运行时' |
||||
db_table = 'ai_runtime' |
||||
|
||||
|
||||
class MovieHotInfo(models.Model): |
||||
id = models.AutoField(primary_key=True) |
||||
movie_zz_code = models.CharField(max_length=50) |
||||
movie_name = models.CharField(max_length=50) |
||||
req_date = models.DateField() |
||||
api_response = models.TextField() |
||||
show_type = models.CharField(max_length=500, default='') |
||||
title = models.CharField(max_length=1000, default='') |
||||
wants = models.CharField(max_length=50, default='') |
||||
hots = models.CharField(max_length=50, default='') |
||||
day1_val = models.CharField(max_length=50, default='') |
||||
day2_val = models.CharField(max_length=50, default='') |
||||
day3_val = models.CharField(max_length=50, default='') |
||||
day4_val = models.CharField(max_length=50, default='') |
||||
day5_val = models.CharField(max_length=50, default='') |
||||
day_data = models.TextField(default='') |
||||
|
||||
def __str__(self): |
||||
return self.movie_name |
||||
|
||||
class Meta: |
||||
verbose_name = 'AI影片热度信息' |
||||
verbose_name_plural = 'AI影片热度信息' |
||||
db_table = 'ai_movie_hot' |
||||
|
||||
|
||||
class NewMovieSuggestion(models.Model): |
||||
id = models.AutoField(primary_key=True) |
||||
cinema = models.CharField(max_length=50, default='') |
||||
zz_code = models.CharField(max_length=50, default='') |
||||
movie_zz_code = models.CharField(max_length=50, default='') |
||||
movie_name = models.CharField(max_length=50, default='') |
||||
suggestion = models.CharField(max_length=50, default='') |
||||
delete_flag = models.BooleanField(default=False) |
||||
|
||||
def __str__(self): |
||||
return self.movie_name |
||||
|
||||
class Meta: |
||||
verbose_name = '新片推荐排片数' |
||||
verbose_name_plural = '新片推荐排片数' |
||||
db_table = 'ai_new_movie_suggestion' |
||||
|
||||
|
||||
class MovieGuidance(models.Model): |
||||
id = models.AutoField(primary_key=True) |
||||
cinema = models.CharField(max_length=50, default='') |
||||
zz_code = models.CharField(max_length=50, default='') |
||||
show_date = models.CharField(max_length=50, default='') |
||||
movie_zz_code = models.CharField(max_length=50, default='') |
||||
movie_name = models.CharField(max_length=50, default='') |
||||
guidance = models.CharField(max_length=50, default='') |
||||
type = models.CharField(max_length=50, default='') |
||||
delete_flag = models.BooleanField(default=False) |
||||
|
||||
def __str__(self): |
||||
return self.movie_name |
||||
|
||||
class Meta: |
||||
verbose_name = '集团排片指导' |
||||
verbose_name_plural = '集团排片指导' |
||||
db_table = 'ai_movie_guidance' |
||||
@ -1,56 +0,0 @@ |
||||
from rest_framework import serializers |
||||
|
||||
from ai.models import * |
||||
|
||||
|
||||
class TestCinemaSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = TestCinema |
||||
fields = '__all__' |
||||
|
||||
|
||||
class PromptTemplateSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = PromptTemplate |
||||
fields = '__all__' |
||||
|
||||
|
||||
class AiShowSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = AiShow |
||||
fields = '__all__' |
||||
|
||||
|
||||
class CinemaHallSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = CinemaHall |
||||
fields = '__all__' |
||||
|
||||
|
||||
class AiModelSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = AiModel |
||||
fields = '__all__' |
||||
|
||||
|
||||
class AiRuntimeSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = AiRuntime |
||||
fields = '__all__' |
||||
|
||||
|
||||
class MovieHotInfoSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = MovieHotInfo |
||||
fields = '__all__' |
||||
|
||||
|
||||
class NewMovieSuggestionSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = NewMovieSuggestion |
||||
fields = '__all__' |
||||
|
||||
class MovieGuidanceSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = MovieGuidance |
||||
fields = '__all__' |
||||
@ -1,18 +0,0 @@ |
||||
from celery import shared_task |
||||
from ai.utils.show_process import show_main_process |
||||
from ai.utils.basic_func import clear_lock_func |
||||
from ai.utils.show_func import get_new_movie |
||||
|
||||
@shared_task(time_limit=18*60, soft_time_limit=18*60) |
||||
def ai_show_general(): |
||||
clear_lock_func() |
||||
show_main_process() |
||||
print("task success") |
||||
return True |
||||
|
||||
|
||||
@shared_task(time_limit=18*60, soft_time_limit=18*60) |
||||
def get_new_movie_task(): |
||||
get_new_movie() |
||||
print("task success") |
||||
return True |
||||
@ -1,3 +0,0 @@ |
||||
from django.test import TestCase |
||||
|
||||
# Create your tests here. |
||||
@ -1,31 +0,0 @@ |
||||
""" |
||||
URL configuration for dingxin_toolbox_drf project. |
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see: |
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/ |
||||
Examples: |
||||
Function views |
||||
1. Add an import: from my_app import views |
||||
2. Add a URL to urlpatterns: path('', views.home, name='home') |
||||
Class-based views |
||||
1. Add an import: from other_app.views import Home |
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') |
||||
Including another URLconf |
||||
1. Import the include() function: from django.urls import include, path |
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) |
||||
""" |
||||
from django.contrib import admin |
||||
from django.urls import path, include |
||||
from ai.views import * |
||||
|
||||
urlpatterns = [ |
||||
path('manual_general_show', manual_general_show), |
||||
path('get_cinema_show_result', get_cinema_show_result), |
||||
path('clear', clear_lock), |
||||
path('report', report), |
||||
path('report_date', get_report_date_api), |
||||
path('new_movie', insert_new_movie), |
||||
path('test', manual_test), |
||||
path('test_date', get_test_date), |
||||
path('get_prompt', get_prompt), |
||||
] |
||||
@ -1,235 +0,0 @@ |
||||
import datetime |
||||
import csv |
||||
import json |
||||
from ai.models import * |
||||
from io import StringIO |
||||
from django_redis import get_redis_connection |
||||
from ai.models import CinemaHall |
||||
from django.db.models import Q |
||||
|
||||
|
||||
# 清除redis锁 |
||||
def clear_lock_func(): |
||||
redis_conn = get_redis_connection() |
||||
redis_key = f'ai_show{datetime.date.today().strftime("%Y%m%d")}' |
||||
if redis_conn.exists(redis_key): |
||||
redis_conn.delete(redis_key) |
||||
print(f'清除{redis_key}成功') |
||||
|
||||
|
||||
# 将csv转化成字典 |
||||
def csv_to_obj(csv_data): |
||||
f = StringIO(csv_data) |
||||
reader = csv.DictReader(f) |
||||
return list(reader) |
||||
|
||||
|
||||
# 列表转csv |
||||
def list_to_csv(rows, include_header=True): |
||||
""" |
||||
将嵌套列表转换为 CSV 字符串 |
||||
:param rows: 输入数据,格式为 [['col1','col2'], ['val1','val2'], ...] |
||||
:param include_header: 若为 True,则 rows[0] 作为表头;否则全部当作数据行 |
||||
""" |
||||
output = StringIO() |
||||
writer = csv.writer(output, lineterminator='\r\n') |
||||
if include_header and rows: |
||||
writer.writerow(rows[0]) |
||||
writer.writerows(rows[1:]) |
||||
else: |
||||
writer.writerows(rows) |
||||
return output.getvalue() |
||||
|
||||
|
||||
# 格式化数据 |
||||
def format_show_data(cinema_code: str, show_date: str, data_left: dict, data_right: dict): |
||||
# 获取影厅数据 |
||||
hall = CinemaHall.objects.filter(cinema_code=cinema_code).all() |
||||
# 准备数据 |
||||
data = dict() |
||||
for h in hall: |
||||
hall_dict = {'hall_name': h.hall_name, 'hall_id': h.hall_id, 'ai': [], 'real': []} |
||||
for ai in data_left: |
||||
if dict_get(ai, ['影厅id', '影厅 id']) == str(h.hall_id): |
||||
print(ai) |
||||
hall_dict['ai'].append({ |
||||
'movie_name': ai['影片别名'], |
||||
'movie_id': dict_get(ai, ['本地影片id' '本地影片 id']), |
||||
'language': ai['语言'], |
||||
'show_date': ai['放映日期'], |
||||
'start': ai['开始时间'], |
||||
'end': ai['结束时间'], |
||||
'length': ai['片长'], |
||||
'duration': ai['场间'] |
||||
}) |
||||
for real in data_right: |
||||
if dict_get(real, ['影厅id', '影厅 id']) == str(h.hall_id): |
||||
hall_dict['real'].append({ |
||||
'movie_name': real['影片别名'], |
||||
'movie_id': dict_get(real, ['本地影片id' '本地影片 id']), |
||||
'language': real['语言'], |
||||
'show_date': real['放映日期'], |
||||
'start': real['开始时间'], |
||||
'end': real['结束时间'], |
||||
'length': real['片长'], |
||||
'duration': real['场间'] |
||||
}) |
||||
data[h.hall_id] = hall_dict |
||||
# 格式化输出 |
||||
output_list = [] |
||||
output_csv = [ |
||||
['影厅别名', '影片别名', '语言', '开始时间', '结束时间', '片长', '场间', '', '影厅别名', '影片别名', '语言', |
||||
'开始时间', '结束时间', '片长', '场间']] |
||||
for v in data.values(): |
||||
if len(v['ai']) == 0 and len(v['real']) == 0: |
||||
output_list.append([v['hall_name'], show_date, '', '', '', '', '', '', '', '', '', '', '', '', '', '']) |
||||
output_csv.append([v['hall_name'], '', '', '', '', '', '', '', v['hall_name'], '', '', '', '', '', '']) |
||||
if len(v['ai']) >= len(v['real']): |
||||
for i in range(len(v['ai'])): |
||||
if i < len(v['real']): |
||||
a = v['ai'][i] |
||||
r = v['real'][i] |
||||
output_list.append( |
||||
[v['hall_name'], show_date, a['movie_name'], a['movie_id'], a['language'], a['start'], |
||||
a['end'], a['length'], a['duration'], r['movie_name'], r['movie_id'], r['language'], |
||||
r['start'], r['end'], r['length'], r['duration']] |
||||
) |
||||
output_csv.append( |
||||
[v['hall_name'], a['movie_name'], a['language'], a['start'], a['end'], a['length'], |
||||
a['duration'], '', v['hall_name'], r['movie_name'], r['language'], r['start'], r['end'], |
||||
r['length'], r['duration']] |
||||
) |
||||
else: |
||||
a = v['ai'][i] |
||||
output_list.append( |
||||
[v['hall_name'], show_date, a['movie_name'], a['movie_id'], a['language'], a['start'], |
||||
a['end'], a['length'], a['duration'], '', '', '', '', '', '', ''] |
||||
) |
||||
output_csv.append( |
||||
[v['hall_name'], a['movie_name'], a['language'], a['start'], a['end'], a['length'], |
||||
a['duration'], '', '', '', '', '', '', '', ''] |
||||
) |
||||
else: |
||||
for i in range(len(v['real'])): |
||||
if i < len(v['ai']): |
||||
a = v['ai'][i] |
||||
r = v['real'][i] |
||||
output_list.append( |
||||
[v['hall_name'], show_date, a['movie_name'], a['movie_id'], a['language'], a['start'], |
||||
a['end'], a['length'], a['duration'], r['movie_name'], r['movie_id'], r['language'], |
||||
r['start'], r['end'], r['length'], r['duration']] |
||||
) |
||||
output_csv.append( |
||||
[v['hall_name'], a['movie_name'], a['language'], a['start'], a['end'], a['length'], |
||||
a['duration'], '', v['hall_name'], r['movie_name'], r['language'], r['start'], r['end'], |
||||
r['length'], r['duration']] |
||||
) |
||||
else: |
||||
r = v['real'][i] |
||||
output_list.append( |
||||
[v['hall_name'], show_date, '', '', '', '', '', '', '', r['movie_name'], r['movie_id'], |
||||
r['language'], r['start'], r['end'], r['length'], r['duration']] |
||||
) |
||||
output_csv.append( |
||||
[v['hall_name'], '', '', '', '', '', '', '', v['hall_name'], r['movie_name'], r['language'], |
||||
r['start'], r['end'], r['length'], r['duration']] |
||||
) |
||||
return output_list, output_csv |
||||
|
||||
|
||||
# 获取影厅制式 |
||||
def get_hall_type(cinema_code): |
||||
halls = CinemaHall.objects.filter(cinema_code=cinema_code).all() |
||||
hall_dict = dict() |
||||
for h in halls: |
||||
hall_dict[h.hall_name] = h.hall_type |
||||
return hall_dict |
||||
|
||||
|
||||
# 获取排片占比 |
||||
def count_show(show_data): |
||||
print('count_show', show_data) |
||||
show_dict = dict() |
||||
for show in show_data: |
||||
if show['影片别名'] in show_dict.keys(): |
||||
show_dict[show['影片别名']] += 1 |
||||
else: |
||||
show_dict[show['影片别名']] = 1 |
||||
show_dict = dict(sorted(show_dict.items(), key=lambda item: item[0], reverse=True)) |
||||
show_count = [] |
||||
for show, count in show_dict.items(): |
||||
show_count.append(f"{show}:{str(round(count / len(show_data) * 100, 2))}%,共排{str(count)}场") |
||||
return '\n'.join(show_count), f"共{len(show_data)}场" |
||||
|
||||
|
||||
# 处理黑名单 |
||||
def get_black_list(cinema_code: str): |
||||
black_list = json.loads(TestCinema.objects.filter(zz_code=cinema_code).first().user_config)['movie_black_list'] |
||||
black_list_bool = False |
||||
black_list_str = "' '" |
||||
if len(black_list) > 0: |
||||
black_list_bool = True |
||||
black_list_str = ','.join(['%s'] * len(black_list)) |
||||
return black_list_bool, black_list_str, black_list |
||||
|
||||
|
||||
# 获取运行时参数 |
||||
def get_runtime_val(key: str): |
||||
return AiRuntime.objects.filter(runtime_key=key).first().runtime_val |
||||
|
||||
|
||||
# 获取当前开启的模型 |
||||
def get_current_model(): |
||||
return AiModel.objects.filter(Q(current_used=True) & Q(delete_flag=False)).first() |
||||
|
||||
|
||||
# 通不过不同key获取数据 |
||||
def dict_get(_dict: dict, keys: list): |
||||
for k in keys: |
||||
if k in _dict.keys(): |
||||
return _dict[k] |
||||
return False |
||||
|
||||
|
||||
# AI返回数据清洗 |
||||
def data_cleansing(data: str): |
||||
return data.replace(',', ',').replace('影厅 id', '影厅id').replace('本地影片 id', '本地影片id').replace(', ', ',') |
||||
|
||||
|
||||
def json_to_csv(data:list): |
||||
csv_list = ['影厅别名,影厅id,影片别名,本地影片id,语言,放映日期,开始时间,结束时间,片长,场间', ] |
||||
for d in data: |
||||
csv_list.append( |
||||
f"{d['hall_name']},{d['hall_id']},{d['movie_alias']},{d['movie_id']},{d['language']},{d['show_date']},{d['start']},{d['end']},{d['length']},{d['duration']}") |
||||
return '\n'.join(csv_list) |
||||
|
||||
|
||||
# 获取排片数据的起始和结束日期 |
||||
def get_report_date(): |
||||
start_date = datetime.datetime.strftime( |
||||
AiShow.objects.filter(is_ai_show=True).order_by('show_date').first().show_date, '%Y-%m-%d') + 'T00:00:00Z' |
||||
end_date = datetime.datetime.strftime( |
||||
AiShow.objects.filter(is_ai_show=True).order_by('-show_date').first().show_date, '%Y-%m-%d') + 'T00:00:00Z' |
||||
print(start_date, end_date) |
||||
return start_date, end_date |
||||
|
||||
|
||||
# 判断目标日期是否是暑期档 |
||||
def is_summer(target: str, start='06-11', end='08-31') -> bool: |
||||
year = str(datetime.datetime.strptime(target, '%Y-%m-%d').year) |
||||
start_obj = datetime.datetime.strptime(f"{year}-{start}", '%Y-%m-%d').date() |
||||
end_obj = datetime.datetime.strptime(f"{year}-{end}", '%Y-%m-%d').date() |
||||
target_obj = datetime.datetime.strptime(target, '%Y-%m-%d').date() |
||||
if start_obj <= target_obj <= end_obj: |
||||
return True |
||||
return False |
||||
|
||||
|
||||
# 根据输入的两个日期,判端是否需要增减场次 |
||||
def add_reduce_rule(template: bool, target: bool) -> str: |
||||
if template is True and target is False: |
||||
return 'decrease' |
||||
elif template is False and target is True: |
||||
return 'increase' |
||||
else: |
||||
return 'same' |
||||
@ -1,50 +0,0 @@ |
||||
import datetime |
||||
from chinese_calendar import (is_holiday, is_workday) |
||||
|
||||
|
||||
def get_data_datetime(show_date): |
||||
show_date_obj = datetime.datetime.strptime(show_date, '%Y-%m-%d') |
||||
target_start_datetime_obj = show_date_obj + datetime.timedelta(hours=6) |
||||
target_end_datetime_obj = show_date_obj + datetime.timedelta(hours=29, minutes=59, seconds=59) |
||||
data_start_datetime_obj = show_date_obj + datetime.timedelta(days=-7) + datetime.timedelta(hours=6) |
||||
data_end_datetime_obj = show_date_obj + datetime.timedelta(hours=5, minutes=59, seconds=59) |
||||
history_start = datetime.datetime.strftime(data_start_datetime_obj, '%Y-%m-%d %H:%M:%S') |
||||
history_end = datetime.datetime.strftime(data_end_datetime_obj, '%Y-%m-%d %H:%M:%S') |
||||
target_start = datetime.datetime.strftime(target_start_datetime_obj, '%Y-%m-%d %H:%M:%S') |
||||
target_end = datetime.datetime.strftime(target_end_datetime_obj, '%Y-%m-%d %H:%M:%S') |
||||
return history_start, history_end, target_start, target_end |
||||
|
||||
def get_data_datetime_template(show_date, template_date): |
||||
show_date_obj = datetime.datetime.strptime(show_date, '%Y-%m-%d') |
||||
target_start_datetime_obj = show_date_obj + datetime.timedelta(hours=6) |
||||
target_end_datetime_obj = show_date_obj + datetime.timedelta(hours=29, minutes=59, seconds=59) |
||||
template_date_obj = datetime.datetime.strptime(template_date, '%Y-%m-%d') |
||||
data_start_datetime_obj = template_date_obj + datetime.timedelta(hours=6) |
||||
data_end_datetime_obj = template_date_obj + datetime.timedelta(hours=29, minutes=59, seconds=59) |
||||
history_start = datetime.datetime.strftime(data_start_datetime_obj, '%Y-%m-%d %H:%M:%S') |
||||
history_end = datetime.datetime.strftime(data_end_datetime_obj, '%Y-%m-%d %H:%M:%S') |
||||
target_start = datetime.datetime.strftime(target_start_datetime_obj, '%Y-%m-%d %H:%M:%S') |
||||
target_end = datetime.datetime.strftime(target_end_datetime_obj, '%Y-%m-%d %H:%M:%S') |
||||
return history_start, history_end, target_start, target_end |
||||
|
||||
|
||||
def get_date_type(show_date, template_date): |
||||
show_date_obj = datetime.datetime.strptime(show_date, '%Y-%m-%d') |
||||
template_date_obj = datetime.datetime.strptime(template_date, '%Y-%m-%d') |
||||
result = dict() |
||||
# 处理参考数据日期 |
||||
history_date_list = [(show_date_obj - datetime.timedelta(days=i)) for i in range(7, 0, -1)] |
||||
history_date = '、'.join( |
||||
[f'{datetime.date.strftime(d, "%Y-%m-%d")}({"节假日" if is_holiday(d) else "工作日"})' for d in |
||||
history_date_list]) |
||||
# 处理目标日期 |
||||
show_date = f'{datetime.date.strftime(show_date_obj, "%Y-%m-%d")}({"节假日" if is_holiday(show_date_obj) else "工作日"})' |
||||
show_date_is_holiday = is_holiday(show_date_obj) |
||||
# 处理模板日期 |
||||
template_date = f'{datetime.date.strftime(template_date_obj, "%Y-%m-%d")}({"节假日" if is_holiday(template_date_obj) else "工作日"})' |
||||
template_date_is_holiday = is_holiday(template_date_obj) |
||||
return history_date, show_date, show_date_is_holiday, template_date, template_date_is_holiday |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
get_date_type("2026-06-13", "2026-06-01") |
||||
@ -1,131 +0,0 @@ |
||||
import csv |
||||
from io import StringIO |
||||
import pymysql |
||||
from pymysql.cursors import DictCursor |
||||
|
||||
s = """ |
||||
影厅别名,影厅id,影片别名,本地影片id,语言,放映日期,开始时间,结束时间,片长,场间 |
||||
2楼 百花厅(部分按摩椅),1,功夫女足,4292,国语,2026-07-14,13:00,14:46,106,0 |
||||
2楼 百花厅(部分按摩椅),1,功夫女足,4292,国语,2026-07-14,15:00,16:46,106,14 |
||||
2楼 百花厅(部分按摩椅),1,功夫女足,4292,国语,2026-07-14,17:00,18:46,106,14 |
||||
2楼 百花厅(部分按摩椅),1,功夫女足,4292,国语,2026-07-14,19:00,20:46,106,14 |
||||
2楼 百花厅(部分按摩椅),1,功夫女足,4292,国语,2026-07-14,21:00,22:46,106,14 |
||||
2楼1号厅(部分按摩椅),2,功夫女足,4292,国语,2026-07-14,11:00,12:46,106,0 |
||||
2楼1号厅(部分按摩椅),2,八仙!,4296,国语,2026-07-14,13:00,15:24,144,14 |
||||
2楼1号厅(部分按摩椅),2,三国第一部:争洛阳,4281,国语,2026-07-14,15:40,17:57,137,16 |
||||
2楼1号厅(部分按摩椅),2,三国第一部:争洛阳,4281,国语,2026-07-14,18:10,20:27,137,13 |
||||
2楼1号厅(部分按摩椅),2,八仙!,4296,国语,2026-07-14,20:40,23:04,144,13 |
||||
2楼2号速度与激情厅(部分按摩椅),3,四渡,4275,国语,2026-07-14,10:20,12:22,122,0 |
||||
2楼2号速度与激情厅(部分按摩椅),3,四渡,4275,国语,2026-07-14,12:35,14:37,122,13 |
||||
2楼2号速度与激情厅(部分按摩椅),3,四渡,4275,国语,2026-07-14,14:50,16:52,122,13 |
||||
2楼2号速度与激情厅(部分按摩椅),3,四渡,4275,国语,2026-07-14,17:05,19:07,122,13 |
||||
2楼2号速度与激情厅(部分按摩椅),3,四渡,4275,国语,2026-07-14,19:20,21:22,122,13 |
||||
2楼3号厅(部分按摩椅),4,功夫女足,4292,国语,2026-07-14,10:30,12:16,106,0 |
||||
2楼3号厅(部分按摩椅),4,小黄人与大怪兽(国语),4289,国语,2026-07-14,12:30,14:00,90,14 |
||||
2楼3号厅(部分按摩椅),4,小黄人与大怪兽(国语),4289,国语,2026-07-14,14:15,15:45,90,15 |
||||
2楼3号厅(部分按摩椅),4,后室,4279,原版,2026-07-14,16:00,17:51,111,15 |
||||
2楼3号厅(部分按摩椅),4,功夫女足,4292,国语,2026-07-14,18:05,19:51,106,14 |
||||
2楼3号厅(部分按摩椅),4,八仙!,4296,国语,2026-07-14,20:05,22:29,144,14 |
||||
2楼4号优选福励厅,5,功夫女足,4292,国语,2026-07-14,11:30,13:16,106,0 |
||||
2楼4号优选福励厅,5,功夫女足,4292,国语,2026-07-14,13:30,15:16,106,14 |
||||
2楼4号优选福励厅,5,功夫女足,4292,国语,2026-07-14,15:30,17:16,106,14 |
||||
2楼4号优选福励厅,5,功夫女足,4292,国语,2026-07-14,17:30,19:16,106,14 |
||||
2楼4号优选福励厅,5,功夫女足,4292,国语,2026-07-14,19:30,21:16,106,14 |
||||
2楼4号优选福励厅,5,功夫女足,4292,国语,2026-07-14,21:30,23:16,106,14 |
||||
3楼5号厅(部分按摩椅),6,功夫女足,4292,国语,2026-07-14,11:05,12:51,106,0 |
||||
3楼5号厅(部分按摩椅),6,功夫女足,4292,国语,2026-07-14,13:05,14:51,106,14 |
||||
3楼5号厅(部分按摩椅),6,功夫女足,4292,国语,2026-07-14,15:05,16:51,106,14 |
||||
3楼5号厅(部分按摩椅),6,功夫女足,4292,国语,2026-07-14,17:05,18:51,106,14 |
||||
3楼5号厅(部分按摩椅),6,功夫女足,4292,国语,2026-07-14,19:05,20:51,106,14 |
||||
3楼5号厅(部分按摩椅),6,功夫女足,4292,国语,2026-07-14,21:05,22:51,106,14 |
||||
3楼6号泰隆银行厅(部分按摩椅),7,功夫女足,4292,国语,2026-07-14,12:00,13:46,106,0 |
||||
3楼6号泰隆银行厅(部分按摩椅),7,功夫女足,4292,国语,2026-07-14,14:00,15:46,106,14 |
||||
3楼6号泰隆银行厅(部分按摩椅),7,功夫女足,4292,国语,2026-07-14,16:00,17:46,106,14 |
||||
3楼6号泰隆银行厅(部分按摩椅),7,功夫女足,4292,国语,2026-07-14,18:00,19:46,106,14 |
||||
3楼6号泰隆银行厅(部分按摩椅),7,功夫女足,4292,国语,2026-07-14,20:00,21:46,106,14 |
||||
3楼7号厅,8,功夫女足,4292,国语,2026-07-14,12:40,14:26,106,0 |
||||
3楼7号厅,8,八仙!,4296,国语,2026-07-14,14:40,17:04,144,14 |
||||
3楼7号厅,8,小黄人与大怪兽(国语),4289,国语,2026-07-14,17:15,18:45,90,11 |
||||
3楼7号厅,8,三国第一部:争洛阳,4281,国语,2026-07-14,19:00,21:17,137,15 |
||||
3楼7号厅,8,后室,4279,原版,2026-07-14,21:30,23:21,111,13 |
||||
2楼 三江VIP厅,9,功夫女足,4292,国语,2026-07-14,14:05,15:51,106,0 |
||||
2楼 三江VIP厅,9,那山那水,4264,国语,2026-07-14,16:05,17:31,86,14 |
||||
2楼 三江VIP厅,9,八仙!,4296,国语,2026-07-14,17:45,20:09,144,14 |
||||
2楼 三江VIP厅,9,特立独行,4280,国语,2026-07-14,20:20,22:23,123,11 |
||||
""" |
||||
|
||||
|
||||
# 将csv转化成字典 |
||||
def csv_to_obj(csv_data): |
||||
f = StringIO(csv_data) |
||||
print(csv_data, f) |
||||
reader = csv.DictReader(f) |
||||
return list(reader) |
||||
|
||||
|
||||
def get_real_data(cinema_code: str, show_date: str): |
||||
db_config = { |
||||
'host': '172.16.1.63', |
||||
'port': 3306, |
||||
'user': 'root', |
||||
'password': 'Cine123456', |
||||
'database': 'dingxin_toolbox', |
||||
} |
||||
db_conn = pymysql.connect(**db_config) |
||||
db_cursor = db_conn.cursor(cursor=DictCursor) |
||||
db_cursor.execute( |
||||
"SELECT * FROM dingxin_toolbox.ai_show_result WHERE zz_code=%s AND show_date=%s AND is_ai_show=%s", |
||||
(cinema_code, show_date, 0)) |
||||
real_data = db_cursor.fetchone() |
||||
return real_data['show'] |
||||
|
||||
|
||||
def count_data(data): |
||||
count = len(data) - 1 |
||||
movie_dict = {} |
||||
for movie in data[1:]: |
||||
movie_name = movie[None][2] |
||||
if movie_name in movie_dict.keys(): |
||||
movie_dict[movie_name] += 1 |
||||
else: |
||||
movie_dict[movie_name] = 1 |
||||
movie_dict = dict(sorted(movie_dict.items(), key=lambda item: item[1], reverse=True)) |
||||
print(f"共{count}场") |
||||
for key, value in movie_dict.items(): |
||||
print(f"《{key}》: {value}场 占比{round(value / count * 100, 2)}%") |
||||
|
||||
|
||||
def _get_hall_count(show: list) -> dict: |
||||
hall_show_count = dict() |
||||
for show in show[1:]: |
||||
hall = show[None][1] |
||||
if hall in hall_show_count.keys(): |
||||
hall_show_count[show[None][1]] += 1 |
||||
else: |
||||
hall_show_count[show[None][1]] = 1 |
||||
return hall_show_count |
||||
|
||||
|
||||
def get_hall_show_count(ai: list, real: list) -> dict: |
||||
ai_hall_show_count = _get_hall_count(ai) |
||||
real_hall_show_count = _get_hall_count(real) |
||||
more = ai_hall_show_count if len(ai_hall_show_count) >= len(real_hall_show_count) else real_hall_show_count |
||||
hall_show_count = dict() |
||||
for key in more.keys(): |
||||
hall_show_count[key] = ai_hall_show_count[key] if ai_hall_show_count.get(key, 0) >= real_hall_show_count.get( |
||||
key, 0) else real_hall_show_count[key] |
||||
return hall_show_count |
||||
|
||||
|
||||
def show_data(zz_code: str, show_date: str): |
||||
real_obj = csv_to_obj(get_real_data(zz_code, show_date)) |
||||
ai_obj = csv_to_obj(s) |
||||
print('ai_obj', ai_obj) |
||||
print('real_obj', real_obj) |
||||
hall_show_count = get_hall_show_count(ai_obj, real_obj) |
||||
print(hall_show_count) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
count_data(csv_to_obj(s)) |
||||
# show_data('33040301', '2026-07-13') |
||||
@ -1,95 +0,0 @@ |
||||
from hashlib import md5 |
||||
import requests |
||||
from ai.models import * |
||||
import json |
||||
from django.db.models import Q |
||||
import datetime |
||||
|
||||
|
||||
# 从BI的日常影片数据接口中获取信息 |
||||
class MovieData: |
||||
def __init__(self): |
||||
self.salt = '53b22eda5938706a34fd9d44f097bec2' |
||||
self.ts = str(int(datetime.datetime.timestamp(datetime.datetime.now()))) |
||||
self.url = 'https://nation.bi.piao51.cn/nationDataApi/restful/boxoffice/nation/movieSupportData' |
||||
|
||||
# 从BI获取热度数据 |
||||
def get_data_from_bi(self, movie_code, show_type): |
||||
# 基本变量定义 |
||||
today_str = datetime.datetime.today().strftime('%Y-%m-%d') # 当天日期字符串 |
||||
movie_name = '' # 返回的影片名称,以BI返回为准 |
||||
hot_title = '' # CSV表头 |
||||
hot_data = '' # 数据部分 |
||||
# 如果本地有则读取本地数据 |
||||
today_obj = datetime.datetime.strptime(today_str, '%Y-%m-%d') |
||||
if not MovieHotInfo.objects.filter(Q(movie_zz_code=movie_code) & Q(req_date=today_obj)).exists(): |
||||
print(f'热度数据中不存在日期为{today_str}专资编码为{movie_code}数据') |
||||
params = { |
||||
'movieCode': movie_code, |
||||
'timeStamp': self.ts, |
||||
'sign': self.sign(movie_code) |
||||
} |
||||
req = requests.get(self.url, params=params) |
||||
print(req.request.url) |
||||
print(json.dumps(req.json(), indent=4)) |
||||
|
||||
req = req.json() |
||||
|
||||
if (req['success'] is True) and req['data']['movieInfo'] != '': |
||||
print('从BI获取热度数据成功') |
||||
# 基础数据 |
||||
info = req['data']['movieInfo'] |
||||
movie_name = info['movie_name'] |
||||
daily = req['data']['movieDailyBox'] |
||||
if MovieHotInfo.objects.filter(Q(movie_name=movie_name) & Q(req_date=today_str)).exists(): |
||||
print('热度数据中已包含同名影片') |
||||
return '', '', '' |
||||
# 生成标题 |
||||
hot_info_list = ['影片名称', '想看数量', '鼎新热度指数'] |
||||
hot_info_list.extend([f"{daily[n]['businessDate']}(销售)" for n in range(4, 6)]) |
||||
hot_info_list.append(f"{daily[6]['businessDate']}(今日)") |
||||
hot_info_list.extend([f"{daily[n]['businessDate']}(预售)" for n in range(7, 9)]) |
||||
hot_title = f"{','.join(hot_info_list)}" |
||||
# 生成热度指数 |
||||
hot = int((self.to_number(info['xiaohongshu']) + self.to_number(info['shipinhao']) + self.to_number( |
||||
info['douyin']) + self.to_number(info['weibo'])) / 10000) |
||||
# 准备数据部分 |
||||
data_list = [] |
||||
for n in range(4, 6): |
||||
data_list.append({'data': f"{daily[n]['businessDate']}(销售)", 'value': f"{daily[n]['boxRate']}%"}) |
||||
data_list.append({'data': f"{daily[6]['businessDate']}(今日)", 'value': f"{daily[6]['boxRate']}%"}) |
||||
for n in range(7, 9): |
||||
data_list.append({'date': f"{daily[n]['businessDate']}(预售)", 'value': f"{daily[n]['boxRate']}%"}) |
||||
# 写入数据 |
||||
MovieHotInfo.objects.update_or_create( |
||||
movie_zz_code=movie_code, |
||||
movie_name=info['movie_name'], |
||||
req_date=today_str, |
||||
api_response=req, |
||||
show_type=show_type, |
||||
title=hot_title, |
||||
wants=info['wish_num'], |
||||
hots=hot, |
||||
day1_val=daily[4]['boxRate'], |
||||
day2_val=daily[5]['boxRate'], |
||||
day3_val=daily[6]['boxRate'], |
||||
day4_val=daily[7]['boxRate'], |
||||
day5_val=daily[8]['boxRate'], |
||||
day_data=json.dumps(data_list), |
||||
) |
||||
return movie_name, hot_title, hot_data |
||||
|
||||
def sign(self, code): |
||||
_pre = md5((self.salt + f"movieCode={code}&timeStamp={self.ts}").encode()).hexdigest() |
||||
_sign = md5((_pre + self.salt).encode()).hexdigest() |
||||
return _sign |
||||
|
||||
@staticmethod |
||||
def to_number(num_str): |
||||
if num_str == '--': |
||||
return 0 |
||||
if '万' in num_str: |
||||
return int(float(num_str.replace('万', '')) * 10000) |
||||
if '亿' in num_str: |
||||
return int(float(num_str.replace('亿', '')) * 100000000) |
||||
return 0 |
||||
@ -1,307 +0,0 @@ |
||||
import pymysql |
||||
from chinese_calendar import is_holiday |
||||
from pymysql.cursors import DictCursor |
||||
from ai.models import * |
||||
from ai.models import TestCinema |
||||
from ai.utils.sql import * |
||||
from ai.utils.basic_func import * |
||||
import datetime |
||||
import pandas as pd |
||||
import json |
||||
|
||||
|
||||
class GetData: |
||||
def __init__(self, cinema): |
||||
self.conn = pymysql.connect(**json.loads(cinema.db_config)) |
||||
self.cur = self.conn.cursor(cursor=DictCursor) |
||||
self.zz_code = cinema.zz_code |
||||
|
||||
def exit(self): |
||||
try: |
||||
self.cur.close() |
||||
self.conn.close() |
||||
except Exception as e: |
||||
print(e) |
||||
|
||||
# 获取指定日期范围的排片数据 |
||||
def get_show_data(self, start_datetime, end_datetime): |
||||
# print(self.cur.mogrify(GET_SHOW_DATA, (start_datetime, end_datetime))) |
||||
self.cur.execute(GET_SHOW_DATA, (start_datetime, end_datetime)) |
||||
show_data = self.cur.fetchall() |
||||
if len(show_data) == 0: |
||||
return False |
||||
show_data_mapping = { |
||||
'hall_name': '影厅别名', |
||||
'hall_id': '影厅id', |
||||
'movie_name': '影片别名', |
||||
'movie_id': '本地影片id', |
||||
'language': '语言', |
||||
'show_date': '放映日期', |
||||
'start_time': '开始时间', |
||||
'end_time': '结束时间', |
||||
'length': '片长', |
||||
'duration': '场间', |
||||
} |
||||
return self.format_to_csv(show_data, show_data_mapping) |
||||
|
||||
# 获取指定日期的可放映影片 |
||||
def get_available_movie(self, date): |
||||
start_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=29, minutes=59, |
||||
seconds=59) |
||||
end_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=6) |
||||
self.cur.execute(GET_AVAILABLE_MOVIE, (start_datetime, end_datetime)) |
||||
available_movie = self.cur.fetchall() |
||||
available_movie_list = [ |
||||
f"\t{m['cinema_movie_alias']} - 影片id:{m['cinema_movie_id']};" |
||||
for m in available_movie] |
||||
return '\n'.join(available_movie_list) |
||||
|
||||
# 获取指定日期的可用于排片的影片 |
||||
def get_handle_movie(self, date): |
||||
if get_runtime_val('real_target') == '0': |
||||
movie_date_start = datetime.datetime.today().replace(hour=6, minute=0, second=0, microsecond=0) |
||||
movie_date_end = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=29, minutes=59, |
||||
seconds=59) |
||||
show_date_limit = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=6, minutes=0, |
||||
seconds=0) |
||||
bl_bool, bl_str, bl_list = get_black_list(self.zz_code) |
||||
if bl_bool: |
||||
sql = GET_HANDLE_MOVIE_TEST + bl_str + ');' |
||||
print(self.cur.mogrify(sql, (movie_date_start, movie_date_end, show_date_limit, *bl_list))) |
||||
self.cur.execute(sql, (movie_date_start, movie_date_end, show_date_limit, *bl_list)) |
||||
else: |
||||
sql = GET_HANDLE_MOVIE_TEST + bl_str + ');' |
||||
print(self.cur.mogrify(sql, (movie_date_start, movie_date_end, show_date_limit))) |
||||
self.cur.execute(sql, (movie_date_start, movie_date_end, show_date_limit)) |
||||
else: |
||||
start_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=29, minutes=59, |
||||
seconds=59) |
||||
end_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=6) |
||||
|
||||
bl_bool, bl_str, bl_list = get_black_list(self.zz_code) |
||||
if bl_bool: |
||||
sql = GET_HANDLE_MOVIE + bl_str + ');' |
||||
print(self.cur.mogrify(sql, (start_datetime, end_datetime, *bl_list))) |
||||
self.cur.execute(sql, (start_datetime, end_datetime, *bl_list)) |
||||
else: |
||||
sql = GET_HANDLE_MOVIE + bl_str + ');' |
||||
print(self.cur.mogrify(sql, (start_datetime, end_datetime))) |
||||
self.cur.execute(sql, (start_datetime, end_datetime)) |
||||
available_movie = self.cur.fetchall() |
||||
available_movie_list = [ |
||||
f"\t{m['cinema_movie_alias']} - 影片id:{m['cinema_movie_id']},影片时长:{m['cinema_movie_time']},语言:{m['language']},制式:{m['media_type']}, 最早排片开始时间:{m['cinema_movie_start_datetime']}, 最晚排片截止时间:{m['cinema_movie_end_datetime']};" |
||||
for m in available_movie] |
||||
return '\n'.join(available_movie_list) |
||||
|
||||
# 获取新上映的影片 |
||||
def get_new_movie(self, date): |
||||
start_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') |
||||
end_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=29, minutes=59, |
||||
seconds=59) |
||||
self.cur.execute(GET_NEW_MOVIE, (start_datetime, end_datetime)) |
||||
new = self.cur.fetchall() |
||||
new_list = [f"{m['cinema_movie_alias']}" for m in new] |
||||
return new_list |
||||
|
||||
# 为获取影片热度功能提供影院数据 |
||||
def get_movie_info(self, date, show_type='all'): |
||||
start_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=29, minutes=59, |
||||
seconds=59) |
||||
end_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=6) |
||||
bl_bool, bl_str, bl_list = get_black_list(self.zz_code) |
||||
if bl_bool: |
||||
if show_type == "new": |
||||
sql = GET_NEW_MOVIE_INFO + bl_str + GET_MOVIE_INFO_END |
||||
self.cur.execute(sql, (start_datetime, end_datetime, *bl_list)) |
||||
print(self.cur.mogrify(sql, (start_datetime, end_datetime, *bl_list))) |
||||
elif show_type == "old": |
||||
sql = GET_OLD_MOVIE_INFO + bl_str + GET_MOVIE_INFO_END |
||||
self.cur.execute(sql, (end_datetime, start_datetime, *bl_list)) |
||||
print(self.cur.mogrify(sql, (start_datetime, end_datetime, *bl_list))) |
||||
else: |
||||
sql = GET_MOVIE_INFO + bl_str + GET_MOVIE_INFO_END |
||||
self.cur.execute(sql, (start_datetime, end_datetime, *bl_list)) |
||||
print(self.cur.mogrify(sql, (start_datetime, end_datetime, *bl_list))) |
||||
|
||||
else: |
||||
if show_type == "new": |
||||
sql = GET_NEW_MOVIE_INFO + bl_str + GET_MOVIE_INFO_END |
||||
self.cur.execute(sql, (start_datetime, end_datetime)) |
||||
print(self.cur.mogrify(sql, (start_datetime, end_datetime))) |
||||
elif show_type == "old": |
||||
sql = GET_OLD_MOVIE_INFO + bl_str + GET_MOVIE_INFO_END |
||||
self.cur.execute(sql, (end_datetime, start_datetime)) |
||||
print(self.cur.mogrify(sql, (start_datetime, end_datetime))) |
||||
else: |
||||
sql = GET_MOVIE_INFO + bl_str + GET_MOVIE_INFO |
||||
self.cur.execute(sql, (start_datetime, end_datetime)) |
||||
print(self.cur.mogrify(sql, (start_datetime, end_datetime))) |
||||
return self.cur.fetchall() |
||||
|
||||
# 按照场次获取销售数据 |
||||
def get_sell_data(self, start_datetime, end_datetime): |
||||
# print(self.cur.mogrify(GET_SELL_DATA, (start_datetime, end_datetime))) |
||||
self.cur.execute(GET_SELL_DATA, (start_datetime, end_datetime, start_datetime, end_datetime)) |
||||
sell_data = self.cur.fetchall() |
||||
sell_data_mapping = { |
||||
'movie_name': '影片别名', |
||||
'movie_id': '本地影片id', |
||||
'show_date': '放映日期', |
||||
'start_time': '开始时间', |
||||
'hall_name': '影厅别名', |
||||
'hall_id': '影厅id', |
||||
'total_count': '场次观影人数', |
||||
'total_income': '场次收入', |
||||
'seat_num': '影厅座位数', |
||||
'average_price': '平均价', |
||||
'rate': '上座率(单位%)', |
||||
} |
||||
return self.format_to_csv(sell_data, sell_data_mapping) |
||||
|
||||
# 按照影片获取销售数据 |
||||
def get_sell_data_by_movie(self, start_datetime, end_datetime): |
||||
# 获取过去7天的数据 |
||||
new_start_datetime = datetime.datetime.strptime(start_datetime, '%Y-%m-%d %H:%M:%S') + datetime.timedelta( |
||||
days=-7) |
||||
start_datetime = datetime.datetime.strftime(new_start_datetime, '%Y-%m-%d %H:%M:%S') |
||||
self.cur.execute(GET_SELL_DATA_BY_MOVIE, (start_datetime, end_datetime, start_datetime, end_datetime)) |
||||
sell_data = self.cur.fetchall() |
||||
print('get_sell_data_by_movie', start_datetime, end_datetime, sell_data) |
||||
sell_data_mapping = { |
||||
'movie_alias_name': '影片别名', |
||||
'movie_id': '本地影片id', |
||||
'total_count': '观影总人数', |
||||
'average_show_count': '场均人次', |
||||
'average_seat_rate': '平均上座率(单位%)', |
||||
'total_income': '票房总收入', |
||||
'average_ticket_price': '平均票价', |
||||
'average_show_ticket_price': '场均收入', |
||||
'show_count': '总场次数', |
||||
'show_rate': '排片占比(单位%)', |
||||
} |
||||
return self.format_to_csv(sell_data, sell_data_mapping) |
||||
|
||||
# 按工作日和节假日计算销售数据 |
||||
def get_sell_data_by_day_type(self, start_datetime, end_datetime): |
||||
# 获取过去7天的数据 |
||||
print('get_sell_data_by_day_type_start_datetime', start_datetime) |
||||
date_list = [datetime.datetime.strptime(start_datetime, '%Y-%m-%d %H:%M:%S') + datetime.timedelta(days=n) for n |
||||
in range(-7, 0, 1)] |
||||
print('get_sell_data_by_day_type', date_list) |
||||
sell_data_dict = { |
||||
'holiday': [], |
||||
'workday': [], |
||||
} |
||||
for date in date_list: |
||||
start = datetime.datetime.strftime(date, '%Y-%m-%d %H:%M:%S') |
||||
end = datetime.datetime.strftime(date + datetime.timedelta(days=1), '%Y-%m-%d %H:%M:%S') |
||||
self.cur.execute(GET_SELL_DATA_SELF_CALCULATE, (start, end)) |
||||
sell_data = self.cur.fetchall() |
||||
print('get_sell_data_by_movie', start, end, sell_data) |
||||
if is_holiday(date): |
||||
sell_data_dict['holiday'].append(sell_data) |
||||
else: |
||||
sell_data_dict['workday'].append(sell_data) |
||||
|
||||
movie_sell_data = dict() |
||||
for key, val in sell_data_dict.items(): |
||||
print(key, val) |
||||
for sell in val: |
||||
print(sell) |
||||
for m in sell: |
||||
print(m) |
||||
if m['movie_id'] not in movie_sell_data.keys(): |
||||
movie_sell_data[m['movie_id']] = { |
||||
'movie_alias_name': m['movie_alias_name'], |
||||
'movie_id': m['movie_id'], |
||||
'viewer': { |
||||
'holiday': 0, |
||||
'workday': 0, |
||||
}, |
||||
'income': { |
||||
'holiday': 0.0, |
||||
'workday': 0.0, |
||||
}, |
||||
'show': { |
||||
'holiday': 0, |
||||
'workday': 0, |
||||
} |
||||
} |
||||
movie_sell_data[m['movie_id']]['viewer'][key] += int(m['total_viewers']) |
||||
movie_sell_data[m['movie_id']]['income'][key] += float(m['total_income']) |
||||
movie_sell_data[m['movie_id']]['show'][key] += int(m['total_show']) |
||||
print('get_sell_data_by_day_type', movie_sell_data) |
||||
movie_sell_data_list = [] |
||||
for m in movie_sell_data.values(): |
||||
movie_sell_data_list.append({ |
||||
'movie_alias_name': m['movie_alias_name'], |
||||
'movie_id': m['movie_id'], |
||||
'average_viewer_workday': round( |
||||
float(0 if m['show']['workday'] == 0 else m['viewer']['workday'] / m['show']['workday']), 2), |
||||
'average_ticket_price_workday': round( |
||||
float(0 if m['viewer']['workday'] == 0 else m['income']['workday'] / m['viewer']['workday']), 2), |
||||
'average_income_workday': round( |
||||
float(0 if m['show']['workday'] == 0 else m['income']['workday'] / m['show']['workday']), 2), |
||||
'average_viewer_holiday': round( |
||||
float(0 if m['show']['holiday'] == 0 else m['viewer']['holiday'] / m['show']['holiday']), 2), |
||||
'average_ticket_price_holiday': round( |
||||
float(0 if m['viewer']['holiday'] == 0 else m['income']['holiday'] / m['viewer']['holiday']), 2), |
||||
'average_income_holiday': round( |
||||
float(0 if m['show']['holiday'] == 0 else m['income']['holiday'] / m['show']['holiday']), 2), |
||||
}) |
||||
sell_data_mapping = { |
||||
'movie_alias_name': '影片别名', |
||||
'movie_id': '本地影片id', |
||||
'average_viewer_workday': '场均人次(工作日)', |
||||
'average_ticket_price_workday': '平均票价(工作日)', |
||||
'average_income_workday': '场均收入(工作日)', |
||||
'average_viewer_holiday': '场均人次(节假日)', |
||||
'average_ticket_price_holiday': '平均票价(节假日)', |
||||
'average_income_holiday': '场均收入(节假日)', |
||||
} |
||||
return self.format_to_csv(movie_sell_data_list, sell_data_mapping) |
||||
|
||||
# 获取指定范围的影片销售总额 |
||||
def get_total_income(self, start_datetime, end_datetime): |
||||
print(self.cur.mogrify(GET_TOTAL_INCOME, (start_datetime, end_datetime, start_datetime, end_datetime))) |
||||
self.cur.execute(GET_TOTAL_INCOME, (start_datetime, end_datetime, start_datetime, end_datetime)) |
||||
return self.cur.fetchone()['total_income'] |
||||
|
||||
# 获取影厅支持的制式 |
||||
def get_hall_media_type(self): |
||||
self.cur.execute(GET_HALL_MEDIA_TYPE) |
||||
hall_data = self.cur.fetchall() |
||||
# print(hall_data) |
||||
hall_dict = dict() |
||||
|
||||
# 处理成对应的字典格式 {"影厅别名": {"hall_id":影厅id,"media_type": 影片制式列表}} |
||||
for hall in hall_data: |
||||
if hall['cinema_hall_name'] not in hall_dict.keys(): |
||||
hall_dict[hall['cinema_hall_name']] = { |
||||
'hall_id': hall['cinema_hall_id'], |
||||
'media_type': [hall['media_type'], ] |
||||
} |
||||
else: |
||||
hall_dict[hall['cinema_hall_name']]['media_type'].append(hall['media_type']) |
||||
# 拼装字符串 |
||||
hall_str_list = [] |
||||
for hall, val in hall_dict.items(): |
||||
hall_str_list.append(f"\t{hall} - 影厅id:{val['hall_id']},支持制式:{','.join(val['media_type'])};") |
||||
return '\n'.join(hall_str_list) |
||||
|
||||
# 获取模板日期 |
||||
def get_template_date(self, start_datetime, end_datetime): |
||||
basic_val = 4 |
||||
self.cur.execute(GET_TEMPLATE_DATE, (start_datetime, end_datetime, basic_val)) |
||||
template_date = self.cur.fetchall()[0]['template_date'] |
||||
return template_date |
||||
|
||||
# 数据转csv格式字符串 |
||||
@staticmethod |
||||
def format_to_csv(dict_data, mapping): |
||||
# print(dict_data) |
||||
new_dict = [{mapping[k]: v for k, v in d.items()} for d in dict_data] |
||||
return pd.DataFrame(new_dict).to_csv(index=False) |
||||
|
||||
def get_media_type(self): |
||||
self.cur.execute(GET_HALL_MEDIA_TYPE) |
||||
@ -1,218 +0,0 @@ |
||||
from django.db.models import Q |
||||
import datetime |
||||
from ai.models import * |
||||
from ai.utils.show_database import GetData |
||||
from ai.utils.datetime_format import * |
||||
from ai.utils.movie_data import * |
||||
from ai.utils.basic_func import * |
||||
|
||||
|
||||
def get_cinema_show_result_func(_zz_code, _show_date): |
||||
cinema = TestCinema.objects.filter(zz_code=_zz_code).first() |
||||
start = datetime.datetime.strftime(datetime.datetime.strptime(_show_date, '%Y-%m-%d') + datetime.timedelta(hours=6), |
||||
'%Y-%m-%d %H:%M:%S') |
||||
end = datetime.datetime.strftime( |
||||
datetime.datetime.strptime(_show_date, '%Y-%m-%d') + datetime.timedelta(hours=29, minutes=59, seconds=59), |
||||
'%Y-%m-%d %H:%M:%S') |
||||
show = '' |
||||
income = '0' |
||||
if cinema: |
||||
print(cinema) |
||||
data = GetData(cinema) |
||||
show = data.get_show_data(start, end) |
||||
income = data.get_total_income(start, end) |
||||
print(show, income) |
||||
show_db = AiShow.objects.filter(Q(is_ai_show=False) & Q(zz_code=_zz_code) & Q(show_date=_show_date)).order_by( |
||||
'-id').first() |
||||
if show is False: |
||||
show = ('影厅别名,影厅id,影片别名,本地影片id,语言,放映日期,开始时间,结束时间,片长,场间') |
||||
income = '0' |
||||
if income is None: |
||||
income = '0' |
||||
if show_db: |
||||
print('show_db', show_db) |
||||
show_db.show = show |
||||
show_db.sales = income |
||||
show_db.save() |
||||
else: |
||||
try: |
||||
AiShow.objects.create( |
||||
cinema=cinema.name, |
||||
zz_code=cinema.zz_code, |
||||
show_date=_show_date, |
||||
is_ai_show=False, |
||||
show=show, |
||||
sales=income, |
||||
prompt='', |
||||
result='', |
||||
message='', |
||||
take_times=0, |
||||
take_tokens='0', |
||||
create_datetime=datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S'), |
||||
) |
||||
except Exception as e: |
||||
print(e) |
||||
return show, income |
||||
|
||||
|
||||
# 获取模板日期排片数据 |
||||
def get_template_show(cinema, show_date): |
||||
history_start, history_end, target_start, target_end = get_data_datetime(show_date) |
||||
data = GetData(cinema) |
||||
temp_date_obj = data.get_template_date(history_start, history_end) |
||||
temp_date = datetime.datetime.strftime(temp_date_obj, '%Y-%m-%d') |
||||
temp_start = datetime.datetime.strftime(temp_date_obj + datetime.timedelta(hours=6), '%Y-%m-%d %H:%M:%S') |
||||
temp_end = datetime.datetime.strftime(temp_date_obj + datetime.timedelta(hours=29, minutes=59, seconds=59), |
||||
'%Y-%m-%d %H:%M:%S') |
||||
temp_show = data.get_show_data(temp_start, temp_end) |
||||
return temp_show, temp_date |
||||
|
||||
|
||||
# 获取模板日期排片数据, 从昨天开始找一天有排片的数据做为模板,如果没有则返回None |
||||
def get_template_show_tomorrow(cinema): |
||||
i = -1 |
||||
temp_show = False |
||||
while temp_show is False or i >= -3: |
||||
tomorrow = datetime.datetime.combine(datetime.date.today() + datetime.timedelta(days=i), datetime.time()) |
||||
tomorrow_start = datetime.datetime.strftime(tomorrow + datetime.timedelta(hours=6), '%Y-%m-%d %H:%M:%S') |
||||
tomorrow_end = datetime.datetime.strftime(tomorrow + datetime.timedelta(hours=29, minutes=59, seconds=59), |
||||
'%Y-%m-%d %H:%M:%S') |
||||
tomorrow_str = datetime.datetime.strftime(tomorrow, '%Y-%m-%d') |
||||
data = GetData(cinema) |
||||
temp_show = data.get_show_data(tomorrow_start, tomorrow_end) |
||||
if temp_show is not False: |
||||
return temp_show, tomorrow_str |
||||
else: |
||||
i -= 1 |
||||
return temp_show, '' |
||||
|
||||
|
||||
# 获取目标日期排片数据 |
||||
def get_target_show(cinema, show_date): |
||||
history_start, history_end, target_start, target_end = get_data_datetime(show_date) |
||||
data = GetData(cinema) |
||||
target_date_show = data.get_show_data(target_start, target_end) |
||||
if not target_date_show: |
||||
target_date_show = '影厅别名,影厅id,影片别名,本地影片id,语言,放映日期,开始时间,结束时间,片长,场间' |
||||
return target_date_show |
||||
|
||||
|
||||
# 从BI接口获取影片热度信息 |
||||
def get_movie_hot_info_from_bi(cinema, show_date): |
||||
data = GetData(cinema) |
||||
show_type_list = ['old', 'new'] |
||||
for show_type in show_type_list: |
||||
print('get_movie_hot_info_from_bi', show_type) |
||||
movie = data.get_movie_info(show_date, show_type) |
||||
movie_data = MovieData() |
||||
for m in movie: |
||||
name, title, hot = movie_data.get_data_from_bi(m['cinema_movie_num'], show_type) |
||||
print('name, title, hot', name, title, hot) |
||||
return True |
||||
|
||||
|
||||
# 从本地数据库中获取影片热度信息 |
||||
def get_all_movie_hot_info(req_date: str = 'today', show_type: str = 'old', get_num: int = 10): |
||||
if req_date == 'today': |
||||
date_sr = datetime.datetime.today().strftime('%Y-%m-%d') |
||||
else: |
||||
date_sr = req_date |
||||
hot_order_day = get_runtime_val('hot_order_day') |
||||
hot_data = MovieHotInfo.objects.filter(Q(req_date=date_sr) & Q(show_type=show_type)).order_by(hot_order_day).all()[ |
||||
:get_num] |
||||
if hot_data: |
||||
print('if hot_data') |
||||
title = f"\t{hot_data[0].title}" |
||||
data_list = [title] |
||||
else: |
||||
return [] |
||||
for hot in hot_data: |
||||
print(f"\t{hot.movie_name},{hot.wants},{hot.hots},{','.join([d['value'] for d in json.loads(hot.day_data)])}") |
||||
data_list.append( |
||||
f"\t{hot.movie_name},{hot.wants},{hot.hots},{','.join([d['value'] for d in json.loads(hot.day_data)])}") |
||||
print(data_list) |
||||
return data_list |
||||
|
||||
|
||||
# 模拟用户设置的新片推荐数量 |
||||
def get_new_suggestion(cinema, show_date): |
||||
data = GetData(cinema) |
||||
tomorrow = datetime.datetime.today() + datetime.timedelta(days=-1) |
||||
show_date_obj = datetime.datetime.strptime(show_date, '%Y-%m-%d') |
||||
delta = (show_date_obj - tomorrow).days |
||||
date_list = [datetime.datetime.strftime(tomorrow + datetime.timedelta(days=i), "%Y-%m-%d") for i in |
||||
range(0, delta + 2)] |
||||
print('get_new_suggestion-date_list', date_list) |
||||
new_movie_list = [] |
||||
for date in date_list: |
||||
movie = data.get_movie_info(date, 'new') |
||||
for m in movie: |
||||
print(m['cinema_movie_cn_name']) |
||||
new_movie = NewMovieSuggestion.objects.filter( |
||||
Q(movie_name=m['cinema_movie_cn_name']) & Q(zz_code=cinema.zz_code) & Q(delete_flag=False)).first() |
||||
if new_movie is not None: |
||||
if new_movie.suggestion == '0': |
||||
text = f"\t{m['cinema_movie_cn_name']} 建议排一些场次;" |
||||
else: |
||||
text = f"\t{m['cinema_movie_cn_name']} 的不同制式版本总计建议排片占比为{new_movie.suggestion}%;" |
||||
new_movie_list.append(text) |
||||
if len(new_movie_list) > 0: |
||||
return '\n'.join(new_movie_list) |
||||
return None |
||||
|
||||
|
||||
def get_new_movie(start_date=None): |
||||
cinema_list = TestCinema.objects.all() |
||||
start_date_obj = datetime.datetime.today() |
||||
if start_date is not None: |
||||
try: |
||||
start_date_obj = datetime.datetime.strptime(start_date, '%Y-%m-%d') |
||||
except ValueError: |
||||
print(start_date) |
||||
return False |
||||
date_list = [datetime.datetime.strftime(start_date_obj + datetime.timedelta(days=i), '%Y-%m-%d') for i in |
||||
range(1, 8)] |
||||
new_dict = dict() |
||||
new_data = False |
||||
for cinema in cinema_list: |
||||
data = GetData(cinema) |
||||
new_dict[cinema.name] = dict() |
||||
for date_val in date_list: |
||||
new_list = data.get_movie_info(date_val, 'new') |
||||
new_dict[cinema.name][date_val] = [] |
||||
for new in new_list: |
||||
print(new) |
||||
if NewMovieSuggestion.objects.filter( |
||||
Q(movie_zz_code=new['cinema_movie_num']) & Q(zz_code=cinema.zz_code)).first() is None: |
||||
NewMovieSuggestion.objects.create( |
||||
cinema=cinema.name, |
||||
zz_code=cinema.zz_code, |
||||
movie_zz_code=new['cinema_movie_num'], |
||||
movie_name=new['cinema_movie_cn_name'], |
||||
suggestion=0, |
||||
delete_flag=True) |
||||
new_dict[cinema.name][date_val].append( |
||||
{'movie_zz_code': new['cinema_movie_num'], 'movie_name': new['cinema_movie_cn_name']}) |
||||
new_data = True |
||||
return None if new_data == False else new_dict |
||||
|
||||
|
||||
# 模拟用户设置的新片推荐数量 |
||||
def get_movie_guidance(cinema, show_date): |
||||
movie_guidance = MovieGuidance.objects.filter( |
||||
Q(zz_code=cinema.zz_code) & Q(show_date=show_date) & Q(delete_flag=False)).all() |
||||
if movie_guidance: |
||||
movie_list = [] |
||||
for m in movie_guidance: |
||||
if m.type == 'rate': |
||||
movie_list.append(f"\t{m.movie_name} 强制排片占比必须大于{m.guidance}%") |
||||
else: |
||||
movie_list.append(f"\t{m.movie_name} 强制排片至少{m.guidance}场") |
||||
return '\n'.join(movie_list) |
||||
return '\t无' |
||||
|
||||
|
||||
def get_test_date_from_db(cinema_code: str, show_date: str) -> list: |
||||
test_data = AiShow.objects.filter( |
||||
Q(zz_code=cinema_code) & Q(show_date=show_date) & Q(is_ai_show=True)).order_by('-create_datetime').all() |
||||
return [(test.create_datetime, test.is_manual_test) for test in test_data] |
||||
@ -1,185 +0,0 @@ |
||||
import json |
||||
from ai.models import * |
||||
from ai.utils.show_prompt import * |
||||
from ai.utils.show_func import * |
||||
from ai.utils.basic_func import * |
||||
import datetime |
||||
from django_redis import get_redis_connection |
||||
from django.db.models import Q |
||||
from ai.models import TestCinema |
||||
import re |
||||
|
||||
|
||||
# ai排片主流程 |
||||
def show_main_process(zz_code=None, day_delta=None): |
||||
# 查看状态 |
||||
redis_conn = get_redis_connection() |
||||
redis_key = f'ai_show{datetime.date.today().strftime("%Y%m%d")}' |
||||
if redis_conn.exists(redis_key): |
||||
return False |
||||
# 获取影院列表 |
||||
redis_conn.set(redis_key, 1, ex=60 * 60 * 20) |
||||
if not zz_code: |
||||
test_cinema_list = TestCinema.objects.filter(is_active=True).all() |
||||
else: |
||||
test_cinema_list = TestCinema.objects.filter(Q(zz_code=zz_code) & Q(is_active=True)).all() |
||||
day_delta = int(get_runtime_val('day_delta')) if day_delta is None else int(day_delta) |
||||
# 获取提示词版本 |
||||
prompt_ver = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='version') & Q(prompt_key='ShowPromptVersion')).first().prompt_val |
||||
# 开始处理提示词 |
||||
# 生成目标日期 |
||||
show_date = datetime.date.strftime(datetime.date.today() + datetime.timedelta(days=day_delta), '%Y-%m-%d') |
||||
# 获取当前模型 |
||||
model = AiModel.objects.filter(current_used=True).first() |
||||
|
||||
# 按照影院生成排片 |
||||
for cinema in test_cinema_list: |
||||
print(cinema.name) |
||||
show_ai = ShowAI(cinema, show_date) |
||||
# template_show, template_date = get_template_show(cinema, show_date) |
||||
template_show, template_date = get_template_show_tomorrow(cinema) |
||||
if str(get_runtime_val('real_target')) == '1': |
||||
target_show = get_target_show(cinema, show_date) |
||||
else: |
||||
target_show = '影厅别名,影厅id,影片别名,本地影片id,语言,放映日期,开始时间,结束时间,片长,场间' |
||||
prompt = show_ai.general_prompt() |
||||
if str(get_runtime_val('test')) == '0': |
||||
start = datetime.datetime.now() # 开始计时 |
||||
result, message, tokens = show_ai.get_show_result_ai() |
||||
end = datetime.datetime.now() # 结束计时 |
||||
print('prompt:', prompt) |
||||
print('result:', result) |
||||
print('message:', message) |
||||
print('tokens:', tokens) |
||||
|
||||
# 获取排片数据 |
||||
print('result:', result) |
||||
if model.config_name in ['lmstudio_qwen3.6_35b', 'company_qwen3.5_35b']: |
||||
result_obj = json.loads(result.replace('```json', '').replace('}\n```', '}').strip()) |
||||
else: |
||||
result_obj = json.loads(result.strip()) |
||||
|
||||
show_result = result_obj['show'] |
||||
# 预测排片数据 |
||||
if isinstance(show_result, list): |
||||
show = json_to_csv(show_result) |
||||
else: |
||||
show = data_cleansing(show_result.replace('```', '').replace('csv', '').strip()) |
||||
|
||||
# 预测销售数据 |
||||
sales = str(result_obj['income']).strip() |
||||
|
||||
# 处理返回结果 |
||||
try: |
||||
AiShow.objects.create( |
||||
cinema=cinema.name, |
||||
zz_code=cinema.zz_code, |
||||
show_date=show_date, |
||||
is_ai_show=True, |
||||
is_manual_test=False, |
||||
ai_model=model.config_name, |
||||
template=template_show, |
||||
temp_date=template_date, |
||||
target=target_show, |
||||
show=show, |
||||
sales=sales, |
||||
prompt=prompt, |
||||
result=result, |
||||
message=message, |
||||
take_times=int((end - start).seconds), |
||||
take_tokens=tokens, |
||||
prompt_version=prompt_ver, |
||||
create_datetime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S'), |
||||
) |
||||
except Exception as e: |
||||
print(e) |
||||
return True |
||||
|
||||
|
||||
def show_manual_process(zz_code: str, show_date: str, prompt: str): |
||||
cinema = TestCinema.objects.filter(zz_code=zz_code).first() |
||||
ai = ShowAI(cinema, show_date) |
||||
|
||||
# 处理模板日期的排片数据 |
||||
template_show, template_date = get_template_show_tomorrow(cinema) |
||||
|
||||
# 处理目标日期的排片数据 |
||||
if str(get_runtime_val('real_target')) == '1': |
||||
target_show = get_target_show(cinema, show_date) |
||||
else: |
||||
target_show = '影厅别名,影厅id,影片别名,本地影片id,语言,放映日期,开始时间,结束时间,片长,场间' |
||||
|
||||
# 开始请求AI |
||||
start = datetime.datetime.now() # 开始计时 |
||||
result, message, tokens = ai.get_show_result_ai(prompt) |
||||
end = datetime.datetime.now() # 结束计时 |
||||
# 打印返回结果 |
||||
print('prompt:', prompt) |
||||
print('result:', result) |
||||
print('message:', message) |
||||
print('tokens:', tokens) |
||||
|
||||
# 获取当前模型根据模型处理返回结果 |
||||
model = AiModel.objects.filter(current_used=True).first() |
||||
if model.config_name in ['lmstudio_qwen3.6_35b', 'company_qwen3.5_35b']: |
||||
result_obj = json.loads(result.replace('```json', '').replace('}\n```', '}').strip()) |
||||
else: |
||||
result_obj = json.loads(result.strip()) |
||||
|
||||
# 预测排片数据 |
||||
show_result = result_obj['show'] |
||||
# 预测排片数据 |
||||
if isinstance(show_result, list): |
||||
show = json_to_csv(show_result) |
||||
else: |
||||
show = data_cleansing(show_result.replace('```', '').replace('csv', '').strip()) |
||||
|
||||
# 预测销售数据 |
||||
sales = str(result_obj['income']).strip() |
||||
|
||||
# 处理返回结果 |
||||
try: |
||||
AiShow.objects.create( |
||||
cinema=cinema.name, |
||||
zz_code=cinema.zz_code, |
||||
show_date=show_date, |
||||
is_ai_show=True, |
||||
is_manual_test=True, |
||||
ai_model=model.config_name, |
||||
template=template_show, |
||||
temp_date=template_date, |
||||
target=target_show, |
||||
show=show, |
||||
sales=sales, |
||||
prompt=prompt, |
||||
result=result, |
||||
message=message, |
||||
take_times=int((end - start).seconds), |
||||
take_tokens=tokens, |
||||
prompt_version=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), |
||||
create_datetime=datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S'), |
||||
) |
||||
except Exception as e: |
||||
print(e) |
||||
return e |
||||
return result |
||||
|
||||
|
||||
def get_prompt_process(zz_code=None, show_date=None): |
||||
print('zz_code:', zz_code) |
||||
print('show_date:', show_date) |
||||
if zz_code == '' or show_date == '' : |
||||
return '请检查影院编码和排片日期' |
||||
# 获取影院 |
||||
cinema = TestCinema.objects.filter(Q(zz_code=zz_code) & Q(is_active=True)).first() |
||||
# 获取提示词版本 |
||||
prompt_ver = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='version') & Q(prompt_key='ShowPromptVersion')).first().prompt_val |
||||
# 开始处理提示词 |
||||
# 按照影院生成排片 |
||||
print(cinema.name) |
||||
show_ai = ShowAI(cinema, show_date) |
||||
prompt = show_ai.general_prompt() |
||||
return prompt |
||||
|
||||
@ -1,274 +0,0 @@ |
||||
from django.db.models import Q |
||||
from ai.models import PromptTemplate |
||||
from ai.utils.show_database import GetData |
||||
from ai.utils.datetime_format import * |
||||
from ai.utils.show_func import * |
||||
from ai.utils.basic_func import * |
||||
import datetime |
||||
import random |
||||
import json |
||||
from openai import OpenAI |
||||
|
||||
|
||||
class ShowAI: |
||||
def __init__(self, cinema_info, show_date): |
||||
self.cinema = cinema_info |
||||
self.user_config = json.loads(cinema_info.user_config) |
||||
self.show_date = show_date |
||||
self.is_summer = is_summer(show_date) |
||||
self.prompt = "" |
||||
self.model = get_current_model() |
||||
self.ai_model_name = self.model.model_name |
||||
self.client = OpenAI( |
||||
api_key=self.model.api_key, |
||||
base_url=self.model.base_url, |
||||
) |
||||
|
||||
# 生成提示词 |
||||
# def general_prompt(self): |
||||
# data = GetData(self.cinema) |
||||
# # 准备各种日期时间 |
||||
# history_start, history_end, target_start, target_end = get_data_datetime(self.show_date) |
||||
# temp = datetime.datetime.strftime(data.get_template_date(history_start, history_end), '%Y-%m-%d') |
||||
# history_date, target_date, target_date_is_holiday, template_date, template_date_is_holiday = get_date_type( |
||||
# self.show_date, temp) |
||||
# # print(history_start, history_end, target_start, target_end, history_date, show_date, template_date) |
||||
# |
||||
# # 开始处理提示词 |
||||
# prompt_list = [] |
||||
# # 处理排片数据 |
||||
# pre_data = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='PreData')).first().prompt_val # 获取提示词模板 |
||||
# pre_data = pre_data.replace('{history_show}', data.get_show_data(history_start, history_end)) # 处理排片数据 |
||||
# pre_data = pre_data.replace('{history_sales}', data.get_sell_data(history_start, history_end)) # 处理销售数据 |
||||
# pre_data = pre_data.replace('{target_already_show}', |
||||
# '\t无' if data.get_show_data(target_start, |
||||
# target_end) is False else data.get_show_data( |
||||
# target_start, target_end)) # 处理目标日期已排场次数据 |
||||
# pre_data = pre_data.replace('{reference_date}', history_date) # 处理参考日期 |
||||
# pre_data = pre_data.replace('{template_date}', template_date) # 处理模板日期 |
||||
# pre_data = pre_data.replace('{target_date}', target_date) # 处理目标日期 |
||||
# prompt_list.append(pre_data) |
||||
# |
||||
# # 处理角色说明 |
||||
# role = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Role')).first().prompt_val # 获取提示词模板 |
||||
# role = role.replace('{template_date}', template_date) |
||||
# prompt_list.append(role) |
||||
# |
||||
# # 处理影片和影厅信息 |
||||
# movie_hall = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='MovieHall')).first().prompt_val # 获取提示词模板 |
||||
# movie_hall = movie_hall.replace('{available_movie}', data.get_available_movie(self.show_date)) # 处理上映影片 |
||||
# movie_hall = movie_hall.replace('{handle_movie}', data.get_handle_movie(self.show_date)) # 处理可排影片 |
||||
# movie_hall = movie_hall.replace('{hall_info}', data.get_hall_media_type()) # 处理影厅信息 |
||||
# free_hall = self.user_config['holiday_date_free_hall'] if target_date_is_holiday else self.user_config[ |
||||
# 'holiday_date_free_hall'] |
||||
# movie_hall = movie_hall.replace('{free_hall}', |
||||
# '\t无' if len(free_hall) == 0 else '\n'.join( |
||||
# f'\t{h};' for h in free_hall)) # 处理不可排片影厅 |
||||
# prompt_list.append(movie_hall) |
||||
# |
||||
# # 影片热度和排片占比 |
||||
# movie_hot = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Hot')).first().prompt_val # 获取提示词模板 |
||||
# movie_hot = movie_hot.replace('{movie_hot}', '\n'.join(get_all_movie_hot_info(self.cinema, self.show_date))) |
||||
# prompt_list.append(movie_hot) |
||||
# |
||||
# # 处理具体要求 |
||||
# rules = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Rules')).first().prompt_val # 获取提示词模板 |
||||
# rules = rules.replace('{template_date}', template_date) # 处理模板日期 |
||||
# # 获取新片 |
||||
# # new_movie_str_list = [] |
||||
# # new_movie = data.get_new_movie(self.show_date) |
||||
# # for new in new_movie: |
||||
# # new_movie_str_list.append( |
||||
# # f"\t增加{new}的场次,建议排{str(random.randint(2, 4))}场,可根据影片热度和口碑适当增加;") |
||||
# # rules = rules.replace('{new_movie}', |
||||
# # '\t无新片上映' if len(new_movie_str_list) == 0 else '\n'.join( |
||||
# # new_movie_str_list)) # 处理新片数据 |
||||
# prompt_list.append(rules) |
||||
# |
||||
# # 处理基本规则 |
||||
# basic = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Basic')).first().prompt_val # 获取提示词模板 |
||||
# start = self.user_config['holiday_date_start'] if target_date_is_holiday else self.user_config[ |
||||
# 'work_date_start'] |
||||
# end = self.user_config['holiday_date_end'] if target_date_is_holiday else self.user_config['work_date_end'] |
||||
# basic = basic.replace('{start}', start) |
||||
# basic = basic.replace('{end}', end) |
||||
# prompt_list.append(basic) |
||||
# |
||||
# # 处理增减场次规则 |
||||
# add_reduce = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='AddReduce')).first().prompt_val # 获取提示词模板 |
||||
# prompt_list.append(add_reduce) |
||||
# |
||||
# # 处理黄金时段 |
||||
# prime_time = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='PrimeTime')).first().prompt_val # 获取提示词模板 |
||||
# prompt_list.append(prime_time) |
||||
# |
||||
# # 处理暑期档 |
||||
# summer = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Summer')).first().prompt_val # 获取提示词模板 |
||||
# prompt_list.append(summer) |
||||
# |
||||
# # 处理输出目标 |
||||
# output = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Output')).first().prompt_val # 获取提示词模板 |
||||
# prompt_list.append(output) |
||||
# |
||||
# # 打印提示词 |
||||
# self.prompt = '\n'.join(prompt_list) |
||||
# print(self.prompt) |
||||
# # 关闭数据库连接 |
||||
# data.exit() |
||||
# return self.prompt |
||||
|
||||
# 生成提示词(对应V1.2版本) |
||||
def general_prompt(self): |
||||
data = GetData(self.cinema) |
||||
# 准备各种日期时间 |
||||
template_show, template_date = get_template_show_tomorrow(self.cinema) |
||||
history_start, history_end, target_start, target_end = get_data_datetime_template(self.show_date, template_date) |
||||
# temp = datetime.datetime.strftime(data.get_template_date(history_start, history_end), '%Y-%m-%d') |
||||
history_date, target_date, target_date_is_holiday, template_date, template_date_is_holiday = get_date_type( |
||||
self.show_date, template_date) |
||||
# print(history_start, history_end, target_start, target_end, history_date, show_date, template_date) |
||||
|
||||
# 开始处理提示词 |
||||
prompt_list = [] |
||||
# 处理排片数据 |
||||
pre_data = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='PreData')).first().prompt_val # 获取提示词模板 |
||||
pre_data = pre_data.replace('{template_show}', template_show) # 处理排片数据 |
||||
# pre_data = pre_data.replace('{history_sales}', |
||||
# data.get_sell_data_by_movie(history_start, history_end)) # 处理销售数据 |
||||
pre_data = pre_data.replace('{history_sales}', |
||||
data.get_sell_data_by_day_type(history_start, history_end)) # 处理销售数据 |
||||
get_movie_hot_info_from_bi(self.cinema, self.show_date) # 获取全部影片的热度信息 |
||||
movie_data_old = get_all_movie_hot_info('today', 'old') |
||||
movie_data_new = get_all_movie_hot_info('today', 'new') |
||||
|
||||
pre_data = pre_data.replace('{hot_movie_old}', |
||||
'\n'.join(movie_data_old) if len(movie_data_old) > 0 else '\t无') |
||||
pre_data = pre_data.replace('{hot_movie_new}', |
||||
'\n'.join(movie_data_new) if len(movie_data_new) > 0 else '\t无') |
||||
if get_runtime_val('real_target') == '1': |
||||
pre_data = pre_data.replace('{target_already_show}', |
||||
'\t无' if data.get_show_data(target_start, |
||||
target_end) is False else data.get_show_data( |
||||
target_start, target_end)) # 处理目标日期已排场次数据 |
||||
else: |
||||
pre_data = pre_data.replace('{target_already_show}', '无') # 处理目标日期已排场次数据 |
||||
# pre_data = pre_data.replace('{reference_date}', history_date) # 处理参考日期 |
||||
pre_data = pre_data.replace('{template_date}', template_date) # 处理模板日期 |
||||
pre_data = pre_data.replace('{target_date}', target_date) # 处理目标日期 |
||||
prompt_list.append(pre_data) |
||||
|
||||
# 处理角色说明 |
||||
role = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Role')).first().prompt_val # 获取提示词模板 |
||||
role = role.replace('{template_date}', template_date) |
||||
prompt_list.append(role) |
||||
|
||||
# 处理影片和影厅信息 |
||||
movie_hall = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='MovieHall')).first().prompt_val # 获取提示词模板 |
||||
# movie_hall = movie_hall.replace('{available_movie}', data.get_available_movie(self.show_date)) # 处理上映影片 |
||||
movie_hall = movie_hall.replace('{handle_movie}', data.get_handle_movie(self.show_date)) # 处理可排影片 |
||||
movie_hall = movie_hall.replace('{hall_info}', data.get_hall_media_type()) # 处理影厅信息 |
||||
free_hall = self.user_config['holiday_date_free_hall'] if target_date_is_holiday else self.user_config[ |
||||
'holiday_date_free_hall'] |
||||
movie_hall = movie_hall.replace('{free_hall}', |
||||
'\t无' if len(free_hall) == 0 else '\n'.join( |
||||
f'\t{h};' for h in free_hall)) # 处理不可排片影厅 |
||||
prompt_list.append(movie_hall) |
||||
|
||||
# 处理具体要求 |
||||
rules = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Rules')).first().prompt_val # 获取提示词模板 |
||||
rules = rules.replace('{template_date}', template_date) # 处理模板日期 |
||||
rules = rules.replace('{available_movie}', data.get_available_movie(self.show_date)) # 处理上映影片 |
||||
new_suggestion = get_new_suggestion(self.cinema, self.show_date) |
||||
rules = rules.replace('{new_movie_suggestion}', |
||||
'\t无' if new_suggestion is None else new_suggestion) # 处理新片推荐数量 |
||||
prompt_list.append(rules) |
||||
|
||||
# 处理基本规则 |
||||
basic = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Basic')).first().prompt_val # 获取提示词模板 |
||||
start = self.user_config['holiday_date_start'] if target_date_is_holiday or self.is_summer else \ |
||||
self.user_config['work_date_start'] |
||||
end = self.user_config['holiday_date_end'] if target_date_is_holiday or self.is_summer else self.user_config[ |
||||
'work_date_end'] |
||||
basic = basic.replace('{start}', start) |
||||
basic = basic.replace('{end}', end) |
||||
prompt_list.append(basic) |
||||
|
||||
# 处理集团排片指导 |
||||
movie_guidance = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Guide')).first().prompt_val # 获取提示词模板 |
||||
guidance = get_movie_guidance(self.cinema, self.show_date) |
||||
movie_guidance = movie_guidance.replace('{movie_guidance}', guidance) |
||||
prompt_list.append(movie_guidance) |
||||
|
||||
# 处理增减场次规则 |
||||
add_reduce = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='AddReduce')).first().prompt_val # 获取提示词模板 |
||||
add_reduce_obj = json.loads(add_reduce) |
||||
rule = add_reduce_rule(template_date_is_holiday, target_date_is_holiday) |
||||
add_reduce_str = f"{add_reduce_obj['title']}\n{add_reduce_obj[rule]}\n\n" |
||||
prompt_list.append(add_reduce_str) |
||||
|
||||
# 处理黄金时段 |
||||
prime_time = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='PrimeTime')).first().prompt_val # 获取提示词模板 |
||||
prompt_list.append(prime_time) |
||||
|
||||
# # 处理暑期档 |
||||
# summer = PromptTemplate.objects.filter( |
||||
# Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Summer')).first().prompt_val # 获取提示词模板 |
||||
# prompt_list.append(summer) |
||||
|
||||
# 处理输出目标 |
||||
output = PromptTemplate.objects.filter( |
||||
Q(del_flag=False) & Q(prompt_type='show') & Q(prompt_key='Output')).first().prompt_val # 获取提示词模板 |
||||
prompt_list.append(output) |
||||
|
||||
# 打印提示词 |
||||
self.prompt = '\n'.join(prompt_list) |
||||
print('开始打印提示词\n', self.prompt) |
||||
# 关闭数据库连接 |
||||
data.exit() |
||||
return self.prompt |
||||
|
||||
# 请求AI |
||||
def get_show_result_ai(self, prompt=None): |
||||
# 生成提示词 |
||||
# self.general_prompt() |
||||
# 与AI开始对话 |
||||
print(f"与{self.ai_model_name}开始对话") |
||||
ts = str(int(datetime.datetime.timestamp(datetime.datetime.now()))) |
||||
user_id = f"{self.cinema.zz_code}-{ts}" if get_runtime_val('deepseek_cache') == 0 else self.cinema.zz_code |
||||
response = self.client.chat.completions.create( |
||||
model=self.ai_model_name, |
||||
messages=[ |
||||
{'role': 'system', |
||||
'content': '你是中文AI助手。要求:1.所有思考过程必须使用中文。2.所有tool reasoning必须使用中文。3.所有规划必须使用中文。4.即使用户使用英文提问,也必须中文推理。5.最终输出使用中文。'}, |
||||
{'role': 'user', 'content': self.prompt if prompt is None else prompt}, |
||||
], |
||||
stream=False, |
||||
reasoning_effort="high", |
||||
extra_body={"thinking": {"type": "enabled"}, |
||||
"user_id": user_id}, |
||||
response_format={ |
||||
'type': 'json_object' |
||||
} |
||||
) |
||||
res_json = response.model_dump_json() |
||||
res_obj = json.loads(res_json) |
||||
print(res_obj) |
||||
return res_obj['choices'][0]['message']['content'], res_json, response.usage.model_dump_json() |
||||
@ -1,324 +0,0 @@ |
||||
# 排片数据 |
||||
GET_SHOW_DATA = """ |
||||
SELECT hi.cinema_hall_name as hall_name, |
||||
hi.cinema_hall_id as hall_id, |
||||
mi.cinema_movie_alias as movie_name, |
||||
mi.cinema_movie_id as movie_id, |
||||
mlt.cinema_movie_lang_type_desc as language, |
||||
DATE_FORMAT(ms.cinema_movie_show_start_time, '%%Y-%%m-%%d') as show_date, |
||||
DATE_FORMAT(ms.cinema_movie_show_start_time, '%%H:%%i') as start_time, |
||||
DATE_FORMAT(ms.cinema_movie_show_end_time, '%%H:%%i') as end_time, |
||||
CAST(TIME_TO_SEC(TIMEDIFF(ms.cinema_movie_show_end_time, ms.cinema_movie_show_start_time)) / |
||||
60 AS UNSIGNED) as length, |
||||
IFNULL(MINUTE(TIMEDIFF(ms.cinema_movie_show_start_time, (SELECT MAX(cinema_movie_show_end_time) |
||||
FROM cinema_movie_show t |
||||
WHERE t.cinema_hall_id = ms.cinema_hall_id |
||||
AND t.cinema_movie_show_start_date = ms.cinema_movie_show_start_date |
||||
AND t.cinema_del_flag = 1 |
||||
AND ms.cinema_movie_show_start_time >= t.cinema_movie_show_end_time))), |
||||
0) as duration |
||||
FROM cinema_movie_show ms |
||||
LEFT JOIN cinema_hall_info hi ON ms.cinema_hall_id = hi.cinema_hall_id |
||||
LEFT JOIN cinema_movie_info mi ON ms.cinema_movie_id = mi.cinema_movie_id |
||||
LEFT JOIN cinema_movie_lang_type mlt ON mi.cinema_movie_lang_id = mlt.cinema_movie_lang_type_id |
||||
WHERE ms.cinema_del_flag = 1 |
||||
AND ms.cinema_movie_show_start_time >= %s |
||||
AND ms.cinema_movie_show_start_time <= %s |
||||
ORDER BY show_date, hall_id, start_time; |
||||
""" |
||||
|
||||
# 获取销售数据 |
||||
GET_SELL_DATA = """ |
||||
SELECT md.movie_name, |
||||
md.movie_id, |
||||
md.show_date, |
||||
md.start_time, |
||||
md.hall_name, |
||||
md.hall_id, |
||||
SUM(md.count) as total_count, |
||||
SUM(md.income) as total_income, |
||||
md.seat_num, |
||||
ROUND(IF(SUM(md.income) = 0, 0.0, SUM(md.income) / SUM(md.count)), 2) as average_price, |
||||
ROUND(SUM(md.count) / md.seat_num * 100, 2) as rate |
||||
FROM ( |
||||
-- 售票 |
||||
SELECT ms.cinema_movie_show_id as cinema_movie_show_id, |
||||
mi.cinema_movie_alias as movie_name, |
||||
mi.cinema_movie_id as movie_id, |
||||
DATE_FORMAT(ms.cinema_movie_show_start_time, '%%Y-%%m-%%d') as show_date, |
||||
CAST(TIME(ms.cinema_movie_show_start_time) AS CHAR) as start_time, |
||||
hi.cinema_hall_name as hall_name, |
||||
hi.cinema_hall_id as hall_id, |
||||
SUM(IF(sl.cinema_ticket_status <> 3, 1, 0)) as count, |
||||
SUM(IF(sl.cinema_ticket_status <> 3, sl.cinema_ticket_income, 0)) as income, |
||||
ms.cinema_hall_seat_num as seat_num |
||||
FROM cinema_movie_show ms |
||||
LEFT JOIN cinema_sell_log sl ON ms.cinema_movie_show_id = sl.cinema_movie_show_id |
||||
JOIN cinema_movie_info mi ON ms.cinema_movie_id = mi.cinema_movie_id |
||||
JOIN cinema_hall_info hi ON ms.cinema_hall_id = hi.cinema_hall_id |
||||
WHERE ms.cinema_movie_show_joinflg = 0 |
||||
AND ms.cinema_movie_show_start_time >= %s |
||||
AND ms.cinema_movie_show_start_time <= %s |
||||
AND ms.cinema_del_flag = 1 |
||||
AND NOT (ms.cinema_movie_show_sold_num = 0 AND ms.cinema_movie_show_status <> 1) |
||||
GROUP BY ms.cinema_movie_show_id, CAST(ms.cinema_movie_show_id AS CHAR) |
||||
UNION |
||||
-- 补登 |
||||
SELECT ms.cinema_movie_show_id as cinema_movie_show_id, |
||||
mi.cinema_movie_alias as movie_name, |
||||
mi.cinema_movie_id as movie_id, |
||||
DATE_FORMAT(ms.cinema_movie_show_start_time, '%%Y-%%m-%%d') as show_date, |
||||
CAST(TIME(ms.cinema_movie_show_start_time) AS CHAR) as start_time, |
||||
hi.cinema_hall_name as hall_name, |
||||
hi.cinema_hall_id as hall_id, |
||||
SUM(sa.cinema_sell_add_num) as count, |
||||
SUM(sa.cinema_sell_add_total) as income, |
||||
ms.cinema_hall_seat_num as seat_num |
||||
FROM cinema_sell_add sa |
||||
LEFT JOIN cinema_movie_show ms ON sa.cinema_sell_add_showid = ms.cinema_movie_show_id |
||||
LEFT JOIN cinema_hall_info hall ON ms.cinema_hall_id = hall.cinema_hall_id |
||||
LEFT JOIN cinema_show_policy_map spm ON sa.cinema_sell_add_showid = spm.cinema_movie_show_id AND |
||||
sa.cinema_sell_add_policy = spm.cinema_show_policy_map_id |
||||
JOIN cinema_hall_info hi ON ms.cinema_hall_id = hi.cinema_hall_id |
||||
JOIN cinema_movie_info mi ON ms.cinema_movie_id = mi.cinema_movie_id |
||||
WHERE ms.cinema_movie_show_joinflg = 0 |
||||
AND ms.cinema_movie_show_start_time >= %s |
||||
AND ms.cinema_movie_show_start_time <= %s |
||||
AND ms.cinema_del_flag = 1 |
||||
AND NOT (ms.cinema_movie_show_sold_num = 0 AND ms.cinema_movie_show_status <> 1) |
||||
GROUP BY ms.cinema_movie_show_id, CAST(ms.cinema_movie_show_id AS CHAR)) as md |
||||
GROUP BY md.cinema_movie_show_id, CAST(md.cinema_movie_show_id AS CHAR) |
||||
ORDER BY md.show_date, md.hall_id, md.start_time; |
||||
""" |
||||
|
||||
GET_SELL_DATA_BY_MOVIE = """ |
||||
SELECT sd.movie_alias_name movie_alias_name, |
||||
sd.movie_id movie_id, |
||||
SUM(sd.total_count) total_count, |
||||
ROUND(IF(SUM(sd.total_count) = 0, 0.0, SUM(sd.total_count) / COUNT(sd.cinema_movie_show_id)), |
||||
2) average_show_count, |
||||
ROUND(IF(SUM(sd.total_count) = 0, 0.0, SUM(sd.total_count) / SUM(sd.total_seat)) * 100, |
||||
2) average_seat_rate, |
||||
SUM(sd.total_income) total_income, |
||||
ROUND(IF(SUM(sd.total_income) = 0, 0.0, SUM(sd.total_income) / SUM(sd.total_count)), |
||||
2) average_ticket_price, |
||||
ROUND(IF(SUM(sd.total_income) = 0, 0.0, SUM(sd.total_income) / COUNT(sd.cinema_movie_show_id)), |
||||
2) average_show_ticket_price, |
||||
COUNT(sd.cinema_movie_show_id) show_count, |
||||
ROUND(IF(COUNT(sd.cinema_movie_show_id) = 0, 0.0, |
||||
COUNT(sd.cinema_movie_show_id) / (SELECT COUNT(ms.cinema_movie_show_id) |
||||
FROM cinema_movie_show ms |
||||
WHERE ms.cinema_movie_show_joinflg = 0 |
||||
AND ms.cinema_movie_show_start_time >= % s |
||||
AND ms.cinema_movie_show_start_time <= % s |
||||
AND ms.cinema_del_flag = 1 |
||||
AND NOT (ms.cinema_movie_show_sold_num = 0 AND ms.cinema_movie_show_status <> 1))) * |
||||
100, |
||||
2) show_rate |
||||
FROM (SELECT CAST(ms.cinema_movie_show_id AS CHAR) cinema_movie_show_id, |
||||
mi.cinema_movie_id movie_id, |
||||
mi.cinema_movie_cn_name cinema_movie_name, |
||||
mi.cinema_movie_alias movie_alias_name, |
||||
SUM(IF(sl.cinema_ticket_status <> 3, 1, 0)) total_count, |
||||
SUM(IF(sl.cinema_ticket_status <> 3, sl.cinema_ticket_income, 0)) total_income, |
||||
ms.cinema_hall_seat_num total_seat |
||||
FROM cinema_movie_show ms |
||||
LEFT JOIN cinema_sell_log sl ON ms.cinema_movie_show_id = sl.cinema_movie_show_id |
||||
JOIN cinema_movie_info mi ON ms.cinema_movie_id = mi.cinema_movie_id |
||||
JOIN cinema_hall_info hi ON ms.cinema_hall_id = hi.cinema_hall_id |
||||
WHERE ms.cinema_movie_show_joinflg = 0 |
||||
AND ms.cinema_movie_show_start_time >= % s |
||||
AND ms.cinema_movie_show_start_time <= % s |
||||
AND ms.cinema_del_flag = 1 |
||||
AND NOT (ms.cinema_movie_show_sold_num = 0 AND ms.cinema_movie_show_status <> 1) |
||||
GROUP BY ms.cinema_movie_show_id, CAST(ms.cinema_movie_show_id AS CHAR)) sd |
||||
GROUP BY sd.movie_id ORDER BY average_show_ticket_price DESC; |
||||
""" |
||||
|
||||
GET_SELL_DATA_SELF_CALCULATE = """ |
||||
SELECT sd.movie_alias_name movie_alias_name, |
||||
sd.movie_id movie_id, |
||||
SUM(sd.total_viewers) total_viewers, |
||||
SUM(sd.total_income) total_income, |
||||
COUNT(sd.cinema_movie_show_id) total_show |
||||
FROM (SELECT CAST(ms.cinema_movie_show_id AS CHAR) cinema_movie_show_id, |
||||
mi.cinema_movie_alias movie_alias_name, |
||||
mi.cinema_movie_id movie_id, |
||||
SUM(IF(sl.cinema_ticket_status <> 3, 1, 0)) total_viewers, |
||||
SUM(IF(sl.cinema_ticket_status <> 3, sl.cinema_ticket_income, 0)) total_income |
||||
FROM cinema_movie_show ms |
||||
LEFT JOIN cinema_sell_log sl ON ms.cinema_movie_show_id = sl.cinema_movie_show_id |
||||
JOIN cinema_movie_info mi ON ms.cinema_movie_id = mi.cinema_movie_id |
||||
WHERE ms.cinema_movie_show_joinflg = 0 |
||||
AND ms.cinema_movie_show_start_time >= %s |
||||
AND ms.cinema_movie_show_start_time < %s |
||||
AND ms.cinema_del_flag = 1 |
||||
AND NOT (ms.cinema_movie_show_sold_num = 0 AND ms.cinema_movie_show_status <> 1) |
||||
GROUP BY ms.cinema_movie_show_id) sd |
||||
GROUP BY sd.movie_id ORDER BY sd.total_income DESC; |
||||
""" |
||||
|
||||
|
||||
# 获取指定日期的可放映影片 |
||||
GET_AVAILABLE_MOVIE = """ |
||||
SELECT cmi.cinema_movie_alias, |
||||
cmi.cinema_movie_id, |
||||
cmi.cinema_movie_time, |
||||
cmlt.cinema_movie_lang_type_desc as language, |
||||
scvm.system_const_val_desc as media_type, |
||||
cmi.cinema_movie_start_datetime, |
||||
cmi.cinema_movie_end_datetime |
||||
FROM cinema_movie_info cmi |
||||
JOIN cinema_movie_lang_type cmlt ON cmi.cinema_movie_lang_id = cmlt.cinema_movie_lang_type_id |
||||
JOIN system_const_val_map scvm ON cmi.cinema_movie_media_type = scvm.system_const_val_value |
||||
WHERE scvm.system_const_sub_module = 'new_media_type' |
||||
AND cmi.cinema_movie_start_datetime <= %s |
||||
AND cmi.cinema_movie_end_datetime > %s; |
||||
""" |
||||
|
||||
# 获取指定日期的可用于排片的影片 |
||||
GET_HANDLE_MOVIE = f""" |
||||
SELECT cmi.cinema_movie_alias, |
||||
cmi.cinema_movie_num, |
||||
cmi.cinema_movie_id, |
||||
cmi.cinema_movie_time, |
||||
cmlt.cinema_movie_lang_type_desc as language, |
||||
scvm.system_const_val_desc as media_type, |
||||
cmi.cinema_movie_start_datetime, |
||||
cmi.cinema_movie_end_datetime |
||||
FROM cinema_movie_info cmi |
||||
JOIN cinema_movie_lang_type cmlt ON cmi.cinema_movie_lang_id = cmlt.cinema_movie_lang_type_id |
||||
JOIN system_const_val_map scvm ON cmi.cinema_movie_media_type = scvm.system_const_val_value |
||||
WHERE scvm.system_const_sub_module = 'new_media_type' |
||||
AND cmi.cinema_movie_start_datetime <= %s |
||||
AND cmi.cinema_movie_end_datetime > %s |
||||
AND cmi.cinema_movie_num NOT IN ( |
||||
""" |
||||
|
||||
|
||||
GET_HANDLE_MOVIE_TEST = """ |
||||
SELECT cmi.cinema_movie_alias, |
||||
cmi.cinema_movie_num, |
||||
cmi.cinema_movie_id, |
||||
cmi.cinema_movie_time, |
||||
cmlt.cinema_movie_lang_type_desc as language, |
||||
scvm.system_const_val_desc as media_type, |
||||
cmi.cinema_movie_start_datetime, |
||||
cmi.cinema_movie_end_datetime |
||||
FROM cinema_movie_info cmi |
||||
JOIN cinema_movie_lang_type cmlt ON cmi.cinema_movie_lang_id = cmlt.cinema_movie_lang_type_id |
||||
JOIN system_const_val_map scvm ON cmi.cinema_movie_media_type = scvm.system_const_val_value |
||||
WHERE scvm.system_const_sub_module = 'new_media_type' |
||||
AND cmi.cinema_movie_id IN (SELECT ms.cinema_movie_id |
||||
FROM cinema_movie_show ms |
||||
WHERE ms.cinema_del_flag = 1 |
||||
AND ms.cinema_movie_show_start_time >= %s |
||||
AND ms.cinema_movie_show_start_time <= %s |
||||
GROUP BY ms.cinema_movie_num) |
||||
AND cmi.cinema_movie_end_datetime > %s |
||||
AND cmi.cinema_movie_num NOT IN ( |
||||
""" |
||||
|
||||
# 获取新上映的影片 |
||||
GET_NEW_MOVIE = """SELECT cmi.cinema_movie_alias, |
||||
cmi.cinema_movie_id, |
||||
cmi.cinema_movie_time, |
||||
cmlt.cinema_movie_lang_type_desc as language, |
||||
scvm.system_const_val_desc as media_type, |
||||
cmi.cinema_movie_start_datetime, |
||||
cmi.cinema_movie_end_datetime |
||||
FROM cinema_movie_info cmi |
||||
JOIN cinema_movie_lang_type cmlt ON cmi.cinema_movie_lang_id = cmlt.cinema_movie_lang_type_id |
||||
JOIN system_const_val_map scvm ON cmi.cinema_movie_media_type = scvm.system_const_val_value |
||||
WHERE scvm.system_const_sub_module = 'new_media_type' |
||||
AND cmi.cinema_movie_start_datetime >= %s |
||||
AND cmi.cinema_movie_start_datetime <= %s;""" |
||||
|
||||
# 获取影厅支持的制式 |
||||
GET_HALL_MEDIA_TYPE = """ |
||||
SELECT chi.cinema_hall_name, cms.cinema_hall_id, scvm.system_const_val_desc as media_type |
||||
FROM cinema_movie_show cms |
||||
JOIN cinema_movie_info cmi ON cms.cinema_movie_id = cmi.cinema_movie_id |
||||
JOIN cinema_hall_info chi ON cms.cinema_hall_id = chi.cinema_hall_id |
||||
JOIN system_const_val_map scvm ON cmi.cinema_movie_media_type = scvm.system_const_val_value |
||||
WHERE scvm.system_const_sub_module = 'new_media_type' |
||||
AND chi.cinema_delete_flag = 0 |
||||
GROUP BY chi.cinema_hall_id, media_type; |
||||
""" |
||||
|
||||
# 获取模板日期 |
||||
GET_TEMPLATE_DATE = """ |
||||
SELECT cms.cinema_movie_show_start_date as template_date, COUNT(cinema_movie_show_id) as show_count |
||||
FROM cinema_movie_show cms |
||||
WHERE cms.cinema_del_flag = 1 |
||||
AND cms.cinema_movie_show_start_time >= %s |
||||
AND cms.cinema_movie_show_start_time <= %s |
||||
GROUP BY cms.cinema_movie_show_start_date |
||||
HAVING show_count > (SELECT COUNT(chi.cinema_hall_id) FROM cinema_hall_info chi WHERE chi.cinema_delete_flag = 0) * %s |
||||
ORDER BY template_date DESC |
||||
LIMIT 1; |
||||
""" |
||||
|
||||
|
||||
# 获取目标日期的销售总额 |
||||
GET_TOTAL_INCOME = """ |
||||
SELECT SUM(md.income) as total_income |
||||
FROM ( |
||||
-- 售票 |
||||
SELECT SUM(IF(sl.cinema_ticket_status <> 3, sl.cinema_ticket_income, 0)) as income |
||||
FROM cinema_movie_show ms |
||||
LEFT JOIN cinema_sell_log sl ON ms.cinema_movie_show_id = sl.cinema_movie_show_id |
||||
JOIN cinema_movie_info mi ON ms.cinema_movie_id = mi.cinema_movie_id |
||||
JOIN cinema_hall_info hi ON ms.cinema_hall_id = hi.cinema_hall_id |
||||
WHERE ms.cinema_movie_show_joinflg = 0 |
||||
AND ms.cinema_movie_show_start_time >= %s |
||||
AND ms.cinema_movie_show_start_time <= %s |
||||
AND ms.cinema_del_flag = 1 |
||||
AND NOT (ms.cinema_movie_show_sold_num = 0 AND ms.cinema_movie_show_status <> 1) |
||||
UNION |
||||
-- 补登 |
||||
SELECT SUM(sa.cinema_sell_add_total) as income |
||||
FROM cinema_sell_add sa |
||||
LEFT JOIN cinema_movie_show ms ON sa.cinema_sell_add_showid = ms.cinema_movie_show_id |
||||
LEFT JOIN cinema_hall_info hall ON ms.cinema_hall_id = hall.cinema_hall_id |
||||
LEFT JOIN cinema_show_policy_map spm ON sa.cinema_sell_add_showid = spm.cinema_movie_show_id AND |
||||
sa.cinema_sell_add_policy = spm.cinema_show_policy_map_id |
||||
JOIN cinema_hall_info hi ON ms.cinema_hall_id = hi.cinema_hall_id |
||||
JOIN cinema_movie_info mi ON ms.cinema_movie_id = mi.cinema_movie_id |
||||
WHERE ms.cinema_movie_show_joinflg = 0 |
||||
AND ms.cinema_movie_show_start_time >= %s |
||||
AND ms.cinema_movie_show_start_time <= %s |
||||
AND ms.cinema_del_flag = 1 |
||||
AND NOT (ms.cinema_movie_show_sold_num = 0 AND ms.cinema_movie_show_status <> 1)) md |
||||
""" |
||||
|
||||
|
||||
# 获取指定日期的可用于排片的影片 |
||||
GET_MOVIE_INFO = """ |
||||
SELECT cmi.cinema_movie_cn_name, |
||||
cmi.cinema_movie_num |
||||
FROM cinema_movie_info cmi |
||||
WHERE cmi.cinema_movie_start_datetime <= %s |
||||
AND cmi.cinema_movie_end_datetime > %s |
||||
AND cmi.cinema_movie_num NOT IN (""" |
||||
|
||||
GET_MOVIE_INFO_END = """) |
||||
GROUP BY cmi.cinema_movie_num; |
||||
""" |
||||
|
||||
# 获取指定日期的可用于排片的影片 |
||||
GET_NEW_MOVIE_INFO = """ |
||||
SELECT cmi.cinema_movie_cn_name, |
||||
cmi.cinema_movie_num |
||||
FROM cinema_movie_info cmi |
||||
WHERE cmi.cinema_movie_start_datetime <= %s |
||||
AND cmi.cinema_movie_start_datetime > %s |
||||
AND cmi.cinema_movie_num NOT IN (""" |
||||
|
||||
GET_OLD_MOVIE_INFO = """ |
||||
SELECT cmi.cinema_movie_cn_name, |
||||
cmi.cinema_movie_num |
||||
FROM cinema_movie_info cmi |
||||
WHERE cmi.cinema_movie_start_datetime <= %s |
||||
AND cmi.cinema_movie_end_datetime > %s |
||||
AND cmi.cinema_movie_num NOT IN (""" |
||||
@ -1,223 +0,0 @@ |
||||
from anyio import sleep |
||||
from django.http import JsonResponse |
||||
from django.utils.timezone import make_aware, utc |
||||
from django.db.models import Q |
||||
from django.views.decorators.csrf import csrf_exempt |
||||
import json |
||||
from ai.models import * |
||||
import time |
||||
from ai.utils.show_process import show_main_process, show_manual_process, get_prompt_process |
||||
from ai.utils.show_func import * |
||||
from ai.utils.basic_func import * |
||||
|
||||
|
||||
# 手动触发ai排片 |
||||
@csrf_exempt |
||||
def manual_general_show(request): |
||||
zz_code = request.GET.dict().get('cinema_code') |
||||
delta = request.GET.dict().get('delta') |
||||
result = show_main_process(zz_code, delta) |
||||
result_dict = { |
||||
'status': 'success' if result else 'fail', |
||||
'message': '生成成功' if result else '生成失败', |
||||
} |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
# 更新指定日期的排片 |
||||
@csrf_exempt |
||||
def get_cinema_show_result(request): |
||||
zz_code = request.GET.dict().get('cinema_code') |
||||
show_date = request.GET.dict().get('show_date') |
||||
print(zz_code, show_date) |
||||
show, income = get_cinema_show_result_func(zz_code, show_date) |
||||
result_dict = { |
||||
'status': 'success', |
||||
'message': '生成成功', |
||||
'show': show, |
||||
'income': income, |
||||
} |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
# 清除redis锁 |
||||
@csrf_exempt |
||||
def clear_lock(request): |
||||
clear_lock_func() |
||||
result_dict = { |
||||
'status': 'success', |
||||
'message': '完成', |
||||
} |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
@csrf_exempt |
||||
def report(request): |
||||
zz_code = request.GET.dict().get('cinema_code') |
||||
show_date = request.GET.dict().get('show_date') |
||||
force = request.GET.dict().get('force') |
||||
test = request.GET.dict().get('test', None) |
||||
print('report-request_params', zz_code, show_date, force, test) |
||||
# cinema = TestCinema.objects.filter(zz_code=zz_code).first() |
||||
# 获取真实排片和销售数据 |
||||
check_point = datetime.datetime.strftime( |
||||
datetime.datetime.strptime(show_date, '%Y-%m-%d') + datetime.timedelta(hours=30), '%Y-%m-%d %H:%M:%S') |
||||
last_real_data = AiShow.objects.filter(Q(is_ai_show=False) & |
||||
Q(zz_code=zz_code) & |
||||
Q(show_date=show_date) & |
||||
Q(updated_at__gt=check_point)).order_by('-id').first() |
||||
if (not last_real_data) or (force == '1'): |
||||
get_cinema_show_result_func(zz_code, show_date) |
||||
|
||||
if test is None or test == '': |
||||
last_ai_data = AiShow.objects.filter(Q(is_ai_show=True) & |
||||
Q(zz_code=zz_code) & |
||||
Q(show_date=show_date)).order_by('-id').first() |
||||
else: |
||||
print('test', test) |
||||
last_ai_data = AiShow.objects.filter(Q(is_ai_show=True) & |
||||
Q(zz_code=zz_code) & |
||||
Q(show_date=show_date) & |
||||
Q(create_datetime=test)).first() |
||||
if not last_ai_data: |
||||
result_dict = { |
||||
'status': 'Failure', |
||||
'message': '没有查询到有效的智能排片数据,请调整日期和影院后再试!'} |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
last_real_data = AiShow.objects.filter(Q(is_ai_show=False) & |
||||
Q(zz_code=zz_code) & |
||||
Q(show_date=show_date)).order_by('-id').first() |
||||
ai_dict = csv_to_obj(data_cleansing(last_ai_data.show)) |
||||
real_dict = csv_to_obj(last_real_data.show) |
||||
temp_dict = csv_to_obj(last_ai_data.template) |
||||
target_dict = csv_to_obj(last_ai_data.target) |
||||
print(ai_dict, real_dict, temp_dict, target_dict) |
||||
output_list_ai_real, output_csv_ai_real = format_show_data(zz_code, show_date, ai_dict, real_dict) |
||||
output_list_ai_temp, output_csv_ai_temp = format_show_data(zz_code, show_date, ai_dict, temp_dict) |
||||
output_list_ai_target, output_cdv_ai_target = format_show_data(zz_code, show_date, ai_dict, target_dict) |
||||
# 获取影厅制式 |
||||
hall_type = get_hall_type(cinema_code=zz_code) |
||||
# 计算排片占比 |
||||
ai_count, ai_total = count_show(ai_dict) |
||||
real_count, real_total = count_show(real_dict) |
||||
target_count, target_total = count_show(target_dict) |
||||
template_count, template_total = count_show(temp_dict) |
||||
|
||||
if last_ai_data.ai_model in ['lmstudio_qwen3.6_35b', 'company_qwen3.5_35b']: |
||||
think = json.loads(last_ai_data.message)['choices'][0]['message']['reasoning'] |
||||
else: |
||||
think = json.loads(last_ai_data.message)['choices'][0]['message']['reasoning_content'] |
||||
# 返回 |
||||
result_dict = { |
||||
'status': 'success', |
||||
'message': '成功', |
||||
'data': { |
||||
'cinema_name': last_ai_data.cinema, |
||||
'zz_code': last_ai_data.zz_code, |
||||
'hall_type': hall_type, |
||||
'real_sales': last_real_data.sales, |
||||
'ai_sales': last_ai_data.sales, |
||||
'take_times': last_ai_data.take_times, |
||||
'take_tokens': json.loads(last_ai_data.take_tokens)['total_tokens'], |
||||
'csv': list_to_csv(output_csv_ai_real), |
||||
'real_obj': output_list_ai_real, |
||||
'template_obj': output_list_ai_temp, |
||||
'template_date': last_ai_data.temp_date, |
||||
'target_obj': output_list_ai_target, |
||||
'prompt': last_ai_data.prompt, |
||||
'ai_count': ai_count, |
||||
'real_count': real_count, |
||||
'target_count': target_count, |
||||
'template_count': template_count, |
||||
'ai_total': ai_total, |
||||
'real_total': real_total, |
||||
'target_total': target_total, |
||||
'template_total': template_total, |
||||
'result': last_ai_data.result, |
||||
'is_manual_test': last_ai_data.is_manual_test, |
||||
'prompt_version': last_ai_data.prompt_version, |
||||
'think': think, |
||||
'ai_model': last_ai_data.ai_model, |
||||
'create_time': last_ai_data.create_datetime |
||||
} |
||||
} |
||||
print(result_dict) |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
# 获取已经生成排片的日期范围 |
||||
@csrf_exempt |
||||
def get_report_date_api(request): |
||||
start, end = get_report_date() |
||||
result_dict = { |
||||
'status': 'success', |
||||
'message': '成功', |
||||
'start': start, |
||||
'end': end |
||||
} |
||||
print(result_dict) |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
@csrf_exempt |
||||
def insert_new_movie(request): |
||||
start = request.GET.get('start') |
||||
result = get_new_movie(start) |
||||
if result is None: |
||||
data = 'None' |
||||
elif result is False: |
||||
data = '参数start格式错误,示例2026-07-11' |
||||
else: |
||||
data = result |
||||
result_dict = { |
||||
'status': 'success', |
||||
'message': '成功', |
||||
'data': data |
||||
} |
||||
print(result_dict) |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
@csrf_exempt |
||||
def manual_test(request): |
||||
print('manual_test-reuest', json.loads(request.body)) |
||||
body = json.loads(request.body) |
||||
cinema_code = body.get('cinema_code') |
||||
show_date = body.get('show_date') |
||||
prompt = body.get('prompt') |
||||
print('manual_test-request-params', cinema_code, show_date, prompt) |
||||
result = show_manual_process(cinema_code, show_date, prompt) |
||||
result_dict = { |
||||
'status': 'success', |
||||
'message': '成功', |
||||
'data': result |
||||
} |
||||
print(result_dict) |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
@csrf_exempt |
||||
def get_test_date(request): |
||||
cinema_code = request.GET.get('cinema_code') |
||||
show_date = request.GET.get('show_date') |
||||
result_dict = { |
||||
'status': 'success', |
||||
'message': '成功', |
||||
'date': get_test_date_from_db(cinema_code, show_date) |
||||
} |
||||
print(result_dict) |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
# 获取指定日和和影院的提示词用于手动验证 |
||||
@csrf_exempt |
||||
def get_prompt(request): |
||||
cinema_code = request.GET.get('cinema_code') |
||||
show_date = request.GET.get('show_date') |
||||
result_dict = { |
||||
'status': 'success', |
||||
'message': '成功', |
||||
'data': get_prompt_process(cinema_code, show_date) |
||||
} |
||||
print(result_dict) |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
@ -1,5 +0,0 @@ |
||||
py .\manage.py runserver 0.0.0.0:8000 |
||||
python manage.py runserver --skip-checks 0.0.0.0:8000 |
||||
celery -A dingxin_toolbox_drf worker -l info -P solo # windows |
||||
celery -A dingxin_toolbox_drf worker -l info # linux |
||||
celery -A dingxin_toolbox_drf beat -l info |
||||
@ -1,3 +0,0 @@ |
||||
from django.contrib import admin |
||||
|
||||
# Register your models here. |
||||
@ -1,6 +0,0 @@ |
||||
from django.apps import AppConfig |
||||
|
||||
|
||||
class ConfigConfig(AppConfig): |
||||
default_auto_field = 'django.db.models.BigAutoField' |
||||
name = 'config' |
||||
@ -1,3 +0,0 @@ |
||||
from django.db import models |
||||
|
||||
# Create your models here. |
||||
@ -1,3 +0,0 @@ |
||||
from django.test import TestCase |
||||
|
||||
# Create your tests here. |
||||
@ -1,24 +0,0 @@ |
||||
""" |
||||
URL configuration for dingxin_toolbox_drf project. |
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see: |
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/ |
||||
Examples: |
||||
Function views |
||||
1. Add an import: from my_app import views |
||||
2. Add a URL to urlpatterns: path('', views.home, name='home') |
||||
Class-based views |
||||
1. Add an import: from other_app.views import Home |
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') |
||||
Including another URLconf |
||||
1. Import the include() function: from django.urls import include, path |
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) |
||||
""" |
||||
from django.contrib import admin |
||||
from django.urls import path, include |
||||
from config.views import * |
||||
|
||||
urlpatterns = [ |
||||
path('zy_switch_svip', zy_switch_svip), |
||||
path('zy_clear_cache', zy_clear_cache) |
||||
] |
||||
@ -1,94 +0,0 @@ |
||||
from django.http import JsonResponse |
||||
from django.shortcuts import render |
||||
from django.views.decorators.csrf import csrf_exempt |
||||
import pymysql |
||||
from pymysql.cursors import DictCursor |
||||
import redis |
||||
|
||||
zy_db_config = { |
||||
'host': '10.10.0.116', |
||||
'port': 3306, |
||||
'user': 'zyds_select', |
||||
'password': 'select', |
||||
'db': 'suyi_cinema', |
||||
} |
||||
|
||||
zy_redis_config = { |
||||
'host': '10.10.0.116', |
||||
'port': 6379, |
||||
'db': 0, |
||||
'decode_responses': True |
||||
} |
||||
|
||||
|
||||
@csrf_exempt |
||||
def zy_switch_svip(request): |
||||
""" |
||||
接口用于切换自营环境 |
||||
http://172.16.1.168:8000/config/zy_switch_svip?svip=on |
||||
""" |
||||
# 切换自营环境 |
||||
svip = request.GET.get('svip') |
||||
if svip == 'on': |
||||
result = zy_switch_svip_db('svip') |
||||
elif svip == 'off': |
||||
result = zy_switch_svip_db('normal') |
||||
else: |
||||
result = False |
||||
|
||||
# 清除缓存 |
||||
clear_result = False |
||||
if result: |
||||
clear_result = zy_clear_cache_redis() |
||||
|
||||
result_dict = { |
||||
'status': 'success' if clear_result else 'error', |
||||
'message': ('切换环境成功,' if result else '切换环境失败,') + ('清除缓存成功' if clear_result else '清除缓存失败'), |
||||
} |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
@csrf_exempt |
||||
def zy_clear_cache(request): |
||||
""" |
||||
接口用于清除自营缓存 |
||||
http://172.16.1.168:8000/config/zy_clear_cache |
||||
""" |
||||
result = zy_clear_cache_redis() |
||||
result_dict = { |
||||
'status': 'success' if result else 'error', |
||||
'message': '清除缓存成功' if result else '清除缓存失败', |
||||
} |
||||
return JsonResponse(result_dict, json_dumps_params={'ensure_ascii': False}) |
||||
|
||||
|
||||
def zy_switch_svip_db(env_type): |
||||
db_conn = pymysql.Connect(**zy_db_config) |
||||
cursor = db_conn.cursor(cursor=DictCursor) |
||||
|
||||
select_sql = "SELECT value FROM suyi_cinema.group_kv_config gkc WHERE gkc.key = 'svip_switch';" |
||||
cursor.execute(select_sql) |
||||
query_result = cursor.fetchone() |
||||
|
||||
# 若果当前值与要修改的值一至直接返回True |
||||
if (query_result['value'] == '1' and env_type == 'svip') or (query_result['value'] == '0' and env_type != 'svip'): |
||||
return True |
||||
|
||||
# value 0-非华谊 1-华谊 |
||||
sql_str = "UPDATE suyi_cinema.group_kv_config gkc SET gkc.value = %s WHERE gkc.key = 'svip_switch';" |
||||
|
||||
if env_type == 'svip': |
||||
r = cursor.execute(sql_str, ('1',)) |
||||
else: |
||||
r = cursor.execute(sql_str, ('0',)) |
||||
db_conn.commit() |
||||
db_conn.close() |
||||
return True if r == 1 else False |
||||
|
||||
|
||||
def zy_clear_cache_redis(): |
||||
r = redis.Redis(**zy_redis_config) |
||||
result = r.flushdb() |
||||
print('zy_clear_cache_redis', result) |
||||
return result |
||||
# Create your views here. |
||||
@ -1,6 +0,0 @@ |
||||
import pymysql |
||||
from .celery import app as celery_app |
||||
|
||||
pymysql.install_as_MySQLdb() |
||||
|
||||
__all__ = ('celery_app',) |
||||
@ -1,27 +0,0 @@ |
||||
import os |
||||
from celery import Celery |
||||
from celery.schedules import crontab |
||||
from django.conf import settings |
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dingxin_toolbox_drf.settings') |
||||
|
||||
# 创建 Celery实例 |
||||
app = Celery('dingxin_toolbox_drf') |
||||
|
||||
# 加载配置文件中的Celery配置 |
||||
app.config_from_object('django.conf:settings', namespace='CELERY') |
||||
|
||||
# 自动发现并添加任务 |
||||
app.autodiscover_tasks() |
||||
|
||||
# 强制单实例运行 |
||||
app.conf.worker_prefetch_multiplier=1 |
||||
app.conf.task_acks_late=True |
||||
|
||||
# app.conf.beat_schedule = { |
||||
# 'update_client_task': { |
||||
# 'task': 'update.tasks.update_client', |
||||
# # 'schedule': crontab(hour='*'), |
||||
# 'schedule': 30, |
||||
# }, |
||||
# } |
||||
@ -1,23 +0,0 @@ |
||||
from django.utils.deprecation import MiddlewareMixin |
||||
|
||||
|
||||
class SetRemoteAddrFromForwardedFor(MiddlewareMixin): |
||||
""" |
||||
如果部署了代理,使用此中间件获取远程客户端IP。 |
||||
在settings中注册该中间件。 |
||||
""" |
||||
|
||||
def process_request(self, request): |
||||
# print('process_request') |
||||
# print("request.META") |
||||
# print(request.META) |
||||
try: |
||||
# print("request.META") |
||||
real_ip = request.META['HTTP_X_FORWARDED_FOR'] |
||||
# print('real_ip', real_ip) |
||||
except KeyError as err: |
||||
print('HTTP_X_FORWARDED_FOR key error') |
||||
print(err) |
||||
else: |
||||
real_ip = real_ip.split(",")[0] |
||||
request.META['REMOTE_ADDR'] = real_ip |
||||
@ -1,13 +0,0 @@ |
||||
from .wsgi import * |
||||
# from channels.auth import AuthMiddlewareStack |
||||
from channels.routing import ProtocolTypeRouter, URLRouter |
||||
from django.core.asgi import get_asgi_application |
||||
from .urls import websocket_urlpatterns |
||||
|
||||
|
||||
application = ProtocolTypeRouter( |
||||
{ |
||||
'http': get_asgi_application(), |
||||
'websocket': URLRouter(websocket_urlpatterns) |
||||
} |
||||
) |
||||
@ -1,3 +0,0 @@ |
||||
from django.contrib import admin |
||||
|
||||
# Register your models here. |
||||
@ -1,6 +0,0 @@ |
||||
from django.apps import AppConfig |
||||
|
||||
|
||||
class DsptApiConfig(AppConfig): |
||||
default_auto_field = 'django.db.models.BigAutoField' |
||||
name = 'dspt_api' |
||||
@ -1,120 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-05-23 07:57 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
initial = True |
||||
|
||||
dependencies = [ |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='CinemaIds', |
||||
fields=[ |
||||
('id', models.IntegerField(primary_key=True, serialize=False)), |
||||
('env', models.CharField(max_length=10, verbose_name='环境')), |
||||
('cinema_id', models.IntegerField(verbose_name='影院id')), |
||||
('cinema_name', models.CharField(max_length=30, verbose_name='影院名称')), |
||||
('cid', models.CharField(max_length=10, verbose_name='影院cid')), |
||||
], |
||||
options={ |
||||
'verbose_name': '影院cid', |
||||
'verbose_name_plural': '影院cid', |
||||
'db_table': 'ec_cinema_cid', |
||||
}, |
||||
), |
||||
migrations.CreateModel( |
||||
name='EcApi', |
||||
fields=[ |
||||
('id', models.IntegerField(primary_key=True, serialize=False)), |
||||
('desc', models.CharField(max_length=20, verbose_name='接口描述')), |
||||
('path', models.CharField(max_length=50, verbose_name='非会员接口地址')), |
||||
('m_path', models.CharField(max_length=50, verbose_name='会员接口地址')), |
||||
], |
||||
options={ |
||||
'verbose_name': '接口', |
||||
'verbose_name_plural': '接口', |
||||
'db_table': 'ec_api', |
||||
}, |
||||
), |
||||
migrations.CreateModel( |
||||
name='EcApiGroup', |
||||
fields=[ |
||||
('id', models.IntegerField(primary_key=True, serialize=False)), |
||||
('group_id', models.CharField(max_length=20, verbose_name='接口分组id')), |
||||
('name', models.CharField(max_length=20, verbose_name='接口分组id')), |
||||
('order', models.IntegerField(verbose_name='子接口顺序')), |
||||
('api_id', models.IntegerField(verbose_name='接口id')), |
||||
], |
||||
options={ |
||||
'verbose_name': '接口组', |
||||
'verbose_name_plural': '接口组', |
||||
'db_table': 'ec_api_group', |
||||
}, |
||||
), |
||||
migrations.CreateModel( |
||||
name='EcApiParams', |
||||
fields=[ |
||||
('id', models.IntegerField(primary_key=True, serialize=False)), |
||||
('api_id', models.IntegerField(verbose_name='接口id')), |
||||
('param', models.CharField(max_length=50, verbose_name='参数')), |
||||
('desc', models.CharField(max_length=500, verbose_name='参数描述')), |
||||
('value', models.CharField(max_length=500, verbose_name='参数值模版')), |
||||
('is_checked', models.BooleanField(default=False, verbose_name='是否默认勾选')), |
||||
('is_request', models.BooleanField(default=False, verbose_name='是否是必选项')), |
||||
], |
||||
options={ |
||||
'verbose_name': '接口参数', |
||||
'verbose_name_plural': '接口参数', |
||||
'db_table': 'ec_api_params', |
||||
}, |
||||
), |
||||
migrations.CreateModel( |
||||
name='EcChannel', |
||||
fields=[ |
||||
('id', models.IntegerField(primary_key=True, serialize=False)), |
||||
('env', models.CharField(max_length=10, verbose_name='环境')), |
||||
('name', models.CharField(max_length=20, verbose_name='渠道名称')), |
||||
('pid', models.CharField(max_length=10, verbose_name='渠道id')), |
||||
('channel_key', models.CharField(max_length=20, verbose_name='渠道key')), |
||||
], |
||||
options={ |
||||
'verbose_name': '渠道', |
||||
'verbose_name_plural': '渠道', |
||||
'db_table': 'ec_channel', |
||||
}, |
||||
), |
||||
migrations.CreateModel( |
||||
name='EcEnv', |
||||
fields=[ |
||||
('id', models.IntegerField(primary_key=True, serialize=False)), |
||||
('name', models.CharField(max_length=20, verbose_name='环境名称')), |
||||
('code', models.CharField(max_length=20, verbose_name='环境编码')), |
||||
('host', models.CharField(max_length=50, verbose_name='环境地址')), |
||||
], |
||||
options={ |
||||
'verbose_name': '环境', |
||||
'verbose_name_plural': '环境', |
||||
'db_table': 'ec_env', |
||||
}, |
||||
), |
||||
migrations.CreateModel( |
||||
name='EcRequestLog', |
||||
fields=[ |
||||
('id', models.IntegerField(primary_key=True, serialize=False)), |
||||
('ip', models.CharField(max_length=20, verbose_name='请求ip')), |
||||
('env', models.CharField(max_length=10, verbose_name='环境')), |
||||
('request', models.CharField(max_length=500, verbose_name='请求链接')), |
||||
('response', models.CharField(max_length=10000, verbose_name='返回值')), |
||||
('request_datetime', models.DateTimeField(verbose_name='请求发送时间')), |
||||
], |
||||
options={ |
||||
'verbose_name': '请求日志', |
||||
'verbose_name_plural': '请求日志', |
||||
'db_table': 'ec_request_log', |
||||
}, |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-05-23 08:02 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0001_initial'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='ecenv', |
||||
name='type', |
||||
field=models.CharField(default='', max_length=20, verbose_name='会员非会员'), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-05-23 08:34 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0002_ecenv_type'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='ecchannel', |
||||
name='type', |
||||
field=models.CharField(default='', max_length=20, verbose_name='会员非会员'), |
||||
), |
||||
] |
||||
@ -1,27 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-05-23 09:48 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0003_ecchannel_type'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.RemoveField( |
||||
model_name='ecapi', |
||||
name='m_path', |
||||
), |
||||
migrations.AddField( |
||||
model_name='ecapi', |
||||
name='type', |
||||
field=models.CharField(default='', max_length=20, verbose_name='会员非会员'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='ecapi', |
||||
name='path', |
||||
field=models.CharField(max_length=50, verbose_name='接口地址'), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-05-23 10:23 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0004_remove_ecapi_m_path_ecapi_type_alter_ecapi_path'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='ecapiparams', |
||||
name='value', |
||||
field=models.CharField(blank=True, max_length=500, null=True, verbose_name='参数值模版'), |
||||
), |
||||
] |
||||
@ -1,22 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-06-07 03:15 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0005_alter_ecapiparams_value'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.RenameModel( |
||||
old_name='CinemaIds', |
||||
new_name='EcCinemaIds', |
||||
), |
||||
migrations.AddField( |
||||
model_name='ecapigroup', |
||||
name='type', |
||||
field=models.CharField(default='', max_length=20, verbose_name='会员非会员'), |
||||
), |
||||
] |
||||
@ -1,22 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-06-07 03:18 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0006_rename_cinemaids_eccinemaids_ecapigroup_type'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.RemoveField( |
||||
model_name='ecapigroup', |
||||
name='order', |
||||
), |
||||
migrations.AlterField( |
||||
model_name='ecapigroup', |
||||
name='api_id', |
||||
field=models.CharField(max_length=2000, verbose_name='接口id'), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-07-19 02:23 |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0007_remove_ecapigroup_order_alter_ecapigroup_api_id'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.RenameField( |
||||
model_name='ecapi', |
||||
old_name='desc', |
||||
new_name='comment', |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-07-19 02:24 |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0008_rename_desc_ecapi_comment'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.RenameField( |
||||
model_name='ecapi', |
||||
old_name='comment', |
||||
new_name='description', |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-07-19 02:25 |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0009_rename_comment_ecapi_description'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.RenameField( |
||||
model_name='ecapiparams', |
||||
old_name='desc', |
||||
new_name='description', |
||||
), |
||||
] |
||||
@ -1,23 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-07-29 05:56 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0010_rename_desc_ecapiparams_description'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='ecrequestlog', |
||||
name='request', |
||||
field=models.CharField(max_length=5000, verbose_name='请求链接'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='ecrequestlog', |
||||
name='response', |
||||
field=models.TextField(verbose_name='返回值'), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-08-05 09:42 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0011_alter_ecrequestlog_request_and_more'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='ecapi', |
||||
name='description', |
||||
field=models.CharField(max_length=50, verbose_name='接口描述'), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-08-05 10:22 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0012_alter_ecapi_description'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='ecapiparams', |
||||
name='description', |
||||
field=models.CharField(max_length=5000, verbose_name='参数描述'), |
||||
), |
||||
] |
||||
@ -1,18 +0,0 @@ |
||||
# Generated by Django 4.2.7 on 2024-08-29 00:30 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dspt_api', '0013_alter_ecapiparams_description'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='ecapi', |
||||
name='order', |
||||
field=models.IntegerField(default=9999, verbose_name='显示顺序'), |
||||
), |
||||
] |
||||
@ -1,117 +0,0 @@ |
||||
from django.db import models |
||||
|
||||
|
||||
class EcChannel(models.Model): |
||||
id = models.IntegerField(primary_key=True) |
||||
env = models.CharField(verbose_name='环境', max_length=10, null=False) # 电商平台 dspt 自营电商 zyds |
||||
name = models.CharField(verbose_name='渠道名称', max_length=20, null=False) # 电商平台 dspt 自营电商 zyds |
||||
pid = models.CharField(verbose_name='渠道id', max_length=10, null=False) # pid |
||||
channel_key = models.CharField(verbose_name='渠道key', max_length=20, null=False) # pid key |
||||
type = models.CharField(verbose_name='会员非会员', max_length=20, default='', null=False) # 会员 member 非会员 nonmember |
||||
|
||||
def __str__(self): |
||||
return self.name |
||||
|
||||
class Meta: |
||||
verbose_name = '渠道' |
||||
verbose_name_plural = '渠道' |
||||
db_table = 'ec_channel' |
||||
|
||||
|
||||
class EcEnv(models.Model): |
||||
id = models.IntegerField(primary_key=True) |
||||
name = models.CharField(verbose_name='环境名称', max_length=20, null=False) # 电商平台 自营电商 |
||||
code = models.CharField(verbose_name='环境编码', max_length=20, null=False) # 电商平台 dspt 自营电商 zyds |
||||
type = models.CharField(verbose_name='会员非会员', max_length=20, default='', null=False) # 会员 member 非会员 nonmember |
||||
host = models.CharField(verbose_name='环境地址', max_length=50, null=False) # 环境地址 |
||||
|
||||
def __str__(self): |
||||
return self.name |
||||
|
||||
class Meta: |
||||
verbose_name = '环境' |
||||
verbose_name_plural = '环境' |
||||
db_table = 'ec_env' |
||||
|
||||
|
||||
class EcApi(models.Model): |
||||
id = models.IntegerField(primary_key=True) |
||||
description = models.CharField(verbose_name='接口描述', max_length=50, null=False) |
||||
path = models.CharField(verbose_name='接口地址', max_length=50, null=False) |
||||
type = models.CharField(verbose_name='会员非会员', max_length=20, default='', null=False) # 会员 member 非会员 nonmember |
||||
order = models.IntegerField(verbose_name='显示顺序', default=9999) |
||||
|
||||
def __str__(self): |
||||
return self.description |
||||
|
||||
class Meta: |
||||
verbose_name = '接口' |
||||
verbose_name_plural = '接口' |
||||
db_table = 'ec_api' |
||||
|
||||
|
||||
class EcApiParams(models.Model): |
||||
id = models.IntegerField(primary_key=True) |
||||
api_id = models.IntegerField(verbose_name='接口id', null=False) |
||||
param = models.CharField(verbose_name='参数', max_length=50, null=False) |
||||
description = models.CharField(verbose_name='参数描述', max_length=5000, null=False) |
||||
value = models.CharField(verbose_name='参数值模版', max_length=500, null=True, blank=True) |
||||
is_checked = models.BooleanField(verbose_name='是否默认勾选', null=False, default=False) |
||||
is_request = models.BooleanField(verbose_name='是否是必选项', null=False, default=False) |
||||
|
||||
def __str__(self): |
||||
return self.param |
||||
|
||||
class Meta: |
||||
verbose_name = '接口参数' |
||||
verbose_name_plural = '接口参数' |
||||
db_table = 'ec_api_params' |
||||
|
||||
|
||||
class EcCinemaIds(models.Model): |
||||
id = models.IntegerField(primary_key=True) |
||||
env = models.CharField(verbose_name='环境', max_length=10, null=False) # 电商平台 dspt 自营电商 zyds |
||||
cinema_id = models.IntegerField(verbose_name='影院id', null=False) |
||||
cinema_name = models.CharField(verbose_name='影院名称', max_length=30, null=False) |
||||
cid = models.CharField(verbose_name='影院cid', max_length=10, null=False) |
||||
|
||||
def __str__(self): |
||||
return self.cid |
||||
|
||||
class Meta: |
||||
verbose_name = '影院cid' |
||||
verbose_name_plural = '影院cid' |
||||
db_table = 'ec_cinema_cid' |
||||
|
||||
|
||||
class EcRequestLog(models.Model): |
||||
id = models.IntegerField(primary_key=True) |
||||
ip = models.CharField(verbose_name='请求ip', max_length=20, null=False) # 接口测试人的ip |
||||
env = models.CharField(verbose_name='环境', max_length=10, null=False) # 电商平台 dspt 自营电商 zyds |
||||
request = models.CharField(verbose_name='请求链接', max_length=5000, null=False) |
||||
response = models.TextField(verbose_name='返回值', null=False) |
||||
request_datetime = models.DateTimeField(verbose_name='请求发送时间', null=False) |
||||
|
||||
def __str__(self): |
||||
return self.ip |
||||
|
||||
class Meta: |
||||
verbose_name = '请求日志' |
||||
verbose_name_plural = '请求日志' |
||||
db_table = 'ec_request_log' |
||||
|
||||
|
||||
class EcApiGroup(models.Model): |
||||
id = models.IntegerField(primary_key=True) |
||||
group_id = models.CharField(verbose_name='接口分组id', max_length=20, null=False) |
||||
name = models.CharField(verbose_name='接口分组id', max_length=20, null=False) |
||||
api_id = models.CharField(verbose_name='接口id', max_length=2000, null=False) |
||||
type = models.CharField(verbose_name='会员非会员', max_length=20, default='', null=False) # 会员 member 非会员 nonmember |
||||
|
||||
def __str__(self): |
||||
return self.name |
||||
|
||||
class Meta: |
||||
verbose_name = '接口组' |
||||
verbose_name_plural = '接口组' |
||||
db_table = 'ec_api_group' |
||||
@ -1,45 +0,0 @@ |
||||
from rest_framework import serializers |
||||
|
||||
from dspt_api.models import EcChannel, EcEnv, EcApi, EcApiParams, EcCinemaIds, EcRequestLog, EcApiGroup |
||||
|
||||
|
||||
class EcChannelSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = EcChannel |
||||
fields = '__all__' |
||||
|
||||
|
||||
class EcEnvSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = EcEnv |
||||
fields = '__all__' |
||||
|
||||
|
||||
class EcApiSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = EcApi |
||||
fields = '__all__' |
||||
|
||||
|
||||
class EcApiParamsSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = EcApiParams |
||||
fields = '__all__' |
||||
|
||||
|
||||
class EcCinemaIdsSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = EcCinemaIds |
||||
fields = '__all__' |
||||
|
||||
|
||||
class EcRequestLogSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = EcRequestLog |
||||
fields = '__all__' |
||||
|
||||
|
||||
class EcApiGroupSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = EcApiGroup |
||||
fields = '__all__' |
||||
@ -1,3 +0,0 @@ |
||||
from django.test import TestCase |
||||
|
||||
# Create your tests here. |
||||
@ -1,20 +0,0 @@ |
||||
from dspt_api import views |
||||
from django.urls import path |
||||
|
||||
urlpatterns = [ |
||||
path('get_channel', views.EcChannelViewSet.as_view({'get': 'list'}), name='get_ec_channel'), |
||||
path('get_env', views.EcEnvViewSet.as_view({'get': 'list'}), name='get_ec_env'), |
||||
path('get_api', views.EcApiViewSet.as_view({'get': 'list'}), name='get_ec_api'), |
||||
path('get_api_params', views.EcApiParamsViewSet.as_view({'get': 'list'}), name='get_ec_api_params'), |
||||
path('get_cinema_ids', views.EcCinemaIdsViewSet.as_view({'get': 'list'}), name='get_ec_cinema_ids'), |
||||
path('get_request_log', views.EcRequestLogViewSet.as_view({'get': 'list'}), name='get_ec_request_log'), |
||||
path('get_api_group', views.EcApiGroupViewSet.as_view({'get': 'list'}), name='get_ec_api_group'), |
||||
path('get_params_by_type', views.get_api_params_by_api_type), |
||||
path('get_url', views.general_api_url), |
||||
path('send_request', views.send_request), |
||||
path('get_suggest_params', views.get_suggest_params_by_api), |
||||
path('get_suggest_params_timestamp', views.get_suggest_params_timestamp_by_api), |
||||
path('set_user_data', views.set_user_select_data), |
||||
path('clear_user_data', views.clear_user_select_data), |
||||
path('get_quan', views.get_quan), |
||||
] |
||||
@ -1,41 +0,0 @@ |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
from dspt_api.util.general.goods_list import get_goods_list |
||||
import random |
||||
|
||||
|
||||
class ApiCinemaGoodsPic(object): |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
|
||||
def get_suggestion(self): |
||||
# play_id play_update_time |
||||
request_api = {'name': '3.2.1 获取卖品列表', 'path': 'cinema/goods'} |
||||
redis_key_api = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api["path"]}' |
||||
result, _format, redis_data, _timestamp = get_data_from_redis(redis_key_api) |
||||
if result: |
||||
goods_list = get_goods_list(redis_data, _format) |
||||
goods = random.choice(goods_list) |
||||
goods_id = goods['id'] |
||||
goods_type = goods['type'] |
||||
return [ |
||||
{'param': 'goods_id', 'value': goods_id, 'is_checked': True, 'result': True, 'timestamp': _timestamp}, |
||||
{'param': 'type', 'value': goods_type, 'is_checked': True, 'result': True, 'timestamp': _timestamp}] |
||||
else: |
||||
# 返回推荐参数应该包含参数名,参数值,和是否勾选的状态 |
||||
return [ |
||||
{'param': 'goods_id', 'value': redis_data + request_api["name"], 'is_checked': True, 'result': False, |
||||
'timestamp': _timestamp}, |
||||
{'param': 'type', 'value': redis_data + request_api["name"], 'is_checked': True, 'result': False, |
||||
'timestamp': _timestamp}] |
||||
|
||||
def get_timestamp(self): |
||||
# play_id play_update_time |
||||
request_api = {'name': '3.2.1 获取卖品列表', 'path': 'cinema/goods'} |
||||
redis_key_api = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api["path"]}' |
||||
result, _format, redis_data, _timestamp = get_data_from_redis(redis_key_api) |
||||
return _timestamp if result else 0 |
||||
@ -1,33 +0,0 @@ |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
import random |
||||
|
||||
|
||||
class ApiCinemaHallSeats: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
|
||||
def get_suggestion(self): |
||||
# hall_id |
||||
request_api = {'name': '3.1.3 获取影厅列表', 'path': 'cinema/halls'} |
||||
redis_key_api = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api["path"]}' |
||||
result, _format, hall_data, _timestamp = get_data_from_redis(redis_key_api) |
||||
if result: |
||||
hall_id = hall_data['id'] |
||||
return [{'param': 'hall_id', 'value': hall_id, 'is_checked': True, 'result': True, 'timestamp': _timestamp}] |
||||
else: |
||||
# 返回推荐参数应该包含参数名,参数值,和是否勾选的状态 |
||||
return [ |
||||
{'param': 'hall_id', 'value': hall_data + request_api["name"], 'is_checked': True, 'result': False, |
||||
'timestamp': _timestamp}] |
||||
|
||||
def get_timestamp(self): |
||||
# hall_id |
||||
request_api = {'name': '3.1.3 获取影厅列表', 'path': 'cinema/halls'} |
||||
redis_key_api = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api["path"]}' |
||||
result, _format, hall_data, _timestamp = get_data_from_redis(redis_key_api) |
||||
return _timestamp if result else 0 |
||||
@ -1,29 +0,0 @@ |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
import datetime |
||||
|
||||
|
||||
class ApiCinemaPlaysIncrement: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
|
||||
def get_suggestion(self): |
||||
# start |
||||
request_api = {'name': '3.1.6 获取放映计划列表(增量)', 'path': 'cinema/plays-increment'} |
||||
redis_key_api = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api["path"]}' |
||||
result, _format, redis_data, _timestamp = get_data_from_redis(redis_key_api) |
||||
# 生成默认值 |
||||
start = redis_data['nextSyncStartTime'] if result else datetime.datetime.strftime(datetime.datetime.now(), |
||||
'%Y-%m-%d') + ' 06:00:00' |
||||
return [{'param': 'start', 'value': start, 'is_checked': True, 'result': True, 'timestamp': _timestamp}] |
||||
|
||||
def get_timestamp(self): |
||||
# start |
||||
request_api = {'name': '3.1.6 获取放映计划列表(增量)', 'path': 'cinema/plays-increment'} |
||||
redis_key_api = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api["path"]}' |
||||
result, _format, redis_data, _timestamp = get_data_from_redis(redis_key_api) |
||||
return _timestamp if result else 0 |
||||
@ -1,53 +0,0 @@ |
||||
import time |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
from dspt_api.util.general.handle_ecard import get_ecard |
||||
|
||||
|
||||
class ApiEcardDetail: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
|
||||
def get_suggestion(self): |
||||
_now = int(time.time() * 1000) |
||||
# 获取本地记录的联名卡 |
||||
if ecard_num := get_ecard(self.ip, self.env, self.pid, self.cid): |
||||
return [{'param': 'ecard_number', 'value': ecard_num,'is_checked': True, 'result': True,'timestamp': _now}] |
||||
# ecard_number |
||||
request_api_ec_1 = {'name': '3.4.4 获取联名卡详情', 'path': 'ecard/detail'} |
||||
redis_key_api_ec_1 = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api_ec_1["path"]}' |
||||
request_api_ec_2 = {'name': '3.4.2 联名卡开卡', 'path': 'ecard/regist'} |
||||
redis_key_api_ec_2 = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api_ec_2["path"]}' |
||||
result_ec_1, _format_ec_1, redis_data_ec_1, _timestamp_ec_1 = get_data_from_redis(redis_key_api_ec_1) |
||||
result_ec_2, _format_ec_2, redis_data_ec_2, _timestamp_ec_2 = get_data_from_redis(redis_key_api_ec_2) |
||||
ecard_number_result = False |
||||
ecard_number = False |
||||
if result_ec_2: |
||||
print('redis_data_ec_2', redis_data_ec_2) |
||||
ecard_number_ec_2 = {'param': 'ecard_number', 'value': redis_data_ec_2['ecardNumber'], |
||||
'is_checked': True, 'result': True, |
||||
'timestamp': _timestamp_ec_2} |
||||
ecard_number = ecard_number_ec_2 |
||||
ecard_number_result = True |
||||
if result_ec_1: |
||||
ecard_number_ec_1 = {'param': 'ecard_number', 'value': redis_data_ec_1['ecardNumber'], |
||||
'is_checked': True, 'result': True, |
||||
'timestamp': _timestamp_ec_1} |
||||
ecard_number = ecard_number_ec_1 |
||||
ecard_number_result = True |
||||
if result_ec_1 and result_ec_2: |
||||
ecard_number = ecard_number_ec_1 if _timestamp_ec_1 >= _timestamp_ec_2 else ecard_number_ec_2 |
||||
|
||||
if ecard_number_result: |
||||
return [ecard_number] |
||||
else: |
||||
return [{'param': 'ecard_number', 'value': redis_data_ec_1 + request_api_ec_1["name"], 'is_checked': True, |
||||
'result': True, |
||||
'timestamp': _now},] |
||||
|
||||
def get_timestamp(self): |
||||
return int(time.time() * 1000) |
||||
@ -1,62 +0,0 @@ |
||||
import time |
||||
from django_redis import get_redis_connection |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
|
||||
|
||||
class ApiEcardOrderDetail: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
|
||||
def get_suggestion(self): |
||||
_now = int(time.time() * 1000) |
||||
# partner_order_no |
||||
request_renew = {'name': '3.4.3 联名卡续卡', 'path': 'ecard/renew'} |
||||
redis_key_renew_order_num = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_renew["path"]}_order_num' |
||||
redis_key_renew = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_renew["path"]}' |
||||
|
||||
request_regist = {'name': '3.4.2 联名卡开卡', 'path': 'ecard/regist'} |
||||
redis_key_regist_order_num = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_regist["path"]}_order_num' |
||||
redis_key_regist = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_regist["path"]}' |
||||
|
||||
result_renew, _format__renew, redis_data_renew, _timestamp_renew = get_data_from_redis(redis_key_renew) |
||||
result_regist, _format_regist, redis_data_regist, _timestamp_regist = get_data_from_redis(redis_key_regist) |
||||
|
||||
redis_conn = get_redis_connection() |
||||
order_num_renew = redis_conn.get(redis_key_renew_order_num) |
||||
print('order_num_renew', order_num_renew) |
||||
order_num_regist = redis_conn.get(redis_key_regist_order_num) |
||||
print('order_num_regist', order_num_regist) |
||||
|
||||
order_num_result = [ |
||||
{'param': 'partner_order_no', 'value': '请手动输入参数!', 'is_checked': True, 'result': True, |
||||
'timestamp': _now}, |
||||
{'param': 'order_type', 'value': '请手动输入参数!', 'is_checked': True, 'result': True, 'timestamp': _now}] |
||||
|
||||
if order_num_regist: |
||||
order_num_result_regist = [ |
||||
{'param': 'partner_order_no', 'value': str(order_num_regist, encoding='utf-8'), 'is_checked': True, |
||||
'result': True, 'timestamp': _now}, |
||||
{'param': 'order_type', 'value': '1', 'is_checked': True, 'result': True, 'timestamp': _now}] |
||||
if order_num_renew: |
||||
order_num_result_renew = [ |
||||
{'param': 'partner_order_no', 'value': str(order_num_renew, encoding='utf-8'), 'is_checked': True, |
||||
'result': True, |
||||
'timestamp': _now}, |
||||
{'param': 'order_type', 'value': '2', 'is_checked': True, 'result': True, 'timestamp': _now}] |
||||
|
||||
if order_num_renew: |
||||
order_num_result = order_num_result_renew |
||||
if order_num_regist: |
||||
order_num_result = order_num_result_regist |
||||
if order_num_renew and order_num_regist: |
||||
order_num_result = order_num_result_regist if _timestamp_regist > _timestamp_renew else order_num_result_renew |
||||
|
||||
return order_num_result |
||||
|
||||
def get_timestamp(self): |
||||
return int(time.time() * 1000) |
||||
@ -1,30 +0,0 @@ |
||||
import time |
||||
from django_redis import get_redis_connection |
||||
from dspt_api.util.general.get_order_num import general_order_num |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
from dspt_api.util.api.ecard_order_detail import ApiEcardOrderDetail |
||||
from dspt_api.util.general.handle_ecard import get_ecard |
||||
|
||||
|
||||
class ApiEcardRefund: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
self.kwargs = kwargs |
||||
|
||||
def get_suggestion(self): |
||||
# source_order_no |
||||
source_order_no = ApiEcardOrderDetail(**self.kwargs).get_suggestion()[0] |
||||
# partner_order_no |
||||
order_num = general_order_num('REF', self.api, self.member_type, self.ip, self.env, self.pid, self.cid) |
||||
return [{'param': 'source_order_no', 'value': source_order_no['value'], 'is_checked': True, 'result': True, |
||||
'timestamp': int(time.time() * 1000)}, |
||||
{'param': 'partner_order_no', 'value': order_num, 'is_checked': True, 'result': True, |
||||
'timestamp': int(time.time() * 1000)}] |
||||
|
||||
def get_timestamp(self): |
||||
return int(time.time() * 1000) |
||||
@ -1,45 +0,0 @@ |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
from dspt_api.util.general.get_order_num import general_order_num |
||||
import time |
||||
import random |
||||
|
||||
|
||||
class ApiEcardRegist: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
|
||||
def get_suggestion(self): |
||||
request_api = {'name': '3.4.1 获取联名卡等级', 'path': 'ecard/ecard-levels'} |
||||
redis_key_api = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api["path"]}' |
||||
result, _format, level_data, _timestamp = get_data_from_redis(redis_key_api) |
||||
if result: |
||||
level_no = level_data['ecardLevelNo'] |
||||
fee = level_data['registerFee'] |
||||
order_num = general_order_num('REG', self.api, self.member_type, self.ip, self.env, self.pid, self.cid) |
||||
return [ |
||||
{'param': 'mobile', 'value': 18688886666, 'is_checked': True, 'result': True, 'timestamp': _timestamp}, |
||||
{'param': 'register_fee', 'value': fee, 'is_checked': True, 'result': True, 'timestamp': _timestamp}, |
||||
{'param': 'ecard_level_no', 'value': level_no, 'is_checked': True, 'result': True, |
||||
'timestamp': _timestamp}, |
||||
{'param': 'partner_order_no', 'value': order_num, 'is_checked': True, 'result': True, |
||||
'timestamp': _timestamp}] |
||||
else: |
||||
# 返回推荐参数应该包含参数名,参数值,和是否勾选的状态 |
||||
return [ |
||||
{'param': 'mobile', 'value': 18688886666, 'is_checked': True, 'result': True, 'timestamp': _timestamp}, |
||||
{'param': 'register_fee', 'value': level_data + request_api["name"], 'is_checked': True, 'result': True, |
||||
'timestamp': _timestamp}, |
||||
{'param': 'ecard_level_no', 'value': level_data + request_api["name"], 'is_checked': True, |
||||
'result': True, |
||||
'timestamp': _timestamp}, |
||||
{'param': 'partner_order_no', 'value': '', 'is_checked': True, 'result': True, |
||||
'timestamp': _timestamp} |
||||
] |
||||
|
||||
def get_timestamp(self): |
||||
return int(time.time() * 1000) |
||||
@ -1,83 +0,0 @@ |
||||
import random |
||||
import time |
||||
from dspt_api.util.general.get_order_num import general_order_num |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
from dspt_api.util.general.handle_ecard import get_ecard, get_ecard_renew_fee |
||||
|
||||
|
||||
class ApiEcardRenew: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
|
||||
def get_suggestion(self): |
||||
_now = int(time.time() * 1000) |
||||
# ecard_number |
||||
# 获取本地记录的联名卡 |
||||
ecard_number_result = False |
||||
ecard_number = False |
||||
if ecard_num := get_ecard(self.ip, self.env, self.pid, self.cid): |
||||
ecard_number = {'param': 'ecard_number', 'value': ecard_num, 'is_checked': True, 'result': True, |
||||
'timestamp': _now} |
||||
ecard_number_result = True |
||||
else: |
||||
request_api_ec_1 = {'name': '3.4.4 获取联名卡详情', 'path': 'ecard/detail'} |
||||
redis_key_api_ec_1 = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api_ec_1["path"]}' |
||||
request_api_ec_2 = {'name': '3.4.2 联名卡开卡', 'path': 'ecard/regist'} |
||||
redis_key_api_ec_2 = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}_{request_api_ec_2["path"]}' |
||||
result_ec_1, _format_ec_1, redis_data_ec_1, _timestamp_ec_1 = get_data_from_redis(redis_key_api_ec_1) |
||||
result_ec_2, _format_ec_2, redis_data_ec_2, _timestamp_ec_2 = get_data_from_redis(redis_key_api_ec_2) |
||||
|
||||
if result_ec_2: |
||||
print('redis_data_ec_2', redis_data_ec_2) |
||||
ecard_number_ec_2 = {'param': 'ecard_number', 'value': redis_data_ec_2['ecardNumber'], |
||||
'is_checked': True, 'result': True, |
||||
'timestamp': _timestamp_ec_2} |
||||
ecard_number = ecard_number_ec_2 |
||||
ecard_number_result = True |
||||
if result_ec_1: |
||||
ecard_number_ec_1 = {'param': 'ecard_number', 'value': redis_data_ec_1['ecardNumber'], |
||||
'is_checked': True, 'result': True, |
||||
'timestamp': _timestamp_ec_1} |
||||
ecard_number = ecard_number_ec_1 |
||||
ecard_number_result = True |
||||
if result_ec_1 and result_ec_2: |
||||
ecard_number = ecard_number_ec_1 if _timestamp_ec_1 >= _timestamp_ec_2 else ecard_number_ec_2 |
||||
|
||||
# renew_fee |
||||
result_renew_fee = False |
||||
if ecard_number is not False: |
||||
fee = get_ecard_renew_fee(ecard_number['value']) |
||||
if fee is not None: |
||||
renew_fee = {'param': 'renew_fee', 'value': fee, |
||||
'is_checked': True, 'result': True, |
||||
'timestamp': _now} |
||||
result_renew_fee = True |
||||
else: |
||||
renew_fee = {'param': 'renew_fee', 'value': '此卡级别不能续卡', |
||||
'is_checked': True, 'result': True, |
||||
'timestamp': _now} |
||||
result_renew_fee = True |
||||
|
||||
# partner_order_no |
||||
order_num = general_order_num('REN', self.api, self.member_type, self.ip, self.env, self.pid, self.cid) |
||||
partner_order_no = {'param': 'partner_order_no', 'value': order_num, 'is_checked': True, 'result': True, |
||||
'timestamp': _now} |
||||
|
||||
if ecard_number_result and result_renew_fee: |
||||
return [ecard_number, renew_fee, partner_order_no] |
||||
else: |
||||
return [{'param': 'ecard_number', 'value': redis_data_ec_1 + request_api_ec_1["name"], 'is_checked': True, |
||||
'result': True, |
||||
'timestamp': _now}, |
||||
{'param': 'renew_fee', 'value': '请手动输入参数!', 'is_checked': True, 'result': True, |
||||
'timestamp': _now}, |
||||
partner_order_no |
||||
] |
||||
|
||||
def get_timestamp(self): |
||||
return int(time.time() * 1000) |
||||
@ -1,29 +0,0 @@ |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
from dspt_api.util.api.seat_lock import ApiSeatLock |
||||
from dspt_api.util.api.ecard_detail import ApiEcardDetail |
||||
import random |
||||
|
||||
|
||||
class ApiEcardSeatPrice: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
self.kwargs = kwargs |
||||
|
||||
def get_suggestion(self): |
||||
# 获取 play_id seat_idplay_update_time |
||||
params = ApiSeatLock(**self.kwargs).get_suggestion() |
||||
# 获取 ecard_number |
||||
ecard_number = ApiEcardDetail(**self.kwargs).get_suggestion() |
||||
return params + ecard_number |
||||
|
||||
def get_timestamp(self): |
||||
# 获取 play_id seat_idplay_update_time |
||||
params_ts = ApiSeatLock(**self.kwargs).get_timestamp() |
||||
# 获取 ecard_number |
||||
ecard_number_ts = ApiEcardDetail(**self.kwargs).get_timestamp() |
||||
return params_ts if params_ts > ecard_number_ts else ecard_number_ts |
||||
@ -1,52 +0,0 @@ |
||||
import json |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
from dspt_api.util.general.get_order_num import general_order_num |
||||
import time |
||||
import random |
||||
|
||||
|
||||
""" |
||||
UPDATE cinema_common_info SET cinema_common_info_val = '[{"channel_name":"ziying","shelf_id":"1"}]' WHERE cinema_common_info_key = 'third_channel_autosell_config'; |
||||
""" |
||||
|
||||
|
||||
class ApiGoodsDeduct: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
self.user_data = { |
||||
'ip': self.ip, |
||||
'env': self.env, |
||||
'member_type': self.member_type, |
||||
'pid': self.pid, |
||||
'cid': self.cid, |
||||
} |
||||
self.return_data = [] |
||||
|
||||
def get_suggestion(self): |
||||
print('get_suggestion', self.user_data) |
||||
self.handle() |
||||
return self.return_data |
||||
|
||||
@staticmethod |
||||
def get_timestamp(): |
||||
return int(time.time() * 1000) |
||||
|
||||
def handle(self): |
||||
# 获取 ticket_flag |
||||
redis_key_prefix = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}' |
||||
request_api_lock_buy = {'name': '3.3.3 混合下单(影票、卖品)', 'path': 'seat/lock-buy'} |
||||
redis_key_api_lock_buy = f'{redis_key_prefix}_{request_api_lock_buy["path"]}' |
||||
result_lock_buy, _format_lock_buy, ticket_flag_lock_buy, _timestamp_lock_buy = get_data_from_redis( |
||||
redis_key_api_lock_buy) |
||||
if not result_lock_buy: |
||||
self.add_param('center_flag', '请手动输入参数,或先请求接口:3.3.3 混合下单(影票、卖品)') |
||||
self.add_param('center_flag', ticket_flag_lock_buy['ticketFlag1'] + ticket_flag_lock_buy['ticketFlag2']) |
||||
|
||||
def add_param(self, field, value, is_checked=True, result=True, timestamp=int(time.time() * 1000)): |
||||
self.return_data.append( |
||||
{'param': field, 'value': value, 'is_checked': is_checked, 'result': result, 'timestamp': timestamp}) |
||||
@ -1,66 +0,0 @@ |
||||
from dspt_api.util.general.handle_redis import get_data_from_redis |
||||
from dspt_api.util.general.get_order_num import general_order_num |
||||
from dspt_api.util.general.handle_goods import general_goods_params |
||||
from dspt_api.util.general.handle_ecard import get_ecard |
||||
import time |
||||
import random |
||||
import json |
||||
|
||||
|
||||
class ApiOrderBuyGoods: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
self.sale_type = kwargs.get('sale_type') |
||||
self.pay_type = kwargs.get('pay_type') |
||||
self.user_data = { |
||||
'ip': self.ip, |
||||
'env': self.env, |
||||
'member_type': self.member_type, |
||||
'pid': self.pid, |
||||
'cid': self.cid, |
||||
} |
||||
self.return_data = [] |
||||
|
||||
def get_suggestion(self): |
||||
# 通用字段 |
||||
self.add_param('mobile', '18688886666', timestamp=1000000000000) |
||||
_partner_buy_ticket_id = general_order_num('BUY_G', self.api, self.member_type, self.ip, self.env, self.pid, |
||||
self.cid) |
||||
self.add_param('partner_buy_ticket_id', _partner_buy_ticket_id) |
||||
|
||||
# 联名卡卡号 |
||||
ecard_num = None |
||||
if self.pay_type == 'ecard': |
||||
ecard_num = get_ecard(self.ip, self.env, self.pid, self.cid) |
||||
self.add_param('ecard_number', ecard_num, timestamp=1000000000000) |
||||
|
||||
self.goods() |
||||
return self.return_data |
||||
|
||||
@staticmethod |
||||
def get_timestamp(): |
||||
return int(time.time() * 1000) |
||||
|
||||
def goods(self): |
||||
delivery_appoint_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time() + 5 * 60)) |
||||
_good_result, _goods_field, _goods_cash, _quan, _goods_timestamp = general_goods_params(self.pay_type, |
||||
self.user_data) |
||||
if _good_result is False: |
||||
self.add_param('goods', '请手动输入参数,或先请求接口:3.2.1 获取卖品列表', timestamp=_goods_timestamp) |
||||
self.add_param('cash', '请手动输入参数,或先请求接口:3.2.1 获取卖品列表', timestamp=_goods_timestamp) |
||||
return False |
||||
self.add_param('goods', json.dumps(_goods_field), timestamp=_goods_timestamp) |
||||
self.add_param('cash', _goods_cash, timestamp=_goods_timestamp) |
||||
self.add_param('delivery_type', '2', is_checked=False, timestamp=_goods_timestamp) |
||||
self.add_param('delivery_location', '1号厅', is_checked=False, timestamp=_goods_timestamp) |
||||
self.add_param('delivery_appoint_time', delivery_appoint_time, is_checked=False, timestamp=_goods_timestamp) |
||||
self.add_param('contact_number', '18688886666', is_checked=False, timestamp=_goods_timestamp) |
||||
|
||||
def add_param(self, field, value, is_checked=True, result=True, timestamp=int(time.time() * 1000)): |
||||
self.return_data.append( |
||||
{'param': field, 'value': value, 'is_checked': is_checked, 'result': result, 'timestamp': timestamp}) |
||||
@ -1,4 +0,0 @@ |
||||
from dspt_api.util.api.order_ticket_flag import ApiOrderTicketFlag |
||||
|
||||
class ApiOrderInfo(ApiOrderTicketFlag): |
||||
pass |
||||
@ -1,46 +0,0 @@ |
||||
import json |
||||
from dspt_api.util.general.handle_redis import get_param_from_redis |
||||
from dspt_api.util.general.get_order_num import general_order_num |
||||
import time |
||||
import random |
||||
|
||||
|
||||
class ApiOrderStatus: |
||||
def __init__(self, **kwargs): |
||||
self.member_type = kwargs.get('member_type') |
||||
self.api = kwargs.get('api') |
||||
self.ip = kwargs.get('ip') |
||||
self.env = kwargs.get('env') |
||||
self.cid = kwargs.get('cid') |
||||
self.pid = kwargs.get('pid') |
||||
self.user_data = { |
||||
'ip': self.ip, |
||||
'env': self.env, |
||||
'member_type': self.member_type, |
||||
'pid': self.pid, |
||||
'cid': self.cid, |
||||
} |
||||
self.return_data = [] |
||||
|
||||
def get_suggestion(self): |
||||
print('get_suggestion', self.user_data) |
||||
self.handle() |
||||
return self.return_data |
||||
|
||||
@staticmethod |
||||
def get_timestamp(): |
||||
return int(time.time() * 1000) |
||||
|
||||
def handle(self): |
||||
# 获取 ticket_flag |
||||
redis_key_prefix = f'dspt_api_{self.ip}_{self.env}_{self.member_type}_{self.pid}_{self.cid}' |
||||
request_api_lock_buy = {'name': '3.3.3 混合下单(影票、卖品)', 'path': 'seat/lock-buy'} |
||||
redis_key_api_lock_buy = f'{redis_key_prefix}_{request_api_lock_buy["path"]}' |
||||
result_lock_buy = get_param_from_redis(redis_key_api_lock_buy) |
||||
if not result_lock_buy: |
||||
self.add_param('partner_order_id', '请手动输入参数,或先请求接口:3.3.3 混合下单(影票、卖品)') |
||||
self.add_param('partner_order_id', result_lock_buy['partner_buy_ticket_id']) |
||||
|
||||
def add_param(self, field, value, is_checked=True, result=True, timestamp=int(time.time() * 1000)): |
||||
self.return_data.append( |
||||
{'param': field, 'value': value, 'is_checked': is_checked, 'result': result, 'timestamp': timestamp}) |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue