diff --git a/api/api_v1/endpoints/query.py b/api/api_v1/endpoints/query.py index 048d712..8ffa69f 100644 --- a/api/api_v1/endpoints/query.py +++ b/api/api_v1/endpoints/query.py @@ -100,7 +100,8 @@ async def event_model( 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)]) + df.sort_values('values', inplace=True) q['values'].append(df['values'].to_list()) - q['date_range'] = [d.strftime('%Y-%m/%d %H:%M:%S') for d in q['date_range']] + q['date_range'] = [d.strftime('%Y-%m-%d %H:%M:%S') for d in q['date_range']] res.append(q) return schemas.Msg(code=0, msg='ok', data=res) diff --git a/api/api_v1/endpoints/user.py b/api/api_v1/endpoints/user.py index acf4350..f409a24 100644 --- a/api/api_v1/endpoints/user.py +++ b/api/api_v1/endpoints/user.py @@ -38,6 +38,7 @@ async def login( 'name': user.name, 'nickname': user.nickname, 'email': user.email, + 'tel': user.tel, 'token': security.create_access_token( expires_delta=access_token_expires, _id=str(user.id), email=user.email, nickname=user.nickname, @@ -97,6 +98,20 @@ async def reset_password(request: Request, return schemas.Msg(code=0, msg='ok') +@router.post("/edit_profile") +async def edit_profile(request: Request, + game: str, + data_in: schemas.UserProfileEdit, + db: AsyncIOMotorDatabase = Depends(get_database), + current_user: schemas.User = Depends(deps.get_current_user) + ) -> Any: + """ + 编辑用户资料 + """ + await crud.user.edit_profile(db, data_in) + return schemas.Msg(code=0, msg='ok', data=data_in) + + @router.get("/all_account") async def all_account(page: int = 1, limit: int = 10, db: AsyncIOMotorDatabase = Depends(get_database), current_user: schemas.User = Depends(deps.get_current_user) diff --git a/crud/crud_user.py b/crud/crud_user.py index bff4f92..5911f78 100644 --- a/crud/crud_user.py +++ b/crud/crud_user.py @@ -18,6 +18,12 @@ class CRUDUser(CRUDBase): res = await db[self.coll_name].find_one({'name': name}) return res + async def edit_profile(self, db: AsyncIOMotorDatabase, data_id: schemas.UserProfileEdit): + if data_id.nickname: + await self.update_one(db, {'_id': data_id.user_id}, {'$set': data_id.nickname}) + if data_id.nickname: + await self.update_one(db, {'_id': data_id.user_id}, {'$set': data_id.tel}) + async def update_login_time(self, db, name): await self.update_one(db, {'name': name}, {'$set': {'last_login_ts': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}}) diff --git a/main.py b/main.py index 04b5c84..a3730b7 100644 --- a/main.py +++ b/main.py @@ -82,12 +82,12 @@ app.add_middleware( @app.exception_handler(RequestValidationError) async def validation_exception_handler(request, exc): - return Response(schemas.Msg(code='-4', msg='请求错误', data=str(exc)), status_code=400) + return Response(schemas.Msg(code='-4', msg='请求错误', data=str(exc)).json(), status_code=400) @app.exception_handler(Exception) async def http_exception_handler(request, exc): - return Response(schemas.Msg(code='-3', msg='服务器错误'), status_code=500) + return Response(schemas.Msg(code='-3', msg='服务器错误').json(), status_code=500) @app.middleware("http") diff --git a/models/to_sql.py b/models/to_sql.py index 1722cfd..56ce5f6 100644 --- a/models/to_sql.py +++ b/models/to_sql.py @@ -1,7 +1,7 @@ from typing import List, Tuple import sqlalchemy as sa from sqlalchemy.sql import func -from sqlalchemy import create_engine, column, and_, desc, table, or_ +from sqlalchemy import create_engine, column, and_, desc, table, or_, select import pandas as pd from core.config import settings @@ -58,16 +58,22 @@ class ToSql: for event in self.events: event_name = event['event_name'] - where = [ + base_where = [ func.addHours(self.event_columns['#event_time'], time_zone) >= start_data, func.addHours(self.event_columns['#event_time'], time_zone) <= end_data, self.event_columns['#event_name'] == event_name ] analysis = event['analysis'] filters = event['filters'] + self.get_global_filters() + + event_filter = [] + user_filter = [] + for item in filters: if item['table_type'] == 'user': - is_join_user = True + where = user_filter + elif item['table_type'] == 'event': + where = event_filter col = getattr(self, f'{item["table_type"]}_columns').get(item['column_id']) @@ -95,37 +101,48 @@ class ToSql: elif comparator == '!=': where.append(col != ftv[0]) + # 查出用户过滤 + subq = sa.select([self.user_columns.get('#account_id')]) + subq = subq.where(and_(*user_filter)) + if analysis == 'total_count': - qry = sa.select(select_exprs + [func.count().label('values')]) + selectd = select_exprs + [func.count().label('values')] elif analysis == 'touch_user_count': - qry = sa.select( + selectd = sa.select( select_exprs + [func.count(sa.distinct(self.event_columns['#account_id'])).label('values')]) elif analysis == 'touch_user_avg': - qry = sa.select(select_exprs + [ + selectd = select_exprs + [ func.round((func.count() / func.count(sa.distinct(self.event_columns['#account_id']))), 2).label( - 'values')]) + 'values')] elif analysis == 'distinct_count': - qry = sa.select( - select_exprs + [ - func.count(sa.distinct(self.event_columns[event['event_attr_id']])).label('values')]) + selectd = select_exprs + [ + func.count(sa.distinct(self.event_columns[event['event_attr_id']])).label('values')] else: - qry = sa.select( - select_exprs + [ - func.round(getattr(func, analysis)(self.event_columns[event['event_attr_id']]), 2).label( - 'values')]) + selectd = select_exprs + [ + func.round(getattr(func, analysis)(self.event_columns[event['event_attr_id']]), 2).label( + 'values')] + + account_id = column('#account_id') + + if user_filter: + sa.table('user', account_id) + on_clause = [self.event_columns.get('#account_id') == account_id] + qry = self.event_table.join(subq.alias('user'), and_(*on_clause)) + + qry = sa.select(selectd).select_from(qry) + qry = qry.where(and_(*event_filter, *base_where)) + else: + qry = sa.select(selectd) + qry = qry.where(and_(*event_filter, *base_where)) - qry = qry.where(and_(*where)) qry = qry.group_by(*select_exprs) - qry = qry.order_by(column('date')) qry = qry.limit(1000) - qry = qry.select_from(self.event_table) - if is_join_user: - qry = qry.join(self.user_table, - and_(self.event_columns.get('#account_id') == self.user_columns.get('#account_id'))) + # self.event_table.join(self.user_table, and_(*on_clause)) + # qry = qry.select_from(self.event_table) sql = str(qry.compile(self.engine, compile_kwargs={"literal_binds": True})) print(sql) sqls.append({'sql': sql, diff --git a/schemas/user.py b/schemas/user.py index 9e93545..9ab2f27 100644 --- a/schemas/user.py +++ b/schemas/user.py @@ -11,6 +11,13 @@ class UserBase(BaseModel): name: Optional[str] = None nickname: str = '' last_login_ts: str = '尚未登录' + tel: str = '' + + +class UserProfileEdit(BaseModel): + user_id: str + nickname: str = None + tel: str = None class User(UserBase): @@ -30,9 +37,11 @@ class UserRestPassword(BaseModel): username: str = ... password: str = ... + class UserRestMyPassword(BaseModel): password: str = ... + class UserCreate(UserBase): password: str name: str @@ -46,7 +55,8 @@ class UserDB(DBBase): email: EmailStr = None is_superuser: bool = False name: str - nickname: str + nickname: str = '' + tel: str = '' last_login_ts: str = '尚未登录'