zy-b / module_admin /controller /designer_controller.py
spongyicybulk's picture
Deploy zy-b backend (internal pg/redis)
085f503 verified
Raw
History Blame Contribute Delete
23.5 kB
from datetime import datetime
from typing import Annotated
from fastapi import File, Form, Path, Query, Request, Response, UploadFile
from pydantic_validation_decorator import ValidateFields
from sqlalchemy.ext.asyncio import AsyncSession
from common.annotation.log_annotation import Log
from common.aspect.db_seesion import DBSessionDependency
from common.aspect.interface_auth import UserInterfaceAuthDependency
from common.aspect.pre_auth import CurrentUserDependency, PreAuthDependency
from common.enums import BusinessType
from common.router import APIRouterPro
from common.vo import DataResponseModel, PageResponseModel, ResponseBaseModel
from exceptions.exception import ServiceException
from module_admin.entity.vo.designer_vo import (
DeleteDesignerProfileModel,
DeleteDesignerCategoryModel,
DeleteDesignerWorkModel,
DesignerCategoryModel,
DesignerCategoryPageQueryModel,
DesignerProfileModel,
DesignerProfilePageQueryModel,
DesignerWorkModel,
DesignerWorkPageQueryModel,
)
from module_admin.entity.vo.common_vo import UploadResponseModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.hf_upload_service import HfUploadService
from module_admin.service.designer_service import DesignerCategoryService, DesignerProfileService, DesignerWorkService
from utils.storage_runtime_util import request_backup_sync
from utils.log_util import logger
from utils.response_util import ResponseUtil
designer_controller = APIRouterPro(
prefix='/designer', order_num=20, tags=['设计师管理'], dependencies=[PreAuthDependency()]
)
DESIGNER_ROLE_KEY = 'designer'
def _is_designer_user(current_user: CurrentUserModel) -> bool:
return bool(current_user and DESIGNER_ROLE_KEY in (current_user.roles or []) and not current_user.user.admin)
async def _get_current_designer_profile(query_db: AsyncSession, current_user: CurrentUserModel) -> DesignerProfileModel:
profile = await DesignerProfileService.get_profile_by_user_services(query_db, current_user.user.user_id)
if not profile.profile_id:
raise ServiceException(message='当前账号尚未完成设计师入驻')
return profile
async def _ensure_category_access(query_db: AsyncSession, category_id: int | None, profile_id: int | None = None) -> None:
if not category_id:
return
category = await DesignerCategoryService.category_detail_services(query_db, category_id)
if not category.category_id:
raise ServiceException(message='分类不存在')
if profile_id is not None and category.profile_id != profile_id:
raise ServiceException(message='无权操作该分类')
async def _ensure_work_access(query_db: AsyncSession, work_id: int, profile_id: int | None = None) -> DesignerWorkModel:
work = await DesignerWorkService.work_detail_services(query_db, work_id)
if not work.work_id:
raise ServiceException(message='作品不存在')
if profile_id is not None and work.profile_id != profile_id:
raise ServiceException(message='只能操作自己的作品')
return work
# ======================== 作品管理 ========================
@designer_controller.get(
'/work/list',
summary='获取设计师作品分页列表接口',
description='用于获取设计师作品分页列表',
response_model=PageResponseModel[DesignerWorkModel],
dependencies=[UserInterfaceAuthDependency('designer:work:list')],
)
async def get_designer_work_list(
request: Request,
work_page_query: Annotated[DesignerWorkPageQueryModel, Query()],
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
work_page_query.profile_id = current_profile.profile_id
work_page_query_result = await DesignerWorkService.get_work_list_services(query_db, work_page_query, is_page=True)
logger.info('获取成功')
return ResponseUtil.success(model_content=work_page_query_result)
@designer_controller.post(
'/work',
summary='新增设计师作品接口',
description='用于新增设计师作品',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('designer:work:add')],
)
@ValidateFields(validate_model='add_work')
@Log(title='设计师作品', business_type=BusinessType.INSERT)
async def add_designer_work(
request: Request,
add_work: DesignerWorkModel,
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
add_work.profile_id = current_profile.profile_id
await _ensure_category_access(query_db, add_work.category_id, add_work.profile_id)
add_work.create_by = current_user.user.user_name
add_work.create_time = datetime.now()
add_work.update_by = current_user.user.user_name
add_work.update_time = datetime.now()
add_work_result = await DesignerWorkService.add_work_services(query_db, add_work)
request_backup_sync('postgres')
logger.info(add_work_result.message)
return ResponseUtil.success(msg=add_work_result.message)
@designer_controller.put(
'/work',
summary='编辑设计师作品接口',
description='用于编辑设计师作品',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('designer:work:edit')],
)
@ValidateFields(validate_model='edit_work')
@Log(title='设计师作品', business_type=BusinessType.UPDATE)
async def edit_designer_work(
request: Request,
edit_work: DesignerWorkModel,
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
if edit_work.work_id:
await _ensure_work_access(query_db, edit_work.work_id, current_profile.profile_id)
edit_work.profile_id = current_profile.profile_id
await _ensure_category_access(query_db, edit_work.category_id, edit_work.profile_id)
edit_work.update_by = current_user.user.user_name
edit_work.update_time = datetime.now()
edit_work_result = await DesignerWorkService.edit_work_services(query_db, edit_work)
request_backup_sync('postgres')
logger.info(edit_work_result.message)
return ResponseUtil.success(msg=edit_work_result.message)
@designer_controller.delete(
'/work/{work_ids}',
summary='删除设计师作品接口',
description='用于删除设计师作品',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('designer:work:remove')],
)
@Log(title='设计师作品', business_type=BusinessType.DELETE)
async def delete_designer_work(
request: Request,
work_ids: Annotated[str, Path(description='需要删除的作品ID')],
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
for work_id in work_ids.split(','):
await _ensure_work_access(query_db, int(work_id), current_profile.profile_id)
delete_work = DeleteDesignerWorkModel(workIds=work_ids)
delete_work_result = await DesignerWorkService.delete_work_services(query_db, delete_work)
request_backup_sync('postgres')
logger.info(delete_work_result.message)
return ResponseUtil.success(msg=delete_work_result.message)
@designer_controller.get(
'/work/{work_id}',
summary='获取设计师作品详情接口',
description='用于获取指定设计师作品的详细信息',
response_model=DataResponseModel[DesignerWorkModel],
dependencies=[UserInterfaceAuthDependency('designer:work:query')],
)
async def query_detail_designer_work(
request: Request,
work_id: Annotated[int, Path(description='作品ID')],
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
await _ensure_work_access(query_db, work_id, current_profile.profile_id)
work_detail_result = await DesignerWorkService.work_detail_services(query_db, work_id)
logger.info(f'获取work_id为{work_id}的信息成功')
return ResponseUtil.success(data=work_detail_result)
# ======================== 分类管理 ========================
@designer_controller.get(
'/category/list',
summary='获取设计师作品分类分页列表接口',
description='用于获取设计师作品分类分页列表',
response_model=PageResponseModel[DesignerCategoryModel],
dependencies=[UserInterfaceAuthDependency('designer:category:list')],
)
async def get_designer_category_list(
request: Request,
category_page_query: Annotated[DesignerCategoryPageQueryModel, Query()],
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
category_page_query.profile_id = current_profile.profile_id
category_page_query_result = await DesignerCategoryService.get_category_list_services(
query_db, category_page_query, is_page=True
)
logger.info('获取成功')
return ResponseUtil.success(model_content=category_page_query_result)
@designer_controller.post(
'/category',
summary='新增设计师作品分类接口',
description='用于新增设计师作品分类',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('designer:category:add')],
)
@ValidateFields(validate_model='add_category')
@Log(title='设计师作品分类', business_type=BusinessType.INSERT)
async def add_designer_category(
request: Request,
add_category: DesignerCategoryModel,
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
add_category.profile_id = current_profile.profile_id
add_category.create_by = current_user.user.user_name
add_category.create_time = datetime.now()
add_category.update_by = current_user.user.user_name
add_category.update_time = datetime.now()
add_category_result = await DesignerCategoryService.add_category_services(query_db, add_category)
request_backup_sync('postgres')
logger.info(add_category_result.message)
return ResponseUtil.success(msg=add_category_result.message)
@designer_controller.put(
'/category',
summary='编辑设计师作品分类接口',
description='用于编辑设计师作品分类',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('designer:category:edit')],
)
@ValidateFields(validate_model='edit_category')
@Log(title='设计师作品分类', business_type=BusinessType.UPDATE)
async def edit_designer_category(
request: Request,
edit_category: DesignerCategoryModel,
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
if edit_category.category_id:
await _ensure_category_access(query_db, edit_category.category_id, current_profile.profile_id)
edit_category.profile_id = current_profile.profile_id
edit_category.update_by = current_user.user.user_name
edit_category.update_time = datetime.now()
edit_category_result = await DesignerCategoryService.edit_category_services(query_db, edit_category)
request_backup_sync('postgres')
logger.info(edit_category_result.message)
return ResponseUtil.success(msg=edit_category_result.message)
@designer_controller.delete(
'/category/{category_ids}',
summary='删除设计师作品分类接口',
description='用于删除设计师作品分类',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('designer:category:remove')],
)
@Log(title='设计师作品分类', business_type=BusinessType.DELETE)
async def delete_designer_category(
request: Request,
category_ids: Annotated[str, Path(description='需要删除的分类ID')],
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
for category_id in category_ids.split(','):
await _ensure_category_access(query_db, int(category_id), current_profile.profile_id)
delete_category = DeleteDesignerCategoryModel(categoryIds=category_ids)
delete_category_result = await DesignerCategoryService.delete_category_services(query_db, delete_category)
request_backup_sync('postgres')
logger.info(delete_category_result.message)
return ResponseUtil.success(msg=delete_category_result.message)
@designer_controller.get(
'/category/{category_id}',
summary='获取设计师作品分类详情接口',
description='用于获取指定设计师作品分类的详细信息',
response_model=DataResponseModel[DesignerCategoryModel],
dependencies=[UserInterfaceAuthDependency('designer:category:query')],
)
async def query_detail_designer_category(
request: Request,
category_id: Annotated[int, Path(description='分类ID')],
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
await _ensure_category_access(query_db, category_id, current_profile.profile_id)
category_detail_result = await DesignerCategoryService.category_detail_services(query_db, category_id)
logger.info(f'获取category_id为{category_id}的信息成功')
return ResponseUtil.success(data=category_detail_result)
# ======================== 档案管理 ========================
@designer_controller.get(
'/profile/list',
summary='获取设计师档案分页列表接口',
description='用于获取设计师档案分页列表',
response_model=PageResponseModel[DesignerProfileModel],
dependencies=[UserInterfaceAuthDependency('designer:profile:list')],
)
async def get_designer_profile_list(
request: Request,
profile_page_query: Annotated[DesignerProfilePageQueryModel, Query()],
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
profile_page_query.user_id = current_user.user.user_id
profile_page_query_result = await DesignerProfileService.get_profile_list_services(
query_db, profile_page_query, is_page=True
)
logger.info('获取设计师档案列表成功')
return ResponseUtil.success(model_content=profile_page_query_result)
@designer_controller.get(
'/profile',
summary='获取当前用户设计师档案接口',
description='用于获取当前登录用户的设计师档案',
response_model=DataResponseModel[DesignerProfileModel],
dependencies=[UserInterfaceAuthDependency('designer:profile:query')],
)
async def get_designer_profile(
request: Request,
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
profile_result = await DesignerProfileService.get_profile_by_user_services(query_db, current_user.user.user_id)
logger.info('获取设计师档案成功')
return ResponseUtil.success(data=profile_result)
@designer_controller.get(
'/profile/{profile_id}',
summary='获取设计师档案详情接口',
description='用于获取指定设计师档案信息',
response_model=DataResponseModel[DesignerProfileModel],
dependencies=[UserInterfaceAuthDependency('designer:profile:query')],
)
async def query_detail_designer_profile(
request: Request,
profile_id: Annotated[int, Path(description='档案ID')],
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
if current_profile.profile_id != profile_id:
raise ServiceException(message='只能查看自己的设计师档案')
profile_result = await DesignerProfileService.get_profile_services(query_db, profile_id)
logger.info(f'获取profile_id为{profile_id}的设计师档案成功')
return ResponseUtil.success(data=profile_result)
@designer_controller.post(
'/profile',
summary='新增设计师档案接口',
description='用于新增设计师档案',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('designer:profile:add')],
)
@ValidateFields(validate_model='add_profile')
@Log(title='设计师档案', business_type=BusinessType.INSERT)
async def add_designer_profile(
request: Request,
add_profile: DesignerProfileModel,
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
add_profile.user_id = current_user.user.user_id
add_profile.create_by = current_user.user.user_name
add_profile.create_time = datetime.now()
add_profile.update_by = current_user.user.user_name
add_profile.update_time = datetime.now()
add_profile_result = await DesignerProfileService.add_profile_services(query_db, add_profile)
request_backup_sync('postgres')
logger.info(add_profile_result.message)
return ResponseUtil.success(msg=add_profile_result.message)
@designer_controller.put(
'/profile',
summary='编辑设计师档案接口',
description='用于编辑设计师档案',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('designer:profile:edit')],
)
@ValidateFields(validate_model='edit_profile')
@Log(title='设计师档案', business_type=BusinessType.UPDATE)
async def edit_designer_profile(
request: Request,
edit_profile: DesignerProfileModel,
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
if edit_profile.profile_id and edit_profile.profile_id != current_profile.profile_id:
raise ServiceException(message='只能修改自己的设计师档案')
edit_profile.profile_id = current_profile.profile_id
edit_profile.user_id = current_user.user.user_id
elif not edit_profile.profile_id and edit_profile.user_id is None:
edit_profile.user_id = current_user.user.user_id
edit_profile.update_by = current_user.user.user_name
edit_profile.update_time = datetime.now()
edit_profile_result = await DesignerProfileService.edit_profile_services(query_db, edit_profile)
request_backup_sync('postgres')
logger.info(edit_profile_result.message)
return ResponseUtil.success(msg=edit_profile_result.message)
@designer_controller.delete(
'/profile/{profile_ids}',
summary='删除设计师档案接口',
description='用于删除设计师档案及其关联作品/分类',
response_model=ResponseBaseModel,
dependencies=[UserInterfaceAuthDependency('designer:profile:remove')],
)
@Log(title='设计师档案', business_type=BusinessType.DELETE)
async def delete_designer_profile(
request: Request,
profile_ids: Annotated[str, Path(description='需要删除的档案ID')],
query_db: Annotated[AsyncSession, DBSessionDependency()],
current_user: Annotated[CurrentUserModel, CurrentUserDependency()],
) -> Response:
if _is_designer_user(current_user):
current_profile = await _get_current_designer_profile(query_db, current_user)
requested_profile_ids = [int(profile_id) for profile_id in profile_ids.split(',') if profile_id]
if requested_profile_ids != [current_profile.profile_id]:
raise ServiceException(message='只能删除自己的设计师档案')
delete_profile = DeleteDesignerProfileModel(profileIds=profile_ids)
delete_profile_result = await DesignerProfileService.delete_profile_services(query_db, delete_profile)
request_backup_sync('postgres')
logger.info(delete_profile_result.message)
return ResponseUtil.success(msg=delete_profile_result.message)
@designer_controller.post(
'/upload',
summary='设计师图片上传接口',
description='上传图片到 Hugging Face 文件服务',
response_model=DataResponseModel[UploadResponseModel],
)
async def upload_designer_image(
request: Request,
file: Annotated[UploadFile, File(description='图片文件')],
folder_query: Annotated[str | None, Query(alias='folder', description='上传目录(works/avatar/banner/category)')] = None,
folder: Annotated[str | None, Form(alias='folder', description='上传目录(works/avatar/banner/category)')] = None,
) -> Response:
upload_folder = folder or folder_query or 'works'
upload_result = await HfUploadService.upload_image(file, folder=upload_folder)
logger.info('设计师图片上传成功')
return ResponseUtil.success(model_content=upload_result.result)
@designer_controller.delete(
'/file/{file_id}',
summary='设计师图片删除接口',
description='删除 Hugging Face 文件服务中的设计师图片',
response_model=ResponseBaseModel,
)
async def delete_designer_image(
request: Request,
file_id: Annotated[str, Path(description='文件ID')],
) -> Response:
delete_result = await HfUploadService.delete_file(file_id)
logger.info(f'设计师图片删除成功: {file_id}')
return ResponseUtil.success(msg=delete_result.message)