diff --git a/integration_api.py b/integration_api.py index 98928b4..1aeda50 100644 --- a/integration_api.py +++ b/integration_api.py @@ -1,14 +1,15 @@ -from fastapi import FastAPI, Depends, HTTPException, status, Header -from fastapi.security import OAuth2PasswordBearer -from sqlmodel import Session, select -from typing import Optional -from datetime import datetime +from fastapi import FastAPI, Depends, HTTPException, status, Header, Body +from sqlmodel import Session, select, Field +from typing import Optional, List, Dict +from datetime import datetime, timedelta import hashlib import uuid from sql_models import Company, IntegrationToken, Ref, Sale, AgentTransaction, PartnerTransaction, AgentBalance, TgAgent, CompanyBalance from integration_models import Token, SaleCreateRequest, SaleCreateResponse, TransactionStatus -from helpers_bff import AUTH_DB_ENGINE, get_integration_db, create_integration_jwt_token, get_current_company_from_jwt +from bff_models import RegisterResponse, TgAuthResponse +from tg_models import RefAddRequest, RefResponse, RefAddResponse, RefStatResponse, RegisterRequest, StatResponse +from helpers_bff import AUTH_DB_ENGINE, get_integration_db, create_integration_jwt_token, get_current_company_from_jwt, get_tg_agent_by_tg_id, get_current_tg_agent app = FastAPI() @@ -52,6 +53,81 @@ async def get_token_for_api_key( jwt_token = create_integration_jwt_token(integration_token_db.company_id) return {"access_token": jwt_token, "token_type": "bearer"} +@app.get("/ref", response_model=List[RefResponse], tags=["partner-tg"]) +def get_refs(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)): + """ + Возвращает список реферальных ссылок текущего Telegram-агента. + """ + refs = db.exec(select(Ref).where(Ref.tg_agent_id == current_tg_agent.id)).all() + return [RefResponse(ref=r.ref, description=r.description or "") for r in refs] + +@app.post("/ref/add", tags=["partner-tg"], response_model=RefAddResponse) +def add_ref(req: RefAddRequest, current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)): + """ + Добавляет новую реферальную ссылку для текущего Telegram-агента. + """ + new_ref = Ref( + tg_agent_id=current_tg_agent.id, + ref=str(uuid.uuid4()), + description=req.description + ) + db.add(new_ref) + db.commit() + db.refresh(new_ref) + return {"ref": new_ref.ref} + +@app.get("/ref/stat", tags=["partner-tg"], response_model=RefStatResponse) +def get_ref_stat(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)): + """ + Возвращает статистику по реферальным ссылкам текущего Telegram-агента. + """ + # 1. Получаем все реферальные ссылки пользователя + refs = db.exec(select(Ref).where(Ref.tg_agent_id == current_tg_agent.id)).all() + result = [] + for ref in refs: + # 2. Для каждой ссылки считаем продажи и сумму + sales = db.exec(select(Sale).where(Sale.ref == ref.id)).all() + sales_count = len(sales) + income = sum(sale.crediting for sale in sales) + result.append({ + "description": ref.description or "", + "sales": sales_count, + "income": income + }) + return {"refData": result} + +@app.get("/stat", tags=["partner-tg"], response_model=StatResponse) +def get_stat(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_integration_db)): + """ + Возвращает общую статистику для текущего Telegram-агента. + """ + # 1. Получаем все реферальные ссылки пользователя + refs = db.exec(select(Ref).where(Ref.tg_agent_id == current_tg_agent.id)).all() + ref_ids = [r.id for r in refs] + + # 2. Считаем totalSales (продажи по всем рефам пользователя) + total_sales = db.exec(select(Sale).where(Sale.ref.in_(ref_ids))).all() + totalSales = len(total_sales) + totalIncome = sum(sale.crediting for sale in total_sales) + # Заменено получение доступного остатка из AgentBalance + agent_balance = db.exec(select(AgentBalance).where(AgentBalance.tg_agent_id == current_tg_agent.id)).first() + availableWithdrawal = agent_balance.available_balance if agent_balance else 0.0 + return { + "totalSales": totalSales, + "totalIncome": totalIncome, + "availableWithdrawal": availableWithdrawal + } + +@app.post("/tg_auth", tags=["partner-tg"], response_model=TgAuthResponse) +def tg_auth(hash: str = Body(..., embed=True), db: Session = Depends(get_integration_db)): + """ + Авторизует Telegram-агента по хешу. + """ + tg_agent = db.exec(select(TgAgent).where(TgAgent.hash == hash)).first() + if not tg_agent: + raise HTTPException(status_code=401, detail="Hash not found") + return {"msg": "Auth success", "tg_id": tg_agent.tg_id} + @app.post("/sale", tags=["integration"], response_model=SaleCreateResponse) async def create_sale( req: SaleCreateRequest, @@ -144,3 +220,37 @@ async def create_sale( "sale_id": new_sale.sale_id, "crediting": new_sale.crediting } + +@app.post("/register", tags=["partner-tg"], response_model=RegisterResponse) +def register(req: RegisterRequest, db: Session = Depends(get_integration_db)): + """ + Регистрирует нового Telegram-агента в системе. + """ + tg_id = req.tg_id + chat_id = req.chat_id + phone = req.phone + name = getattr(req, 'name', None) + login = getattr(req, 'login', None) + company_key = req.company_key + print(f'tg_id: {tg_id}, chat_id: {chat_id}, phone: {phone}, name: {name}, login: {login}, company_key: {company_key}') + tg_agent = get_tg_agent_by_tg_id(db, tg_id) + if tg_agent: + raise HTTPException(status_code=400, detail="tg_id already registered") + # Поиск компании по ключу + company = db.exec(select(Company).where(Company.key == company_key)).first() + if not company: + raise HTTPException(status_code=400, detail="Компания с таким ключом не найдена") + hash_value = hashlib.sha256(f"{tg_id}sold".encode()).hexdigest() + new_tg_agent = TgAgent( + tg_id=tg_id, + chat_id=chat_id, + phone=phone, + name=name, + login=login, + hash=hash_value, + company_id=company.id + ) + db.add(new_tg_agent) + db.commit() + db.refresh(new_tg_agent) + return {"msg": "TgAgent registered successfully"} diff --git a/main.py b/main.py index 113e594..622df40 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,3 @@ -import uuid from fastapi import ( FastAPI, Depends, @@ -13,7 +12,6 @@ from typing import Optional, List, Dict from datetime import timedelta, datetime from bff_models import ( Token, - RegisterResponse, DashboardCardsResponse, DashboardChartTotalResponse, DashboardChartAgentResponse, @@ -30,7 +28,6 @@ from bff_models import ( AutoApproveSettingsGetResponse, AutoApproveSettingsUpdateResponse, ApproveTransactionsResult, - TgAuthResponse, BillingPayoutsTransactionsResponse, AccountProfileUpdateRequest, AccountPasswordChangeRequest, @@ -42,7 +39,6 @@ from bff_models import ( IntegrationTokenCreateRequest, IntegrationTokenUpdateRequest ) -from tg_models import RefAddRequest, RefResponse, RegisterRequest, RefAddResponse, RefStatResponse, StatResponse from sql_models import ( Company, TgAgent, @@ -59,9 +55,7 @@ import hashlib from helpers_bff import ( AUTH_DB_ENGINE, get_db, - get_tg_agent_by_tg_id, get_current_account, - get_current_tg_agent, create_access_token, verify_password, get_account_by_login, @@ -77,41 +71,6 @@ SQLModel.metadata.create_all(AUTH_DB_ENGINE) app = FastAPI() -@app.post("/register", tags=["partner-tg"], response_model=RegisterResponse) -def register(req: RegisterRequest, db: Session = Depends(get_db)): - """ - Регистрирует нового Telegram-агента в системе. - """ - tg_id = req.tg_id - chat_id = req.chat_id - phone = req.phone - name = getattr(req, 'name', None) - login = getattr(req, 'login', None) - company_key = req.company_key - print(f'tg_id: {tg_id}, chat_id: {chat_id}, phone: {phone}, name: {name}, login: {login}, company_key: {company_key}') - tg_agent = get_tg_agent_by_tg_id(db, tg_id) - if tg_agent: - raise HTTPException(status_code=400, detail="tg_id already registered") - # Поиск компании по ключу - company = db.exec(select(Company).where(Company.key == company_key)).first() - if not company: - raise HTTPException(status_code=400, detail="Компания с таким ключом не найдена") - hash_value = hashlib.sha256(f"{tg_id}sold".encode()).hexdigest() - new_tg_agent = TgAgent( - tg_id=tg_id, - chat_id=chat_id, - phone=phone, - name=name, - login=login, - hash=hash_value, - company_id=company.id - ) - db.add(new_tg_agent) - db.commit() - db.refresh(new_tg_agent) - return {"msg": "TgAgent registered successfully"} - - @app.post("/token", response_model=Token, tags=["bff", "token"]) def login_account_for_access_token( form_data: OAuth2PasswordRequestForm = Depends(), @@ -136,72 +95,6 @@ def login_account_for_access_token( return Token(access_token=access_token, token_type="bearer") - -@app.get("/ref", response_model=List[RefResponse], tags=["partner-tg"]) -def get_refs(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_db)): - """ - Возвращает список реферальных ссылок текущего Telegram-агента. - """ - refs = db.exec(select(Ref).where(Ref.tg_agent_id == current_tg_agent.id)).all() - return [RefResponse(ref=r.ref, description=r.description or "") for r in refs] - -@app.post("/ref/add", tags=["partner-tg"], response_model=RefAddResponse) -def add_ref(req: RefAddRequest, current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_db)): - """ - Добавляет новую реферальную ссылку для текущего Telegram-агента. - """ - new_ref = Ref( - tg_agent_id=current_tg_agent.id, - ref=str(uuid.uuid4()), - description=req.description - ) - db.add(new_ref) - db.commit() - db.refresh(new_ref) - return {"ref": new_ref.ref} - -@app.get("/ref/stat", tags=["partner-tg"], response_model=RefStatResponse) -def get_ref_stat(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_db)): - """ - Возвращает статистику по реферальным ссылкам текущего Telegram-агента. - """ - # 1. Получаем все реферальные ссылки пользователя - refs = db.exec(select(Ref).where(Ref.tg_agent_id == current_tg_agent.id)).all() - result = [] - for ref in refs: - # 2. Для каждой ссылки считаем продажи и сумму - sales = db.exec(select(Sale).where(Sale.ref == ref.id)).all() - sales_count = len(sales) - income = sum(sale.crediting for sale in sales) - result.append({ - "description": ref.description or "", - "sales": sales_count, - "income": income - }) - return {"refData": result} - -@app.get("/stat", tags=["partner-tg"], response_model=StatResponse) -def get_stat(current_tg_agent: TgAgent = Depends(get_current_tg_agent), db: Session = Depends(get_db)): - """ - Возвращает общую статистику для текущего Telegram-агента. - """ - # 1. Получаем все реферальные ссылки пользователя - refs = db.exec(select(Ref).where(Ref.tg_agent_id == current_tg_agent.id)).all() - ref_ids = [r.id for r in refs] - - # 2. Считаем totalSales (продажи по всем рефам пользователя) - total_sales = db.exec(select(Sale).where(Sale.ref.in_(ref_ids))).all() - totalSales = len(total_sales) - totalIncome = sum(sale.crediting for sale in total_sales) - # Заменено получение доступного остатка из AgentBalance - agent_balance = db.exec(select(AgentBalance).where(AgentBalance.tg_agent_id == current_tg_agent.id)).first() - availableWithdrawal = agent_balance.available_balance if agent_balance else 0.0 - return { - "totalSales": totalSales, - "totalIncome": totalIncome, - "availableWithdrawal": availableWithdrawal - } - @app.get("/dashboard/cards", tags=["bff", "dashboard"], response_model=DashboardCardsResponse) def get_dashboard_cards(current_account: Account = Depends(get_current_account), db: Session = Depends(get_db)): """ @@ -504,19 +397,6 @@ def get_billing_chart_pie(current_account: Account = Depends(get_current_account -@app.post("/tg_auth", tags=["partner-tg"], response_model=TgAuthResponse) -def tg_auth(hash: str = Body(..., embed=True), db: Session = Depends(get_db)): - """ - Авторизует Telegram-агента по хешу. - """ - tg_agent = db.exec(select(TgAgent).where(TgAgent.hash == hash)).first() - if not tg_agent: - raise HTTPException(status_code=401, detail="Hash not found") - return {"msg": "Auth success", "tg_id": tg_agent.tg_id} - -# --- Новый функционал для Account --- - - @app.get("/account", tags=["bff", "account"], response_model=AccountResponse) def get_account(current_account: Account = Depends(get_current_account)): """