feat(system): add Excel export for dept and menu tree lists

Export flattened filtered or selected rows via backend xlsx and ListExportDropdown.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-08-21 17:31:10 +08:00
1 parent b3b6ec187a
commit ee56dad875
4 files changed
+170 -1

No files matched your search

+106
View File
@@ -987,6 +987,52 @@ def list_depts(
return success_response(tree)
DEPT_EXPORT_COLUMNS = [
ExportColumn(title="组织名称", field="deptName"),
ExportColumn(title="组织类别", field="deptCategoryCode"),
ExportColumn(title="状态", field="status", dict_type="sys_status"),
ExportColumn(title="负责人", field="leader"),
ExportColumn(title="联系电话", field="leaderPhone"),
ExportColumn(title="创建时间", field="createTime"),
]
class DeptExportBody(BaseModel):
keyword: Optional[str] = None
ids: Optional[List[str]] = None
columns: Optional[List[str]] = None
@router.post("/depts/export")
def export_depts(
body: DeptExportBody,
user: dict = Depends(require_menu_code("system:dept:list")),
db: Session = Depends(get_db),
):
"""导出组织列表(扁平行;当前筛选或已选)。"""
try:
tenant_no = _get_tenant_no(db, user)
rows = dept_svc.list_depts(db, keyword=body.keyword, tenant_no=tenant_no, user_info=user)
if body.ids:
idset = set(body.ids)
rows = [r for r in rows if r.get("id") in idset]
cols = filter_export_columns(DEPT_EXPORT_COLUMNS, body.columns)
date_str = datetime.now().strftime("%Y%m%d")
return export_rows_to_xlsx_response(
db,
tenant_no=tenant_no,
sheet_title="组织列表",
columns=cols,
rows=rows,
filename_stem=f"组织列表_{date_str}",
)
except ExportValidationError as e:
return error_response(400, str(e))
except Exception as e:
return error_response(500, str(e))
@router.post("/depts")
def create_dept(
body: DeptCreateBody,
@@ -1462,6 +1508,66 @@ def list_menus(
return success_response(tree)
MENU_EXPORT_COLUMNS = [
ExportColumn(title="菜单名称", field="menuName"),
ExportColumn(title="菜单类型", field="menuType"),
ExportColumn(title="路由", field="path"),
ExportColumn(title="组件", field="component"),
ExportColumn(title="权限标识", field="perms"),
ExportColumn(title="状态", field="status", dict_type="sys_status"),
ExportColumn(title="可见", field="visible"),
ExportColumn(title="创建时间", field="createTime"),
]
class MenuExportBody(BaseModel):
keyword: Optional[str] = None
ids: Optional[List[str]] = None
columns: Optional[List[str]] = None
@router.post("/menus/export")
def export_menus(
body: MenuExportBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
"""导出菜单列表(扁平行;当前筛选或已选)。"""
try:
tenant_no = _get_tenant_no(db, user)
# list flat via tree then flatten, or use underlying list if exists
from app.crud import menu as menu_mod
if hasattr(menu_mod, 'list_menus'):
rows = menu_mod.list_menus(db, keyword=body.keyword, tenant_no=tenant_no, user_info=user)
else:
tree = menu_svc.list_menus_tree(db, keyword=body.keyword, tenant_no=tenant_no, user_info=user)
rows = []
def walk(nodes):
for n in nodes or []:
item = {k: v for k, v in n.items() if k != 'children'}
rows.append(item)
walk(n.get('children') or [])
walk(tree)
if body.ids:
idset = set(body.ids)
rows = [r for r in rows if r.get("id") in idset]
cols = filter_export_columns(MENU_EXPORT_COLUMNS, body.columns)
date_str = datetime.now().strftime("%Y%m%d")
return export_rows_to_xlsx_response(
db,
tenant_no=tenant_no,
sheet_title="菜单列表",
columns=cols,
rows=rows,
filename_stem=f"菜单列表_{date_str}",
)
except ExportValidationError as e:
return error_response(400, str(e))
except Exception as e:
return error_response(500, str(e))
@router.post("/menus")
def create_menu(
body: MenuCreateBody,