common update

This commit is contained in:
2025-06-18 11:48:41 +07:00
parent 88c4ee362e
commit 047290e2ea
27 changed files with 1533 additions and 87 deletions
+6
View File
@@ -0,0 +1,6 @@
from .server import ServerRepository
from .channel import ChannelRepository
from .channel_app import ChannelAppRepository
from .user import UserRepository
__all__ = ['ServerRepository', 'ChannelRepository', 'ChannelAppRepository', 'UserRepository']
+44
View File
@@ -0,0 +1,44 @@
from typing import Optional, List
from models.channel import DiscordChannel
from infra.db import postgres
class ChannelRepository:
def __init__(self):
self.table = postgres.get_table('discord_channel')
async def get_channel(self, channel_id: int) -> Optional[DiscordChannel]:
try:
response = self.table.select('*').eq('channel_id', channel_id).execute()
if response.data:
return DiscordChannel(**response.data[0])
return None
except Exception as e:
print(f"Error getting channel: {e}")
return None
async def get_channels_by_server(self, server_id: int) -> List[DiscordChannel]:
try:
response = self.table.select('*').eq('server_id', server_id).execute()
return [DiscordChannel(**channel) for channel in response.data]
except Exception as e:
print(f"Error getting channels: {e}")
return []
async def create_channel(self, server_id: int, channel_id: int, app: str) -> Optional[DiscordChannel]:
try:
channel = DiscordChannel(server_id=server_id, channel_id=channel_id, app=app)
response = self.table.insert(channel.dict(exclude_none=True)).execute()
return DiscordChannel(**response.data[0])
except Exception as e:
print(f"Error creating channel: {e}")
return None
async def update_channel(self, channel_id: int, app: str) -> Optional[DiscordChannel]:
try:
response = self.table.update({'app': app}).eq('channel_id', channel_id).execute()
if response.data:
return DiscordChannel(**response.data[0])
return None
except Exception as e:
print(f"Error updating channel: {e}")
return None
+52
View File
@@ -0,0 +1,52 @@
from typing import Optional, List
from models.channel_app import DiscordChannelApp
from infra.db import postgres
class ChannelAppRepository:
def __init__(self):
self.table = postgres.get_table('discord_channel_app')
async def get_channel_app(self, name: str) -> Optional[DiscordChannelApp]:
try:
response = self.table.select('*').eq('name', name).execute()
if response.data:
return DiscordChannelApp(**response.data[0])
return None
except Exception as e:
print(f"Error getting channel app: {e}")
return None
async def get_all_apps(self) -> List[DiscordChannelApp]:
try:
response = self.table.select('*').execute()
return [DiscordChannelApp(**app) for app in response.data]
except Exception as e:
print(f"Error getting channel apps: {e}")
return []
async def create_channel_app(self, name: str, description: str) -> Optional[DiscordChannelApp]:
try:
app = DiscordChannelApp(name=name, description=description)
response = self.table.insert(app.dict(exclude_none=True)).execute()
return DiscordChannelApp(**response.data[0])
except Exception as e:
print(f"Error creating channel app: {e}")
return None
async def update_channel_app(self, name: str, description: str) -> Optional[DiscordChannelApp]:
try:
response = self.table.update({'description': description}).eq('name', name).execute()
if response.data:
return DiscordChannelApp(**response.data[0])
return None
except Exception as e:
print(f"Error updating channel app: {e}")
return None
async def delete_channel_app(self, channel_id: int, app_name: str) -> bool:
try:
response = self.table.delete().eq('channel_id', channel_id).eq('app_name', app_name).execute()
return len(response.data) > 0
except Exception as e:
print(f"Error deleting channel app: {e}")
return False
+103
View File
@@ -0,0 +1,103 @@
from typing import List, Optional
from datetime import datetime
from models.debt_group import HomeMember, Expense, ExpenseShare
from infra.db import postgres
class HomeDebtRepository:
_instance = None
_initialized = False
def __new__(cls):
if cls._instance is None:
cls._instance = super(HomeDebtRepository, cls).__new__(cls)
return cls._instance
def __init__(self):
if not HomeDebtRepository._initialized:
self.db = postgres.get_table('home_members')
HomeDebtRepository._initialized = True
async def add_member(self, discord_user_id: int, name: str) -> HomeMember:
"""Thêm thành viên mới vào nhà"""
data = await self.db.table("home_members").insert({
"discord_user_id": discord_user_id,
"name": name
}).execute()
return HomeMember(**data.data[0])
async def get_member(self, discord_user_id: int) -> Optional[HomeMember]:
"""Lấy thông tin thành viên theo discord_user_id"""
data = await self.db.table("home_members").select("*").eq("discord_user_id", discord_user_id).execute()
if not data.data:
return None
return HomeMember(**data.data[0])
async def get_all_members(self) -> List[HomeMember]:
"""Lấy danh sách tất cả thành viên"""
data = await self.db.table("home_members").select("*").execute()
return [HomeMember(**member) for member in data.data]
async def add_expense(self, amount: float, description: str, paid_by: int) -> Expense:
"""Thêm khoản chi tiêu mới"""
# Tạo expense
expense_data = await self.db.table("expenses").insert({
"amount": amount,
"description": description,
"paid_by": paid_by
}).execute()
expense = Expense(**expense_data.data[0])
# Lấy danh sách thành viên
members = await self.get_all_members()
share_amount = amount / len(members)
# Tạo expense shares cho từng thành viên
for member in members:
await self.db.table("expense_shares").insert({
"expense_id": expense.id,
"member_id": member.discord_user_id,
"share_amount": share_amount,
"is_paid": member.discord_user_id == paid_by # Người trả tiền được đánh dấu là đã trả
}).execute()
return expense
async def get_expense(self, expense_id: int) -> Optional[Expense]:
"""Lấy thông tin khoản chi tiêu"""
data = await self.db.table("expenses").select("*").eq("id", expense_id).execute()
if not data.data:
return None
return Expense(**data.data[0])
async def get_all_expenses(self) -> List[Expense]:
"""Lấy danh sách tất cả khoản chi tiêu"""
data = await self.db.table("expenses").select("*").order("created_at", desc=True).execute()
return [Expense(**expense) for expense in data.data]
async def get_expense_shares(self, expense_id: int) -> List[ExpenseShare]:
"""Lấy danh sách chia tiền của một khoản chi tiêu"""
data = await self.db.table("expense_shares").select("*").eq("expense_id", expense_id).execute()
return [ExpenseShare(**share) for share in data.data]
async def mark_share_as_paid(self, share_id: int) -> Optional[ExpenseShare]:
"""Đánh dấu một phần chia tiền đã được trả"""
data = await self.db.table("expense_shares").update({
"is_paid": True
}).eq("id", share_id).execute()
if not data.data:
return None
return ExpenseShare(**data.data[0])
async def get_member_balance(self, discord_user_id: int) -> float:
"""Tính số dư của một thành viên (số tiền phải trả - số tiền đã trả)"""
# Lấy tất cả expense shares của thành viên
data = await self.db.table("expense_shares").select("*").eq("member_id", discord_user_id).execute()
shares = [ExpenseShare(**share) for share in data.data]
# Tính tổng số tiền phải trả
total_owed = sum(share.share_amount for share in shares)
# Tính tổng số tiền đã trả
total_paid = sum(share.share_amount for share in shares if share.is_paid)
return total_owed - total_paid
+39
View File
@@ -0,0 +1,39 @@
from typing import Optional
from models.server import DiscordServer
from infra.db import postgres
class ServerRepository:
def __init__(self):
self.table = postgres.get_table('discord_server')
async def get_server(self, server_id: int) -> Optional[DiscordServer]:
"""Get Discord server by ID"""
try:
response = self.table.select('*').eq('server_id', server_id).execute()
if response.data:
return DiscordServer(**response.data[0])
return None
except Exception as e:
print(f"Error getting server: {e}")
return None
async def create_server(self, server_id: int, name: str) -> Optional[DiscordServer]:
"""Create new Discord server"""
try:
server = DiscordServer(server_id=server_id, name=name)
response = self.table.insert(server.dict(exclude_none=True)).execute()
return DiscordServer(**response.data[0])
except Exception as e:
print(f"Error creating server: {e}")
return None
async def update_server(self, server_id: int, name: str) -> Optional[DiscordServer]:
"""Update Discord server"""
try:
response = self.table.update({'name': name}).eq('server_id', server_id).execute()
if response.data:
return DiscordServer(**response.data[0])
return None
except Exception as e:
print(f"Error updating server: {e}")
return None
+47
View File
@@ -0,0 +1,47 @@
from typing import Optional
from infra.db import postgres
class UserRepository:
def __init__(self):
self.exp_table = postgres.get_table('user_exp')
self.voice_table = postgres.get_table('voice_time')
async def get_exp(self, user_id: int) -> int:
"""Get user's experience points from database"""
try:
response = self.exp_table.select('exp_points').eq('user_id', user_id).execute()
if response.data:
return response.data[0]['exp_points']
return 0
except Exception as e:
print(f"Error getting user exp: {e}")
return 0
async def update_exp(self, user_id: int, exp_points: int) -> bool:
"""Update user's experience points in database"""
try:
response = self.exp_table.upsert({'user_id': user_id, 'exp_points': exp_points}).execute()
return len(response.data) > 0
except Exception as e:
print(f"Error updating user exp: {e}")
return False
async def get_voice_time(self, user_id: int) -> Optional[str]:
"""Get user's voice time from database"""
try:
response = self.voice_table.select('last_join_time').eq('user_id', user_id).execute()
if response.data:
return response.data[0]['last_join_time']
return None
except Exception as e:
print(f"Error getting user voice time: {e}")
return None
async def update_voice_time(self, user_id: int, join_time: str) -> bool:
"""Update user's voice time in database"""
try:
response = self.voice_table.upsert({'user_id': user_id, 'last_join_time': join_time}).execute()
return len(response.data) > 0
except Exception as e:
print(f"Error updating user voice time: {e}")
return False