From 9bd21f574ceef44cc607b9744a6824e78d925375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E4=BC=9F?= <250213850@qq.com> Date: Thu, 27 Oct 2022 16:31:01 +0800 Subject: [PATCH] =?UTF-8?q?1.=E6=96=B0=E5=A2=9E=E6=9C=88=E5=85=85=E6=80=BB?= =?UTF-8?q?=E9=A2=9D=E5=92=8C=E5=85=85=E5=80=BC=E6=80=BB=E9=A2=9D=E7=9C=8B?= =?UTF-8?q?=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/api_v1/endpoints/query.py | 23 +++++++++----- models/behavior_analysis.py | 58 ++++++++++++++++++++++++++++++----- utils/func.py | 14 +++++++-- 3 files changed, 78 insertions(+), 17 deletions(-) diff --git a/api/api_v1/endpoints/query.py b/api/api_v1/endpoints/query.py index da48b11..0d7f8f1 100644 --- a/api/api_v1/endpoints/query.py +++ b/api/api_v1/endpoints/query.py @@ -245,9 +245,13 @@ async def event_model( sql = item['sql'] groupby = item['groupby'] date_range = item['date_range'] # 获取的要查询的每一天的时间 - q['date_range'] = date_range # 把要查询的时间加入q字典中 df = await ckdb.query_dataframe(sql) # 以sql语句查出数据,df是二维列表 - df.fillna(0, inplace=True) # 以0填补空数据 + if item['event_name'] == '月充总额': + date_range=df['date'].tolist() + q['date_range']=[str(i).split('-')[0]+'-'+str(i).split('-')[1] for i in date_range] + else: + q['date_range'] = date_range # 把要查询的时间加入q字典中 + df.fillna(0, inplace=True) # 以0填补空数据 # 映射对应中文返回给前端展示 for i in groupby: if i == 'svrindex': @@ -268,10 +272,13 @@ async def event_model( df = pd.DataFrame({'date': date_range, 'values': 0 * len(date_range)}) # continue # return schemas.Msg(code=0, msg='ok', data=[q]) - if item['time_particle'] == 'total': + if item['time_particle'] == 'total' or item['event_name'] == '充值总额': # for group, df_group in df.groupby(groupby): # df_group.reset_index(drop=True, inplace=True) - q['groups'].append(groupby) + if item['event_name'] == '充值总额': + q['groups']=[] + else: + q['groups'].append(groupby) q['values'].append(df['values'].to_list()) q['sum'].append(round(float(df['values'].sum()), 2)) q['avg'].append(round(float(df['values'].mean()), 2)) @@ -360,12 +367,14 @@ async def event_model( else: # 无分组 concat_data = [] + for i in set(date_range) - set(df['date']): concat_data.append((i, 0)) # 纵向拼接两个表 - df = pd.concat([df, pd.DataFrame(concat_data, columns=df.columns)]) - # 在原数据上按data排序 - df.sort_values('date', inplace=True) + if item['event_name'] != '月充总额': + df = pd.concat([df, pd.DataFrame(concat_data, columns=df.columns)]) + # 在原数据上按data排序 + df.sort_values('date', inplace=True) if len(df) >= 2: q['chain_ratio'] = division((df.iloc[-1, 1] - df.iloc[-2, 1]) * 100, df.iloc[-2, 1], 2) if len(df) >= 8: diff --git a/models/behavior_analysis.py b/models/behavior_analysis.py index d1766a4..a5f6087 100644 --- a/models/behavior_analysis.py +++ b/models/behavior_analysis.py @@ -1,3 +1,5 @@ +import calendar +import datetime import re from typing import Tuple from copy import deepcopy @@ -19,7 +21,7 @@ from db import get_database from db.redisdb import get_redis_pool, RedisDrive from models.user_label import UserClusterDef -from utils import get_week, strptime, start_end_month, strptime1, get_event +from utils import get_week, strptime, start_end_month, strptime1, get_event, get_time class CombinationEvent: @@ -568,6 +570,7 @@ class BehaviorAnalysis: """事件分析生成sql会经过""" sqls = [] event_time_col = getattr(self.event_tbl.c, '#event_time') + event_date_col = settings.TIME_GRAIN_EXPRESSIONS['P1M'](event_time_col, self.zone_time)#按月的 for idx, event in enumerate(self.events): operator_ = event.get('operator_val', '') # 排头显示名 @@ -602,10 +605,45 @@ class BehaviorAnalysis: self.ext_filters, nu=idx ) select_exprs.extend(self.groupby) - qry = sa.select( - *select_exprs, - custom['select'] - ).where(*base_where, *where, *event_filter) + if event_name_display == '充值总额': + qry = sa.select( + custom['select'] + ).where(*where,*event_filter) + elif event_name_display == '月充总额': + times = self.start_date.split('-') + start_date = times[0] + '-' + times[1] + '-' + '01 00:00:00' + now = get_time('%Y-%m-%d %H:%M:%S') + _sp_end = self.end_date[0:7] + _now = now[0:7] + if self.end_date < now: + if _sp_end == _now: # 如果结束时间和现在时间是一个月,则取今天为结束时间 + times = now.split(' ') + end_date = times[0] + ' 23:59:59' + else: # 如果是之前月份,则算出那个月的最后一天 + data = self.end_date.split(' ')[0].split('-') + year = int(data[0]) + month = int(data[1]) + weekDay, monthCountDay = calendar.monthrange(year, month) + time = str(datetime.date(year, month, day=monthCountDay)) + end_date = time + ' 23:59:59' + else: # 结束时间大于现在的时间,则取今天的时间 + times = now.split(' ') + end_date = times[0] + ' 23:59:59' + base_time = [ + func.addHours(event_time_col, self.zone_time) >= start_date, + func.addHours(event_time_col, self.zone_time) <= end_date, + ] + qry = sa.select(event_date_col, + custom['select'] + ).where(*base_time, *where, *event_filter)#.group_by(event_date_col) + # qry = sa.select(event_date_col, *self.groupby, values_col) \ + # .where(and_(*where)) \ + # .group_by(event_date_col, *self.groupby, e_account_id_col) + else: + qry = sa.select( + *select_exprs, + custom['select'] + ).where(*base_where, *where, *event_filter) # 指标组合计算 elif event.get('customType') == 'combination': @@ -685,15 +723,19 @@ class BehaviorAnalysis: else: qry = sa.select(selectd).where(and_(*event_filter, *base_where)) - - qry = qry.group_by(*select_exprs) + if event_name_display == '月充总额': + qry = qry.group_by(event_date_col) + else: + qry = qry.group_by(*select_exprs) if self.time_particle != 'total': qry = qry.order_by(sa.Column('date')) else: qry = qry.order_by(sa.Column('values').desc()) qry = qry.limit(10000) - sql = str(qry.compile(compile_kwargs={"literal_binds": True})) + if event_name_display == '充值总额': + sql=sql.replace("""GROUP BY toDate(addHours(huixie.event."#event_time", 8)) ORDER BY date + LIMIT 10000""",'',1) print(sql) # 单独付费率的拿出来 if event.get('customEvent') == 'pay.touch_user_count/login.touch_user_count': diff --git a/utils/func.py b/utils/func.py index bc5d898..86743c4 100644 --- a/utils/func.py +++ b/utils/func.py @@ -223,10 +223,20 @@ async def get_event(attr, game): :param game: str 游戏名 :return: str 事件名 """ - res = await crud.event_point.all_event(get_database(),game) - event_name='' + res = await crud.event_point.all_event(get_database(), game) + event_name = '' for i in res: if attr in i['event_attr']: event_name = i['event_name'] break return event_name + + +def get_time(fmt: str = '%Y-%m-%d') -> str: + ''' + 获取当前时间 + ''' + ts = time.time() + ta = time.localtime(ts) + t = time.strftime(fmt, ta) + return t