Добавлены новые эндпоинты для работы с реферальными ссылками и статистикой Telegram-агентов в integration_api.py. Реализованы функции для получения списка реферальных ссылок, добавления новых ссылок, получения статистики по ссылкам и общей статистики для агентов. Также добавлена функция авторизации Telegram-агента по хешу и регистрация новых агентов. Удалены устаревшие функции из main.py для улучшения структуры кода.

This commit is contained in:
Redsandyg 2025-06-12 16:27:40 +03:00
parent 16973bbb64
commit 7045d6790a
2 changed files with 116 additions and 126 deletions

View File

@ -1,14 +1,15 @@
from fastapi import FastAPI, Depends, HTTPException, status, Header from fastapi import FastAPI, Depends, HTTPException, status, Header, Body
from fastapi.security import OAuth2PasswordBearer from sqlmodel import Session, select, Field
from sqlmodel import Session, select from typing import Optional, List, Dict
from typing import Optional from datetime import datetime, timedelta
from datetime import datetime
import hashlib import hashlib
import uuid import uuid
from sql_models import Company, IntegrationToken, Ref, Sale, AgentTransaction, PartnerTransaction, AgentBalance, TgAgent, CompanyBalance from sql_models import Company, IntegrationToken, Ref, Sale, AgentTransaction, PartnerTransaction, AgentBalance, TgAgent, CompanyBalance
from integration_models import Token, SaleCreateRequest, SaleCreateResponse, TransactionStatus 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() app = FastAPI()
@ -52,6 +53,81 @@ async def get_token_for_api_key(
jwt_token = create_integration_jwt_token(integration_token_db.company_id) jwt_token = create_integration_jwt_token(integration_token_db.company_id)
return {"access_token": jwt_token, "token_type": "bearer"} 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) @app.post("/sale", tags=["integration"], response_model=SaleCreateResponse)
async def create_sale( async def create_sale(
req: SaleCreateRequest, req: SaleCreateRequest,
@ -144,3 +220,37 @@ async def create_sale(
"sale_id": new_sale.sale_id, "sale_id": new_sale.sale_id,
"crediting": new_sale.crediting "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"}

120
main.py
View File

@ -1,4 +1,3 @@
import uuid
from fastapi import ( from fastapi import (
FastAPI, FastAPI,
Depends, Depends,
@ -13,7 +12,6 @@ from typing import Optional, List, Dict
from datetime import timedelta, datetime from datetime import timedelta, datetime
from bff_models import ( from bff_models import (
Token, Token,
RegisterResponse,
DashboardCardsResponse, DashboardCardsResponse,
DashboardChartTotalResponse, DashboardChartTotalResponse,
DashboardChartAgentResponse, DashboardChartAgentResponse,
@ -30,7 +28,6 @@ from bff_models import (
AutoApproveSettingsGetResponse, AutoApproveSettingsGetResponse,
AutoApproveSettingsUpdateResponse, AutoApproveSettingsUpdateResponse,
ApproveTransactionsResult, ApproveTransactionsResult,
TgAuthResponse,
BillingPayoutsTransactionsResponse, BillingPayoutsTransactionsResponse,
AccountProfileUpdateRequest, AccountProfileUpdateRequest,
AccountPasswordChangeRequest, AccountPasswordChangeRequest,
@ -42,7 +39,6 @@ from bff_models import (
IntegrationTokenCreateRequest, IntegrationTokenCreateRequest,
IntegrationTokenUpdateRequest IntegrationTokenUpdateRequest
) )
from tg_models import RefAddRequest, RefResponse, RegisterRequest, RefAddResponse, RefStatResponse, StatResponse
from sql_models import ( from sql_models import (
Company, Company,
TgAgent, TgAgent,
@ -59,9 +55,7 @@ import hashlib
from helpers_bff import ( from helpers_bff import (
AUTH_DB_ENGINE, AUTH_DB_ENGINE,
get_db, get_db,
get_tg_agent_by_tg_id,
get_current_account, get_current_account,
get_current_tg_agent,
create_access_token, create_access_token,
verify_password, verify_password,
get_account_by_login, get_account_by_login,
@ -77,41 +71,6 @@ SQLModel.metadata.create_all(AUTH_DB_ENGINE)
app = FastAPI() 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"]) @app.post("/token", response_model=Token, tags=["bff", "token"])
def login_account_for_access_token( def login_account_for_access_token(
form_data: OAuth2PasswordRequestForm = Depends(), form_data: OAuth2PasswordRequestForm = Depends(),
@ -136,72 +95,6 @@ def login_account_for_access_token(
return Token(access_token=access_token, token_type="bearer") 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) @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)): 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) @app.get("/account", tags=["bff", "account"], response_model=AccountResponse)
def get_account(current_account: Account = Depends(get_current_account)): def get_account(current_account: Account = Depends(get_current_account)):
""" """