From fcb46e448dd80942be2bd3de52a582a626e5c59a Mon Sep 17 00:00:00 2001 From: rogersun Date: Thu, 18 Jun 2026 14:27:06 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=A0=E5=8A=A0=E6=8E=92=E7=89=87=E7=83=AD?= =?UTF-8?q?=E5=BA=A6=E5=92=8C=E5=9C=BA=E6=AC=A1=E5=8D=A0=E6=AF=94=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=BD=9C=E4=B8=BA=E6=8F=90=E7=A4=BA=E8=AF=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ai/tasks.py | 2 +- ai/utils/movie_data.py | 45 ++++++++++++++++++++++++ ai/utils/show_database.py | 19 +++++++--- ai/utils/show_func.py | 12 +++++++ ai/utils/show_process.py | 73 ++++++++++++++++++++------------------- ai/utils/show_prompt.py | 7 ++++ ai/utils/sql.py | 12 +++++++ 7 files changed, 130 insertions(+), 40 deletions(-) create mode 100644 ai/utils/movie_data.py diff --git a/ai/tasks.py b/ai/tasks.py index 36cd0f8..03d21ea 100644 --- a/ai/tasks.py +++ b/ai/tasks.py @@ -3,7 +3,7 @@ from ai.utils.show_process import show_main_process from ai.utils.basic_func import clear_lock_func -@shared_task +@shared_task(time_limit=18*60, soft_time_limit=18*60) def ai_show_general(): clear_lock_func() show_main_process() diff --git a/ai/utils/movie_data.py b/ai/utils/movie_data.py new file mode 100644 index 0000000..d6bf1ab --- /dev/null +++ b/ai/utils/movie_data.py @@ -0,0 +1,45 @@ +from hashlib import md5 +import requests +import json +from datetime import datetime as dt + + +# 从BI的日常影片数据接口中获取信息 +class MovieData: + def __init__(self): + self.salt = '53b22eda5938706a34fd9d44f097bec2' + self.ts = str(int(dt.timestamp(dt.now()))) + self.url = 'https://nation.bi.piao51.cn/nationDataApi/restful/boxoffice/nation/movieSupportData' + + def get_data(self, movie_code): + params = { + 'movieCode': movie_code, + 'timeStamp': self.ts, + 'sign': self.sign(movie_code) + } + req = requests.get(self.url, params=params) + # print(json.dumps(req.json(), indent=4)) + r = '' + req = req.json() + if (req['success'] is True) and req['data']['movieInfo'] != '': + info = req['data']['movieInfo'] + hot = f"《{info['movie_name']}》 - 想看:{info['wish_num']},热度:小红书{info['xiaohongshu']}、视频号{info['shipinhao']}、抖音{info['douyin']}、微博{info['weibo']};" + print(hot) + daily = req['data']['movieDailyBox'] + sales = [f"{daily[n]['businessDate']} {daily[n]['boxRate']}%" for n in range(0, 6)] + print(sales) + pre_sales = [f"{daily[n]['businessDate']} {daily[n]['boxRate']}%" for n in range(7, len(daily))] + print(pre_sales) + r = f"\t{hot}过去六天的票房占比:{'、'.join(sales)};今天到当前时间的票房占比:{daily[6]['boxRate']}%;未来7天的预售票房占比:{'、'.join(pre_sales)};" + print(r) + return r + + 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 + + +if __name__ == '__main__': + md = MovieData() + md.get_data('001105582014') diff --git a/ai/utils/show_database.py b/ai/utils/show_database.py index a4d9162..3f181bf 100644 --- a/ai/utils/show_database.py +++ b/ai/utils/show_database.py @@ -84,10 +84,14 @@ class GetData: seconds=59) end_datetime = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(hours=6) black_list = json.loads(TestCinema.objects.filter(zz_code=self.zz_code).first().user_config)['movie_black_list'] - print(black_list) - sql = GET_HANDLE_MOVIE + ','.join(['%s']*len(black_list)) + ');' - self.cur.execute(sql, (start_datetime, end_datetime, *black_list)) - # print(self.cur.mogrify(sql, (start_datetime, end_datetime, *black_list))) + if len(black_list) > 0: + sql = GET_HANDLE_MOVIE + ','.join(['%s'] * len(black_list)) + ');' + self.cur.execute(sql, (start_datetime, end_datetime, *black_list)) + print(self.cur.mogrify(sql, (start_datetime, end_datetime, *black_list))) + else: + sql = GET_HANDLE_MOVIE + '\' \'' + ');' + self.cur.execute(sql, (start_datetime, end_datetime)) + print(self.cur.mogrify(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']};" @@ -142,3 +146,10 @@ class GetData: def get_media_type(self): self.cur.execute(GET_HALL_MEDIA_TYPE) + + def get_movie_info(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_MOVIE_INFO, (start_datetime, end_datetime)) + return self.cur.fetchall() diff --git a/ai/utils/show_func.py b/ai/utils/show_func.py index 8ac58bb..9639d56 100644 --- a/ai/utils/show_func.py +++ b/ai/utils/show_func.py @@ -3,6 +3,7 @@ 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 * def get_cinema_show_result_func(_zz_code, _show_date): @@ -58,3 +59,14 @@ def get_template_show(cinema, show_date): temp_show = data.get_show_data(temp_start, temp_end) print('get_template_show', temp_date, temp_show) return temp_show, temp_date + + +def get_all_movie_hot_info(cinema, show_date): + data = GetData(cinema) + movie = data.get_movie_info(show_date) + movie_data = MovieData() + movie_info_list = [] + for m in movie: + print(m) + movie_info_list.append(movie_data.get_data(m['cinema_movie_num'])) + return movie_info_list diff --git a/ai/utils/show_process.py b/ai/utils/show_process.py index 3297f05..9304b7b 100644 --- a/ai/utils/show_process.py +++ b/ai/utils/show_process.py @@ -33,19 +33,43 @@ def show_main_process(zz_code=None): template_show, template_date = get_template_show(cinema, show_date) prompt = show_ai.general_prompt() 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) - # 获取排片数据 - result_obj = json.loads(result) - # 预测排片数据 - _show = result_obj['show'].replace('```', '').replace('csv', '').strip() - # 预测销售数据 - _sales = str(result_obj['income']).strip() - # # 方式一 + # 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) + # # 获取排片数据 + # result_obj = json.loads(result) + # # 预测排片数据 + # _show = result_obj['show'].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, + # template = template_show, + # temp_date=template_date, + # show=_show, + # sales=_sales, + # prompt=prompt, + # result=result, + # message=message, + # take_times=int((end - start).seconds), + # take_tokens=tokens, + # prompt_version=prompt_ver, + # ) + # except Exception as e: + # print(e) + return True + + +# # 方式一 # _show = next((s for s in result.split('------') if s.startswith('\n影厅别名,影厅id')), '') # _show = _show.strip() # # 方式二 @@ -63,25 +87,4 @@ def show_main_process(zz_code=None): # # 获取销售额 # _sales = next((s for s in result.split('\n') if re.search(r'\d{3,6}元', s)), '') # _sales = str(re.findall(r'\d{3,6}元', _sales)[-1]) - # print('_sales:', _sales) - # 处理返回结果 - try: - AiShow.objects.create( - cinema=cinema.name, - zz_code=cinema.zz_code, - show_date=show_date, - is_ai_show=True, - template = template_show, - temp_date=template_date, - show=_show, - sales=_sales, - prompt=prompt, - result=result, - message=message, - take_times=int((end - start).seconds), - take_tokens=tokens, - prompt_version=prompt_ver, - ) - except Exception as e: - print(e) - return True + # print('_sales:', _sales) \ No newline at end of file diff --git a/ai/utils/show_prompt.py b/ai/utils/show_prompt.py index 434c673..1ae288e 100644 --- a/ai/utils/show_prompt.py +++ b/ai/utils/show_prompt.py @@ -2,6 +2,7 @@ from django.db.models import Q from ai.models import PromptTemplate from ai.utils.show_database import GetData from ai.utils.datetime_format import (get_data_datetime, get_date_type) +from ai.utils.show_func import get_all_movie_hot_info import datetime import random import json @@ -65,6 +66,12 @@ class ShowAI: 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 # 获取提示词模板 diff --git a/ai/utils/sql.py b/ai/utils/sql.py index 7b79e67..80da21c 100644 --- a/ai/utils/sql.py +++ b/ai/utils/sql.py @@ -111,6 +111,7 @@ WHERE scvm.system_const_sub_module = 'new_media_type' # 获取指定日期的可用于排片的影片 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, @@ -197,4 +198,15 @@ FROM ( 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 = f""" +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 +GROUP BY cmi.cinema_movie_num; """ \ No newline at end of file