1.家园玩法分析部分加上百分比显示数据
2.新增事件属性添加,修改,删除功能 3.新增用户属性添加,修改,删除功能 4.优化新手引导滞留,等级分布,活跃关卡数据不显示问题
This commit is contained in:
parent
af7091adcc
commit
365a55e528
@ -286,7 +286,12 @@ async def account_owner_list(request: Request,
|
|||||||
resp[-1]['owner_list'] = ','.join(item.get('ftv', []))
|
resp[-1]['owner_list'] = ','.join(item.get('ftv', []))
|
||||||
break
|
break
|
||||||
return schemas.Msg(code=0, msg='ok', data=resp)
|
return schemas.Msg(code=0, msg='ok', data=resp)
|
||||||
|
# @router.post("/git_owner")
|
||||||
|
# async def git_owner(request: Request,
|
||||||
|
# game: str,
|
||||||
|
# db: AsyncIOMotorDatabase = Depends(get_database),
|
||||||
|
# current_user: schemas.UserDB = Depends(deps.get_current_user)) -> schemas.Msg:
|
||||||
|
# user=await crud.user
|
||||||
|
|
||||||
@router.post("/update_account_owner")
|
@router.post("/update_account_owner")
|
||||||
async def account_owner_list(request: Request,
|
async def account_owner_list(request: Request,
|
||||||
|
@ -12,6 +12,7 @@ from core.config import settings
|
|||||||
from db import get_database
|
from db import get_database
|
||||||
from db.ckdb import CKDrive, get_ck_db
|
from db.ckdb import CKDrive, get_ck_db
|
||||||
from db.redisdb import get_redis_pool
|
from db.redisdb import get_redis_pool
|
||||||
|
from utils import estimate_data,dict_to_str
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ async def read_data_attr(
|
|||||||
rdb: Redis = Depends(get_redis_pool),
|
rdb: Redis = Depends(get_redis_pool),
|
||||||
current_user: schemas.UserDB = Depends(deps.get_current_user)
|
current_user: schemas.UserDB = Depends(deps.get_current_user)
|
||||||
) -> schemas.Msg:
|
) -> schemas.Msg:
|
||||||
"""事件属性列表"""
|
"""事件属性列表或用户属性列表"""
|
||||||
data = await rdb.get(f'{game}_{cat}')
|
data = await rdb.get(f'{game}_{cat}')
|
||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
res = []
|
res = []
|
||||||
@ -130,3 +131,27 @@ async def select_attr(
|
|||||||
resp = await crud.select_map.get_select(db, data_in, game)
|
resp = await crud.select_map.get_select(db, data_in, game)
|
||||||
code = 0 if resp else -9
|
code = 0 if resp else -9
|
||||||
return schemas.Msg(code=code, msg='ok', data=resp)
|
return schemas.Msg(code=code, msg='ok', data=resp)
|
||||||
|
|
||||||
|
@router.post("/add_attr")
|
||||||
|
async def add_attr(
|
||||||
|
request: Request,
|
||||||
|
game: str,
|
||||||
|
data_in: schemas.Add_attr,
|
||||||
|
db: AsyncIOMotorDatabase = Depends(get_database),
|
||||||
|
rdb: Redis = Depends(get_redis_pool),
|
||||||
|
current_user: schemas.UserDB = Depends(deps.get_current_user)
|
||||||
|
) -> schemas.Msg:
|
||||||
|
"""添加事件属性或添加用户属性"""
|
||||||
|
data = await rdb.get(f'{game}_{data_in.cat}')
|
||||||
|
data = json.loads(data)
|
||||||
|
if data_in.state =='add':
|
||||||
|
#判断传入数据类型
|
||||||
|
new_data_type=estimate_data(data_in.data_type)
|
||||||
|
#添加数据
|
||||||
|
data[data_in.new_attribute]=new_data_type
|
||||||
|
else:
|
||||||
|
del data[data_in.new_attribute]
|
||||||
|
#将字典转为字符串
|
||||||
|
str_data=dict_to_str(data)
|
||||||
|
await rdb.set(f'{game}_{data_in.cat}',str_data)
|
||||||
|
return schemas.Msg(code=0, msg='ok')
|
@ -27,7 +27,9 @@ async def event_list(
|
|||||||
current_user: schemas.UserDB = Depends(deps.get_current_user)
|
current_user: schemas.UserDB = Depends(deps.get_current_user)
|
||||||
) -> schemas.Msg:
|
) -> schemas.Msg:
|
||||||
"""事件列表"""
|
"""事件列表"""
|
||||||
|
#获取事件名
|
||||||
event_list = await ckdb.distinct(game, 'event', '#event_name')
|
event_list = await ckdb.distinct(game, 'event', '#event_name')
|
||||||
|
#获取事件量
|
||||||
event_count = await ckdb.yesterday_event_count(game)
|
event_count = await ckdb.yesterday_event_count(game)
|
||||||
event_meta = await crud.event_mana.find_many(db, {'game':game}) or {}
|
event_meta = await crud.event_mana.find_many(db, {'game':game}) or {}
|
||||||
if event_meta:
|
if event_meta:
|
||||||
|
@ -172,14 +172,19 @@ async def event_model(
|
|||||||
if item.get('combination_event'):
|
if item.get('combination_event'):
|
||||||
combination_event = CombinationEvent(res, item.get('combination_event'), item['format'])
|
combination_event = CombinationEvent(res, item.get('combination_event'), item['format'])
|
||||||
values, sum_, avg = combination_event.parse()
|
values, sum_, avg = combination_event.parse()
|
||||||
q['values'].append(values)
|
|
||||||
q['sum'].append(sum_)
|
# q['values'].append(values)
|
||||||
|
#q['sum'].append(sum_)
|
||||||
q['avg'].append(avg)
|
q['avg'].append(avg)
|
||||||
q['date_range'] = item['date_range']
|
q['date_range'] = item['date_range']
|
||||||
for last_value in values[::-1]:
|
for last_value in values[::-1]:
|
||||||
if last_value > 0:
|
if last_value > 0:
|
||||||
q['last_value'] = float(last_value)
|
q['last_value'] = float(last_value)
|
||||||
break
|
break
|
||||||
|
for i in range(len(values)):
|
||||||
|
values[i]=str(values[i])+'%'
|
||||||
|
q['values'].append(values)
|
||||||
|
q['sum'].append(str(sum_)+'%')
|
||||||
res.append(q)
|
res.append(q)
|
||||||
continue
|
continue
|
||||||
#sql语句
|
#sql语句
|
||||||
@ -400,10 +405,7 @@ async def retention_model(request: Request,
|
|||||||
}
|
}
|
||||||
return schemas.Msg(code=0, msg='ok', data=resp)
|
return schemas.Msg(code=0, msg='ok', data=resp)
|
||||||
|
|
||||||
#计算流失率
|
|
||||||
# retention_model
|
|
||||||
# retention_model_loss
|
|
||||||
#@router.post("/retention_model")
|
|
||||||
async def retention_model01(request: Request,
|
async def retention_model01(request: Request,
|
||||||
game: str,
|
game: str,
|
||||||
ckdb: CKDrive = Depends(get_ck_db),
|
ckdb: CKDrive = Depends(get_ck_db),
|
||||||
@ -904,6 +906,7 @@ async def scatter_model(
|
|||||||
) -> schemas.Msg:
|
) -> schemas.Msg:
|
||||||
"""分布分析 模型"""
|
"""分布分析 模型"""
|
||||||
await analysis.init(data_where=current_user.data_where)
|
await analysis.init(data_where=current_user.data_where)
|
||||||
|
event_type = analysis.events[0]['eventName']
|
||||||
res = await analysis.scatter_model_sql()
|
res = await analysis.scatter_model_sql()
|
||||||
sql = res['sql']
|
sql = res['sql']
|
||||||
|
|
||||||
@ -1001,31 +1004,37 @@ async def scatter_model(
|
|||||||
label = str(key2)
|
label = str(key2)
|
||||||
n = len(tmp_df2)
|
n = len(tmp_df2)
|
||||||
labels_dict[label] = n
|
labels_dict[label] = n
|
||||||
|
if event_type == 'pay':
|
||||||
#如需要2之后所有之和,则执行下面代码,返回值为字典的labels_dict01
|
#如需要2之后所有之和,则执行下面代码,返回值为字典的labels_dict01
|
||||||
labels_dict01={}
|
labels_dict01={}
|
||||||
v=-1
|
v=-1
|
||||||
for i in labels:
|
for i in labels:
|
||||||
v +=1
|
v +=1
|
||||||
if int(i) == 1:
|
if int(i) == 1:
|
||||||
labels_dict01["1"]=labels_dict['1']
|
labels_dict01["1"]=labels_dict["1"]
|
||||||
else:
|
else:
|
||||||
# for number in labels_dict.keys():
|
# for number in labels_dict.keys():
|
||||||
# if number >=i:
|
# if number >=i:
|
||||||
values=list(labels_dict.values())
|
values=list(labels_dict.values())
|
||||||
n=sum(values[v:])
|
n=sum(values[v:])
|
||||||
labels_dict01[i]=n
|
labels_dict01[i]=n
|
||||||
#传入百分比数据
|
#传入百分比数据
|
||||||
list_p=[]
|
list_p=[]
|
||||||
for i in labels:
|
for i in labels:
|
||||||
number_int=round(labels_dict01.get(i, 0) * 100 / total, 2)
|
number_int=round(labels_dict01.get(i, 0) * 100 / total, 2)
|
||||||
number_str=str(number_int)+'%'
|
number_str=str(number_int)+'%'
|
||||||
list_p.append(number_str)
|
list_p.append(number_str)
|
||||||
|
|
||||||
resp['list'][dt] = {'总体': {'n': [labels_dict01.get(i, 0) for i in labels], 'total': total,
|
resp['list'][dt] = {'总体': {'n': [labels_dict01.get(i, 0) for i in labels], 'total': total,
|
||||||
'p': list_p}}
|
'p': list_p}}
|
||||||
# resp['list'][dt] = {'总体': {'n': [labels_dict.get(i, 0) for i in labels], 'total': total,
|
else:
|
||||||
# 'p': [round(labels_dict.get(i, 0) * 100 / total, 2) for i in labels]}}
|
list_p=[]
|
||||||
|
for i in labels:
|
||||||
|
number_int=round(labels_dict.get(i, 0) * 100 / total, 2)
|
||||||
|
number_str=str(number_int)+'%'
|
||||||
|
list_p.append(number_str)
|
||||||
|
resp['list'][dt] = {'总体': {'n': [labels_dict.get(i, 0) for i in labels], 'total': total,
|
||||||
|
'p': [round(labels_dict.get(i, 0) * 100 / total, 2) for i in labels]}}
|
||||||
return schemas.Msg(code=0, msg='ok', data=resp)
|
return schemas.Msg(code=0, msg='ok', data=resp)
|
||||||
|
|
||||||
# bins_s = pd.cut(tmp_df['values'], bins=bins,
|
# bins_s = pd.cut(tmp_df['values'], bins=bins,
|
||||||
|
@ -4,6 +4,7 @@ from collections import defaultdict
|
|||||||
import time
|
import time
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
import re
|
import re
|
||||||
|
from clickhouse_driver import Client
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from fastapi import APIRouter, Depends, Request
|
from fastapi import APIRouter, Depends, Request
|
||||||
|
@ -31,6 +31,13 @@ class Settings(BaseSettings):
|
|||||||
'db': 1,
|
'db': 1,
|
||||||
'decode_responses': 'utf-8',
|
'decode_responses': 'utf-8',
|
||||||
}
|
}
|
||||||
|
#本地Redis,测试用
|
||||||
|
# REDIS_CONF = {
|
||||||
|
# 'host': '127.0.0.1',
|
||||||
|
# 'port': 6379,
|
||||||
|
# 'db': 1,
|
||||||
|
# 'decode_responses': 'utf-8',
|
||||||
|
# }
|
||||||
|
|
||||||
CK_CONFIG = {'host': '139.159.159.3',
|
CK_CONFIG = {'host': '139.159.159.3',
|
||||||
'port': 9654,
|
'port': 9654,
|
||||||
@ -389,7 +396,13 @@ class Debug(Settings):
|
|||||||
MDB_DB: str = 'xdata'
|
MDB_DB: str = 'xdata'
|
||||||
|
|
||||||
DATABASE_URI = f'mongodb://{MDB_USER}:{MDB_PASSWORD}@{MDB_HOST}:{MDB_PORT}/admin'
|
DATABASE_URI = f'mongodb://{MDB_USER}:{MDB_PASSWORD}@{MDB_HOST}:{MDB_PORT}/admin'
|
||||||
|
#本地MongoDB的库测试
|
||||||
|
# class Debug(Settings):
|
||||||
|
# MDB_HOST: str = '127.0.0.1'
|
||||||
|
# MDB_PORT: int = 27017
|
||||||
|
# MDB_DB: str = 'xdata'
|
||||||
|
#
|
||||||
|
# DATABASE_URI = f'mongodb://{MDB_HOST}:{MDB_PORT}/admin'
|
||||||
|
|
||||||
class Produce(Settings):
|
class Produce(Settings):
|
||||||
MDB_HOST: str = '127.0.0.1'
|
MDB_HOST: str = '127.0.0.1'
|
||||||
|
@ -72,7 +72,6 @@ class CKDrive:
|
|||||||
df = await self.query_dataframe(sql)
|
df = await self.query_dataframe(sql)
|
||||||
return df.T.to_dict().values()
|
return df.T.to_dict().values()
|
||||||
|
|
||||||
|
|
||||||
ckdb = CKDrive()
|
ckdb = CKDrive()
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,8 +124,8 @@ class XAnalysis:
|
|||||||
|
|
||||||
return event_filters
|
return event_filters
|
||||||
|
|
||||||
def ltv_model_sql(self):
|
|
||||||
|
|
||||||
|
def ltv_model_sql(self):
|
||||||
days = (arrow.get(self.event_view['endTime']).date() - arrow.get(self.event_view['startTime']).date()).days
|
days = (arrow.get(self.event_view['endTime']).date() - arrow.get(self.event_view['startTime']).date()).days
|
||||||
quota = self.event_view['quota']
|
quota = self.event_view['quota']
|
||||||
select_ltv = []
|
select_ltv = []
|
||||||
@ -171,7 +171,6 @@ class XAnalysis:
|
|||||||
qry = sa.select().where(*where_account)
|
qry = sa.select().where(*where_account)
|
||||||
sql = str(qry.compile(compile_kwargs={"literal_binds": True}))
|
sql = str(qry.compile(compile_kwargs={"literal_binds": True}))
|
||||||
where_account_str = sql.split('WHERE ')[1]
|
where_account_str = sql.split('WHERE ')[1]
|
||||||
|
|
||||||
sql = f"""SELECT reg.date as date,
|
sql = f"""SELECT reg.date as date,
|
||||||
cnt1,
|
cnt1,
|
||||||
{select_ltv_str},
|
{select_ltv_str},
|
||||||
|
@ -6,3 +6,9 @@ class DataAttrEdit(BaseModel):
|
|||||||
show_name: str
|
show_name: str
|
||||||
is_show: bool
|
is_show: bool
|
||||||
cat: str
|
cat: str
|
||||||
|
|
||||||
|
class Add_attr(BaseModel):
|
||||||
|
cat: str
|
||||||
|
new_attribute: str
|
||||||
|
state: str
|
||||||
|
data_type: str
|
@ -12,3 +12,26 @@ def get_bijiao(bijiao):
|
|||||||
return "IN"
|
return "IN"
|
||||||
elif bijiao == '!=' or bijiao == 'not like' or bijiao == 'is null':
|
elif bijiao == '!=' or bijiao == 'not like' or bijiao == 'is null':
|
||||||
return 'NOT LIKE'
|
return 'NOT LIKE'
|
||||||
|
|
||||||
|
|
||||||
|
# 判断传入的数据类型
|
||||||
|
def estimate_data(data_type):
|
||||||
|
if data_type == 'int':
|
||||||
|
return "Nullable(Int64)"
|
||||||
|
elif data_type == 'ip':
|
||||||
|
return "Nullable(DateTime('UTC'))"
|
||||||
|
else:
|
||||||
|
return "Nullable(String)"
|
||||||
|
#将字典变成字符串
|
||||||
|
def dict_to_str(dic):
|
||||||
|
c = str()
|
||||||
|
b = 0
|
||||||
|
for k, v in dic.items():
|
||||||
|
b += 1
|
||||||
|
if b == 1:
|
||||||
|
c += "{\"%s\":\"%s\"," % (k, v)
|
||||||
|
elif b != len(dic):
|
||||||
|
c += "\"%s\":\"%s\"," % (k, v)
|
||||||
|
else:
|
||||||
|
c += "\"%s\":\"%s\"}" % (k, v)
|
||||||
|
return c
|
Loading…
Reference in New Issue
Block a user