feat: initialize aivideo project
This commit is contained in:
25
backend/app/modules/system/repository.py
Normal file
25
backend/app/modules/system/repository.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.entities import CallbackLog, RedeemCode, SystemConfig
|
||||
|
||||
|
||||
class SystemRepository:
|
||||
def __init__(self, db: Session) -> None:
|
||||
self.db = db
|
||||
|
||||
def list_configs(self):
|
||||
return self.db.query(SystemConfig).order_by(SystemConfig.group_name.asc(), SystemConfig.id.asc())
|
||||
|
||||
def get_config(self, config_key: str) -> SystemConfig | None:
|
||||
return self.db.scalar(select(SystemConfig).where(SystemConfig.config_key == config_key))
|
||||
|
||||
def list_redeem_codes(self):
|
||||
return self.db.query(RedeemCode).order_by(RedeemCode.id.desc())
|
||||
|
||||
def get_redeem_code(self, redeem_id: int) -> RedeemCode | None:
|
||||
return self.db.scalar(select(RedeemCode).where(RedeemCode.id == redeem_id))
|
||||
|
||||
def list_callback_logs(self):
|
||||
return self.db.query(CallbackLog).order_by(CallbackLog.id.desc())
|
||||
|
||||
72
backend/app/modules/system/router.py
Normal file
72
backend/app/modules/system/router.py
Normal file
@@ -0,0 +1,72 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.common.db.session import get_db
|
||||
from app.common.responses.api_response import success_response
|
||||
from app.common.security.deps import require_admin_permission
|
||||
from app.modules.system.schema import RedeemBatchCreatePayload, SystemConfigItemPayload
|
||||
from app.modules.system.service import SystemService
|
||||
|
||||
|
||||
router = APIRouter(prefix="/api/v1/admin", tags=["admin-system"])
|
||||
|
||||
|
||||
@router.get("/system-config")
|
||||
def list_system_configs(
|
||||
_=Depends(require_admin_permission()),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(SystemService(db).list_configs())
|
||||
|
||||
|
||||
@router.put("/system-config")
|
||||
def upsert_system_config(
|
||||
payload: SystemConfigItemPayload,
|
||||
_=Depends(require_admin_permission()),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(SystemService(db).upsert_config(payload))
|
||||
|
||||
|
||||
@router.get("/redeem-codes")
|
||||
def list_redeem_codes(
|
||||
_=Depends(require_admin_permission()),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(SystemService(db).list_redeem_codes())
|
||||
|
||||
|
||||
@router.post("/redeem-codes/batch-create")
|
||||
def batch_create_redeem_codes(
|
||||
payload: RedeemBatchCreatePayload,
|
||||
_=Depends(require_admin_permission()),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(SystemService(db).batch_create_redeem_codes(payload))
|
||||
|
||||
|
||||
@router.post("/redeem-codes/import")
|
||||
def import_redeem_codes(
|
||||
payload: RedeemBatchCreatePayload,
|
||||
_=Depends(require_admin_permission()),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(SystemService(db).batch_create_redeem_codes(payload))
|
||||
|
||||
|
||||
@router.put("/redeem-codes/{redeem_id}/disable")
|
||||
def disable_redeem_code(
|
||||
redeem_id: int,
|
||||
_=Depends(require_admin_permission()),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(SystemService(db).disable_redeem_code(redeem_id))
|
||||
|
||||
|
||||
@router.get("/callback-logs")
|
||||
def list_callback_logs(
|
||||
_=Depends(require_admin_permission()),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
return success_response(SystemService(db).list_callback_logs())
|
||||
|
||||
18
backend/app/modules/system/schema.py
Normal file
18
backend/app/modules/system/schema.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class SystemConfigItemPayload(BaseModel):
|
||||
config_key: str
|
||||
config_value: str
|
||||
value_type: str = "string"
|
||||
group_name: str = "default"
|
||||
description: str = ""
|
||||
is_public: bool = False
|
||||
|
||||
|
||||
class RedeemBatchCreatePayload(BaseModel):
|
||||
batch_no: str
|
||||
points: int
|
||||
quantity: int
|
||||
remark: str = ""
|
||||
|
||||
94
backend/app/modules/system/service.py
Normal file
94
backend/app/modules/system/service.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from app.common.errors.app_error import NotFoundAppError
|
||||
from app.common.utils.id_gen import new_invite_code
|
||||
from app.models.entities import RedeemCode, SystemConfig
|
||||
from app.modules.system.repository import SystemRepository
|
||||
|
||||
|
||||
class SystemService:
|
||||
def __init__(self, db) -> None:
|
||||
self.db = db
|
||||
self.repository = SystemRepository(db)
|
||||
|
||||
def list_configs(self) -> list[dict]:
|
||||
return [
|
||||
{
|
||||
"configKey": item.config_key,
|
||||
"configValue": item.config_value,
|
||||
"valueType": item.value_type,
|
||||
"groupName": item.group_name,
|
||||
"description": item.description,
|
||||
"isPublic": item.is_public,
|
||||
}
|
||||
for item in self.repository.list_configs().all()
|
||||
]
|
||||
|
||||
def upsert_config(self, payload) -> dict:
|
||||
item = self.repository.get_config(payload.config_key)
|
||||
if not item:
|
||||
item = SystemConfig(**payload.model_dump())
|
||||
self.db.add(item)
|
||||
else:
|
||||
for key, value in payload.model_dump().items():
|
||||
setattr(item, key, value)
|
||||
self.db.commit()
|
||||
return {
|
||||
"configKey": item.config_key,
|
||||
"configValue": item.config_value,
|
||||
"groupName": item.group_name,
|
||||
}
|
||||
|
||||
def list_redeem_codes(self) -> list[dict]:
|
||||
return [
|
||||
{
|
||||
"id": item.id,
|
||||
"batchNo": item.batch_no,
|
||||
"redeemCode": item.redeem_code,
|
||||
"points": item.points,
|
||||
"status": item.status,
|
||||
"usedByUserId": item.used_by_user_id,
|
||||
"usedAt": item.used_at.isoformat() if item.used_at else None,
|
||||
}
|
||||
for item in self.repository.list_redeem_codes().all()
|
||||
]
|
||||
|
||||
def batch_create_redeem_codes(self, payload) -> list[dict]:
|
||||
created = []
|
||||
for _ in range(payload.quantity):
|
||||
item = RedeemCode(
|
||||
batch_no=payload.batch_no,
|
||||
redeem_code=f"{payload.batch_no}-{new_invite_code(4)}-{new_invite_code(4)}",
|
||||
points=payload.points,
|
||||
status="unused",
|
||||
remark=payload.remark,
|
||||
)
|
||||
self.db.add(item)
|
||||
created.append(item)
|
||||
self.db.commit()
|
||||
return self.list_redeem_codes()[: payload.quantity]
|
||||
|
||||
def disable_redeem_code(self, redeem_id: int) -> dict:
|
||||
item = self.repository.get_redeem_code(redeem_id)
|
||||
if not item:
|
||||
raise NotFoundAppError("redeem code not found", code=70020)
|
||||
item.status = "disabled"
|
||||
self.db.commit()
|
||||
return {
|
||||
"id": item.id,
|
||||
"status": item.status,
|
||||
}
|
||||
|
||||
def list_callback_logs(self) -> list[dict]:
|
||||
return [
|
||||
{
|
||||
"id": item.id,
|
||||
"sourceType": item.source_type,
|
||||
"sourceCode": item.source_code,
|
||||
"relatedNo": item.related_no,
|
||||
"verifyStatus": item.verify_status,
|
||||
"processStatus": item.process_status,
|
||||
"errorMessage": item.error_message,
|
||||
"createdAt": item.created_at.isoformat(),
|
||||
}
|
||||
for item in self.repository.list_callback_logs().all()
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user