Files

110 lines
3.6 KiB
Python

from io import BytesIO
from typing import Tuple, Dict, Any, Optional
from sqlalchemy.ext.asyncio import AsyncSession
from app.base_service import BaseService
from app.field_metadata_generator import generate_field_metadata_from_schema
from zq_demo.model import Demo
from zq_demo.schema import DemoCreate, DemoUpdate, DemoResponse
class DemoService(BaseService[Demo, DemoCreate, DemoUpdate]):
"""
Demo服务层 - 演示数据权限和字段权限
功能:
1. 数据权限(行权限):根据用户角色过滤数据
- 使用 get_list_with_data_scope() 自动应用数据权限
- 支持本人、本部门、本部门及下级、全部等数据范围
2. 字段权限(列权限):根据角色配置隐藏/脱敏字段
- 使用 apply_field_permissions_auto() 自动应用字段权限
- 必填字段(id、title、status)不可隐藏
- 可选字段(content、priority等)可以隐藏
3. Excel导入导出:支持带数据权限的导出
- 使用 export_to_excel_with_data_scope() 导出
"""
model = Demo
# 资源显示名称(用于前端显示)
RESOURCE_DISPLAY_NAME = "Demo示例"
# 从 Response Schema 生成字段元数据
# 必填字段会被标记为 required=True,前端禁止隐藏
FIELD_METADATA = generate_field_metadata_from_schema(DemoResponse, Demo)
# Excel导入导出配置
excel_columns = {
"title": "标题",
"content": "内容",
"status": "状态",
"priority": "优先级",
"is_active": "是否激活",
}
excel_sheet_name = "Demo列表"
@classmethod
def _export_converter(cls, item: Any) -> Dict[str, Any]:
"""导出数据转换器"""
status_map = {0: "草稿", 1: "发布", 2: "归档"}
priority_map = {0: "", 1: "", 2: ""}
return {
"title": item.title,
"content": item.content or "",
"status": status_map.get(item.status, "未知"),
"priority": priority_map.get(item.priority, "未知"),
"is_active": "" if item.is_active else "",
}
@classmethod
def _import_processor(cls, row: Dict[str, Any]) -> Optional[Demo]:
"""导入数据处理器"""
title = row.get("title")
if not title:
return None
# 状态转换
status_str = row.get("status", "发布")
status_map = {"草稿": 0, "发布": 1, "归档": 2}
status = status_map.get(status_str, 1)
# 优先级转换
priority_str = row.get("priority", "")
priority_map = {"": 0, "": 1, "": 2}
priority = priority_map.get(priority_str, 0)
# 是否激活转换
is_active_str = row.get("is_active", "")
is_active = is_active_str in ("", "true", "True", "1", True)
return Demo(
title=str(title),
content=str(row.get("content") or ""),
status=status,
priority=priority,
is_active=is_active
)
@classmethod
async def export_to_excel(
cls,
db: AsyncSession,
data_converter: Any = None
) -> BytesIO:
"""导出所有Demo到Excel"""
return await super().export_to_excel(db, cls._export_converter)
@classmethod
async def import_from_excel(
cls,
db: AsyncSession,
file_content: bytes,
row_processor: Any = None
) -> Tuple[int, int]:
"""从Excel导入Demo"""
return await super().import_from_excel(db, file_content, cls._import_processor)