看到layui官网下线的消息,想起以前用layui和fastapi搭建的数据展示后台,缅怀一下,虽然很多大神觉得layui不该存在,但却是我们这些小白非常友好,感谢贤心大佬。
为何要自己搭建数据平台?
当前的信息流平台广告归因做的比较完善,但是搜索推广平台就比较拉垮了,仅有百度ocpc配合api会反馈一些后期效果,主流的360和搜狗并没有类似功能。自己搭建数据平台连接账户推广平台和转化数据,就能回答“80%的广告费浪费在哪了?”
以前用power query+pbi,但是数据多了太卡,刷新一次数据太难,还有很多功能不能满足。
当手上账户多了以后很难实时掌握各个渠道的数据,亏了一天都不知道,知道了也不知道亏在哪里,就需要汇总一目了然。再加上账户长期更换,数据难以积累,自己搭建平台很有必要。
获取数据
首先需要获取各个账户,后期注册转化的原始数据。百度360有api接口,并且门槛低,搜狗api开通有一些要求,新户难开,用cookie可以获取。转化数据简单,找技术要api或sql都可以。
获取的原始数据用sqlIte保存,sqlIte不用搭建环境,简单便携。这里不用对数据做任何处理,确保数据的完整有效。
数据关联
也是本系统的难点,前后数据如果能轻易链接也就不用这么伤神费力了。日期、时间点、地域这些简单,账户 关键词 搜索词连接需要考虑周全。
我这里采用的是sql查询对应的数据到pandas,在后端程序用pandas groupby汇总数据, join链接所需数据。join三四个表,数据有点慢与sql命令,但是sql命令本人实在不熟,切不好维护,放弃速度了。
数据API
数据存储后,用fastapi写接口,获取想要的数据。
def getpage(data,sum,limit,page) -> Response:
"""
传入参数:
limit: int, 必须, 默认为20, 每页显示的数据量
page: int, 必须, 默认为1, 第几页
offset: int, 可选,默认等值于limit, 偏移量
返回:
json数据
"""
offset = limit
df2 = data[(int(page) - 1) * int(offset): (int(page) - 1) * int(offset) + int(limit)]
df_json = df2.to_dict('records')
return JSONResponse(
status_code=status.HTTP_200_OK,
content={
'code': 0,
'message': "Success",
'data': df_json,
'sum':sum,
'count': len(data)
}
)
@app.get("/api/{category}")
async def read_item(category:str,channle:str="",searchParams:str="",page: int = 0, limit: int = 15):
#category数据类别
#searchParams筛选参数
if searchParams !="":
searchParams=json.loads(searchParams)
if searchParams['st']=="":
st="2021-10-11"
else:
st=searchParams['st']
if searchParams['et']=="":
et=time.strftime("%Y-%m-%d", time.localtime())
else:
et=searchParams['et']
if searchParams['channle']=="":
cquery=""
else:
cquery=searchParams['channle'].split(',')
if searchParams['game']=="":
gquery=""
else:
gquery=searchParams['game'].split(',')
else:
#如果没有筛选 设置默认
st="2021-10-11"
et=time.strftime("%Y-%m-%d", time.localtime())
cquery=""
gquery=""
if category =="game":
启动命令uvicorn api:app --reload
layui展示数据
最爱layui的table简单就能达到想要的结果,配合筛选太爽了!
layui.use(['form', 'table'], function () {
var $ = layui.jquery,
form = layui.form,
table = layui.table;
tableSelect = layui.tableSelect;
table.render({
elem: '#currentTableId',
url: 'http://127.0.0.1:8000/api/game',
toolbar: '#toolbarDemo',
defaultToolbar: ['filter', 'exports', 'print', {
title: '提示',
layEvent: 'LAYTABLE_TIPS',
icon: 'layui-icon-tips'
}],
cols: [[
{type: "checkbox", width: 50},
{field: '利润', title: '利润', sort: true},
{field: '收益', title: '收益', sort: true},
{field: '现金', title: '现金', sort: true},
{field: '注册数', title: '注册数', sort: true},
{field: '会员数', title: '会员数', sort: true},
{field: '支付金额', title: '会员金额', sort: true},
]],
limits: [10, 15, 20, 25, 50, 100],
limit: 15,
page: true,
skin: 'line',
done: function(data){
$('#stat').show();
$('#profit_sum').text(data.sum.profit ? data.sum.profit : 0);
$('#stream_sum').text(data.sum.stream ? data.sum.stream : 0);
$('#rmb_sum').text(data.sum.rmb ? data.sum.rmb : 0);
$('#vip_sum').text(data.sum.rmb ? data.sum.vip : 0);
}
});
赞一个。。。。。。