diff --git a/api/api_v1/endpoints/query.py b/api/api_v1/endpoints/query.py index 2549b9c..a70a3dc 100644 --- a/api/api_v1/endpoints/query.py +++ b/api/api_v1/endpoints/query.py @@ -17,7 +17,7 @@ from db import get_database from db.ckdb import get_ck_db, CKDrive from db.redisdb import get_redis_pool, RedisDrive -from models.behavior_analysis import BehaviorAnalysis +from models.behavior_analysis import BehaviorAnalysis, CombinationEvent from models.user_analysis import UserAnalysis from utils import DfToStream @@ -64,6 +64,8 @@ async def event_model_export(request: Request, mime = mimetypes.guess_type(file_name)[0] excels = [] for item in sqls: + if not item.get('combination_event'): + continue sql = item['sql'] event_name = item['event_name'] df = await ckdb.query_dataframe(sql) @@ -125,6 +127,17 @@ async def event_model( 'end_date': item['end_date'], 'time_particle': item['time_particle'] } + # 处理组合问题 + if item.get('combination_event'): + combination_event = CombinationEvent(res, item.get('combination_event'), item['format']) + values, sum_, avg = combination_event.parse() + q['values'].append(values) + q['sum'].append(sum_) + q['avg'].append(avg) + q['date_range'] = item['date_range'] + res.append(q) + continue + sql = item['sql'] groupby = item['groupby'] date_range = item['date_range'] @@ -193,16 +206,18 @@ async def event_model( break q['sum'].append(round(float(df['values'].sum()), 2)) q['avg'].append(round(float(df['values'].mean()), 2)) - if item['time_particle'] in ('P1D', 'P1W'): - q['date_range'] = [d.strftime('%Y-%m-%d') for d in q['date_range']] - elif item['time_particle'] in ('P1M',): - q['date_range'] = [d.strftime('%Y-%m') for d in q['date_range']] - else: - q['date_range'] = [d.strftime('%Y-%m-%d %H:%M:%S') for d in q['date_range']] + # q['eventNameDisplay']=item['event_name_display'] res.append(q) # 按总和排序 for item in res: + if item['time_particle'] in ('P1D', 'P1W'): + item['date_range'] = [d.strftime('%Y-%m-%d') for d in item['date_range']] + elif item['time_particle'] in ('P1M',): + item['date_range'] = [d.strftime('%Y-%m') for d in item['date_range']] + else: + item['date_range'] = [d.strftime('%Y-%m-%d %H:%M:%S') for d in item['date_range']] + sort_key = np.argsort(np.array(item['sum']))[::-1] if item.get('groups'): item['groups'] = np.array(item['groups'])[sort_key].tolist() diff --git a/models/behavior_analysis.py b/models/behavior_analysis.py index b8681ec..021e07b 100644 --- a/models/behavior_analysis.py +++ b/models/behavior_analysis.py @@ -19,6 +19,30 @@ from db import get_database from db.redisdb import get_redis_pool, RedisDrive +class CombinationEvent: + def __init__(self, data, string, format): + self.data = data + self.string = string + self.pattern = re.compile('[+\-*/]') + self.format = format + self.events_name = [] + + def parse(self): + opts = self.pattern.findall(self.string) + factors = self.pattern.split(self.string) + result = pd.Series(self.data[int(factors[0])]['values'][0]) + for i, opt in enumerate(opts): + b = pd.Series(self.data[int(factors[i + 1])]['values'][0]) + result = settings.ARITHMETIC[opt](result, b) + if self.format == 'percent': + result = round(result * 100, 2) + elif self.format == 'float': + result = round(result, 2) + elif self.format == 'integer': + result = result.astype(int) + return result.to_list(), result.sum(), round(result.mean(), 2) + + class CustomEvent: def __init__(self, tbl, string, format): self.tbl = tbl @@ -100,6 +124,7 @@ class BehaviorAnalysis: self.date_range = None self.unit_num = None self.report_name = None + self.combination_event = [] async def init(self, *args, **kwargs): @@ -321,17 +346,35 @@ class BehaviorAnalysis: event_name_col = getattr(self.event_tbl.c, '#event_name') format = event.get('format') or 'float' + # 兼容以前的结构 if event.get('customEvent'): - formula = event.get('customEvent') - custom = CustomEvent(self.event_tbl, formula, format).parse() - event_name = custom['event_name'] - where = [event_name_col.in_(event_name)] - event_filter, _ = self.handler_filts(*event['filts']) - select_exprs.extend(self.groupby) - qry = sa.select( - *select_exprs, - custom['select'] - ).where(*base_where, *where, *event_filter) + event['customType'] = event.get('customType') or 'formula' + + if event.get('customType') == 'formula': + if event.get('customEvent'): + formula = event.get('customEvent') + custom = CustomEvent(self.event_tbl, formula, format).parse() + event_name = custom['event_name'] + where = [event_name_col.in_(event_name)] + event_filter, _ = self.handler_filts(*event['filts']) + select_exprs.extend(self.groupby) + qry = sa.select( + *select_exprs, + custom['select'] + ).where(*base_where, *where, *event_filter) + + # 指标组合计算 + elif event.get('customType') == 'combination': + sqls.append({'combination_event': event.get('customEvent'), + 'time_particle': self.time_particle, + 'start_date': self.start_date[:10], + 'end_date': self.end_date[:10], + 'event_name': event.get('eventNameDisplay'), + 'format': event.get('format') or 'float', + 'date_range': self.date_range + } + ) + continue else: event_name = event['event_name'] @@ -386,6 +429,7 @@ class BehaviorAnalysis: 'time_particle': self.time_particle, 'start_date': self.start_date[:10], 'end_date': self.end_date[:10], + }) return sqls