__init__.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. from fastapi import APIRouter, Request, Depends, Query, HTTPException, status
  4. from pydantic import BaseModel
  5. from database import get_db
  6. from sqlalchemy.orm import Session
  7. from typing import List
  8. from models import *
  9. import json
  10. from sqlalchemy.sql import func
  11. from common.auth_user import *
  12. router = APIRouter()
  13. # 定义 Meta 和 Child 模型用于嵌套结构
  14. class Meta(BaseModel):
  15. title: str
  16. icon: str
  17. noCache: bool
  18. link: str = None
  19. class Child(BaseModel):
  20. name: str
  21. path: str
  22. hidden: bool
  23. component: str
  24. meta: Meta
  25. children: List['Child'] = []
  26. class Router(BaseModel):
  27. name: str
  28. path: str
  29. hidden: bool
  30. redirect: str = 'noRedirect'
  31. component: str
  32. alwaysShow: bool = True
  33. meta: Meta
  34. children: List[Child] = []
  35. class Router_frame(BaseModel):
  36. component:str
  37. hidden: bool
  38. meta:Meta
  39. name: str
  40. path: str
  41. redirect: str = 'noRedirect'
  42. children: List[Child] = []
  43. alwaysShow: bool = True
  44. @router.get('/getRouters')
  45. async def getRouters(request: Request, db: Session = Depends(get_db), user: AuthUser = Depends(get_auth_user)):
  46. try:
  47. # 查询数据库中的所有菜单项,根据 parent_id 排序以构建树形结构
  48. query = db.query(SysMenu)
  49. query = query.filter_by(parent_id=0)
  50. query = query.filter(SysMenu.menu_id!=11655)
  51. query = query.filter(SysMenu.del_flag != '2')
  52. menus =query.all() # 顶级菜单
  53. # 递归函数用于构建树形结构
  54. def build_menu_tree(menus, parent_menu):
  55. menu_tree = [] # 初始化一个列表来存储菜单树结构
  56. for menu in menus:
  57. if menu.is_frame==0:
  58. menu_data = Router_frame(
  59. component=menu.component or 'Layout',
  60. hidden=menu.visible == '1',
  61. name=menu.path,
  62. path='/'+menu.path,
  63. meta = Meta(
  64. title=menu.menu_name,
  65. icon=menu.icon,
  66. noCache=menu.is_cache == '1',
  67. link = menu.path
  68. ),
  69. children=[]
  70. )
  71. else:
  72. menu_data = Router(
  73. name=menu.path,#menu.menu_name,
  74. path='/'+menu.path,
  75. hidden=menu.visible == '1',
  76. component=menu.component or 'Layout',
  77. meta=Meta(
  78. title=menu.menu_name,
  79. icon=menu.icon,
  80. noCache=menu.is_cache == '1'
  81. ),
  82. children=[] # 初始化 children 列表,即使没有子菜单
  83. )
  84. # 如果菜单有子菜单,则递归构建子菜单
  85. if menu.menu_type == 'M': # 假设 'M' 表示目录类型
  86. query = db.query(SysMenu)
  87. query = query.filter_by(parent_id=menu.menu_id)
  88. query = query.filter(SysMenu.del_flag != '2')
  89. # children_menus = db.query(SysMenu).filter_by(parent_id=menu.menu_id).all()
  90. children_menus = query.all()
  91. menu_data.children = build_menu_tree(children_menus, menu)
  92. else:
  93. del menu_data.children #没有子菜单,删除children 列表
  94. del menu_data.redirect
  95. del menu_data.alwaysShow
  96. menu_data.path = menu_data.path[1:]
  97. menu_tree.append(menu_data) # 将当前菜单数据添加到菜单树列表
  98. return menu_tree
  99. # 构建顶级菜单的树形结构
  100. routers = build_menu_tree(menus, None)
  101. # routers_dict = [router.dict() for router in routers]
  102. routers_dict = []
  103. for router in routers:
  104. router_info = router.dict()
  105. if len(router_info['children'])==0:
  106. del router_info['children']
  107. del router_info['redirect']
  108. del router_info['alwaysShow']
  109. router_info['path'] = router_info['path'][1:]
  110. routers_dict.append(router_info)
  111. # 返回构建好的路由数据
  112. return {
  113. "code": 200,
  114. "msg": "操作成功",
  115. "data": routers_dict #[router.dict() for router in routers] # 如果没有顶级菜单,返回空列表
  116. }
  117. except Exception as e:
  118. # 处理异常,返回错误信息
  119. raise HTTPException(status_code=500, detail=str(e))
  120. @router.get('/qydt/getRouters')
  121. async def getRouters(request: Request, db: Session = Depends(get_db)):
  122. try:
  123. # 查询数据库中的所有菜单项,根据 parent_id 排序以构建树形结构
  124. query = db.query(SysMenu)
  125. query = query.filter_by(parent_id=0)
  126. query = query.filter(SysMenu.menu_id==11655)
  127. query = query.filter(SysMenu.del_flag != '2')
  128. menus =query.all() # 顶级菜单
  129. # 递归函数用于构建树形结构
  130. def build_menu_tree(menus, parent_menu):
  131. menu_tree = [] # 初始化一个列表来存储菜单树结构
  132. for menu in menus:
  133. if menu.is_frame==0:
  134. menu_data = Router_frame(
  135. component=menu.component or 'Layout',
  136. hidden=menu.visible == '1',
  137. name=menu.path,
  138. path='/'+menu.path,
  139. meta = Meta(
  140. title=menu.menu_name,
  141. icon=menu.icon,
  142. noCache=menu.is_cache == '1',
  143. link = menu.path
  144. ),
  145. children=[]
  146. )
  147. else:
  148. menu_data = Router(
  149. name=menu.path,#menu.menu_name,
  150. path='/'+menu.path,
  151. hidden=menu.visible == '1',
  152. component=menu.component or 'Layout',
  153. meta=Meta(
  154. title=menu.menu_name,
  155. icon=menu.icon,
  156. noCache=menu.is_cache == '1'
  157. ),
  158. children=[] # 初始化 children 列表,即使没有子菜单
  159. )
  160. # 如果菜单有子菜单,则递归构建子菜单
  161. if menu.menu_type == 'M': # 假设 'M' 表示目录类型
  162. query = db.query(SysMenu)
  163. query = query.filter_by(parent_id=menu.menu_id)
  164. query = query.filter(SysMenu.del_flag != '2')
  165. # children_menus = db.query(SysMenu).filter_by(parent_id=menu.menu_id).all()
  166. children_menus = query.all()
  167. menu_data.children = build_menu_tree(children_menus, menu)
  168. else:
  169. del menu_data.children #没有子菜单,删除children 列表
  170. del menu_data.redirect
  171. del menu_data.alwaysShow
  172. menu_data.path = menu_data.path[1:]
  173. menu_tree.append(menu_data) # 将当前菜单数据添加到菜单树列表
  174. return menu_tree
  175. # 构建顶级菜单的树形结构
  176. routers = build_menu_tree(menus, None)
  177. # routers_dict = [router.dict() for router in routers]
  178. routers_dict = []
  179. for router in routers:
  180. router_info = router.dict()
  181. if len(router_info['children'])==0:
  182. del router_info['children']
  183. del router_info['redirect']
  184. del router_info['alwaysShow']
  185. router_info['path'] = router_info['path'][1:]
  186. routers_dict.append(router_info)
  187. # 返回构建好的路由数据
  188. return {
  189. "code": 200,
  190. "msg": "操作成功",
  191. "data": routers_dict #[router.dict() for router in routers] # 如果没有顶级菜单,返回空列表
  192. }
  193. except Exception as e:
  194. # 处理异常,返回错误信息
  195. raise HTTPException(status_code=500, detail=str(e))
  196. @router.get('/list')
  197. async def get_list(
  198. # request: Request,
  199. menuName: str = Query(None, max_length=100),
  200. status: str = Query(None, max_length=100),
  201. db: Session = Depends(get_db),
  202. user: AuthUser = Depends(get_auth_user)
  203. ):
  204. query = db.query(SysMenu)
  205. query = query.filter(SysMenu.del_flag != '2')
  206. if menuName:
  207. query = query.filter(SysMenu.menu_name.like(f'%{menuName}%'))
  208. if status:
  209. query = query.filter(SysMenu.status.like(f'%{status}%'))
  210. # 应用查询
  211. # menu_list = db.query(SysMenu).filter(
  212. # (SysMenu.menu_name.like(f'%{menu_name}%')) ,
  213. # (SysMenu.status.like(f'%{status}%'))
  214. # ).all()
  215. menu_list = query.all()
  216. # 将模型实例转换为字典
  217. menu_list_dict = [{
  218. "menuId": menu.menu_id,
  219. "menuName": menu.menu_name,
  220. "parentId": menu.parent_id,
  221. "orderNum": menu.order_num,
  222. "path": menu.path,
  223. "component": menu.component,
  224. "queryParam": menu.query_param,
  225. "isFrame": str(menu.is_frame),
  226. "isCache": str(menu.is_cache),
  227. "menuType": menu.menu_type,
  228. "visible": menu.visible,
  229. "status": menu.status,
  230. "perms": menu.perms,
  231. "icon": menu.icon,
  232. "createDept": menu.create_dept,
  233. "remark": menu.remark,
  234. "createTime": menu.create_time.strftime('%Y-%m-%d %H:%M:%S') if menu.create_time else '',
  235. "children": [] # 递归调用以获取子菜单
  236. } for menu in menu_list]
  237. # 构建分页响应
  238. # pagination_info = {
  239. # "total": total_count,
  240. # "page_num": page_num,
  241. # "page_size": page_size,
  242. # "total_pages": (total_count + page_size - 1) // page_size # 计算总页数
  243. # }
  244. return {
  245. "code": 200,
  246. "data": menu_list_dict,
  247. # 'pages': page_num, # 总页数
  248. # 'currentPage': page_num, # 当前页数
  249. # # 'current':current,
  250. # # 'total' : total,
  251. # 'total': total_count, # 总数据量
  252. # # 'size':size,
  253. # 'pageSize': page_size, # 页码
  254. # {
  255. # "items": menu_list_dict,
  256. # "pagination": pagination_info
  257. # },
  258. "msg": "操作成功"
  259. }
  260. class SysMuneCreateForm(BaseModel):
  261. component:str = None
  262. icon : str
  263. isCache: str
  264. isFrame:str
  265. menuName: str
  266. menuType:str
  267. orderNum:int
  268. parentId:int
  269. path:str
  270. perms:str=None
  271. queryParam:str=None
  272. status:str
  273. visible:str
  274. @router.post('/create')
  275. async def create(
  276. form_data: SysMuneCreateForm,
  277. db: Session = Depends(get_db)
  278. ):
  279. try:
  280. new_menu = SysMenu(
  281. menu_name = form_data.menuName,
  282. parent_id = form_data.parentId,
  283. order_num = form_data.orderNum,
  284. path = form_data.path,
  285. is_frame = int(form_data.isFrame),
  286. is_cache = int(form_data.isCache),
  287. menu_type = form_data.menuType,
  288. visible = form_data.visible,
  289. status = form_data.status,
  290. icon = form_data.icon,
  291. component= form_data.component,
  292. perms=form_data.perms,
  293. query_param=form_data.queryParam
  294. )
  295. db.add(new_menu)
  296. db.commit()
  297. db.refresh(new_menu)
  298. return {
  299. "code": 200,
  300. "data": None,
  301. "msg": "操作成功"
  302. }
  303. except Exception as e:
  304. db.rollback()
  305. raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
  306. class SysMuneUpdateForm(BaseModel):
  307. menuId : str
  308. component:str = None
  309. icon : str = None
  310. isCache: str = None
  311. isFrame:str = None
  312. menuName: str = None
  313. menuType:str = None
  314. orderNum:int = None
  315. parentId:int = None
  316. path:str = None
  317. perms:str=None
  318. queryParam:str=None
  319. status:str = None
  320. visible:str = None
  321. @router.put('/update')
  322. async def update(
  323. request: Request,
  324. form_data: SysMuneUpdateForm,
  325. db: Session = Depends(get_db)
  326. ):
  327. try:
  328. query = db.query(SysMenu)
  329. query = query.filter(SysMenu.menu_id == form_data.menuId)
  330. query = query.filter(SysMenu.del_flag != '2')
  331. menu = query.first()
  332. if not menu:
  333. detail = "菜单不存在"
  334. raise HTTPException(status_code=404, detail="菜单不存在")
  335. # 更新字段,排除主键和不可更新的字段
  336. if form_data.component:
  337. menu.component=form_data.component
  338. if form_data.icon:
  339. menu.icon=form_data.icon
  340. if form_data.isCache:
  341. menu.is_cache=form_data.isCache
  342. if form_data.isFrame:
  343. menu.is_frame=form_data.isFrame
  344. if form_data.menuName:
  345. menu.menu_name=form_data.menuName
  346. if form_data.menuType:
  347. menu.menu_type=form_data.menuType
  348. if form_data.orderNum:
  349. menu.order_num=form_data.orderNum
  350. if form_data.parentId:
  351. menu.parent_id=form_data.parentId
  352. if form_data.path:
  353. menu.path=form_data.path
  354. if form_data.perms:
  355. menu.perms=form_data.perms
  356. if form_data.queryParam:
  357. menu.query_param=form_data.queryParam
  358. if form_data.status:
  359. menu.status=form_data.status
  360. if form_data.visible:
  361. menu.visible=form_data.visible
  362. # for field, value in menu_data.items():
  363. # if field != 'menu_id' and field in menu_to_update.__dict__:
  364. # setattr(menu_to_update, field, value)
  365. #
  366. # db.add(menu_to_update)
  367. db.commit()
  368. return {
  369. "code": 200,
  370. "msg": "菜单更新成功"
  371. }
  372. except Exception as e:
  373. # db.rollback()
  374. if str(e)=='':
  375. e = detail
  376. raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
  377. @router.delete('/delete/{menu_id}')
  378. async def delete(
  379. menu_id: int,
  380. db: Session = Depends(get_db)
  381. ):
  382. try:
  383. query = db.query(SysMenu)
  384. query = query.filter(SysMenu.menu_id == menu_id)
  385. query = query.filter(SysMenu.del_flag != '2')
  386. menu_to_delete =query.first()
  387. if not menu_to_delete:
  388. detail = "菜单不存在"
  389. raise HTTPException(status_code=404, detail="菜单不存在")
  390. menu_to_delete.del_flag='2'
  391. # db.delete(menu_to_delete)
  392. db.commit()
  393. return {
  394. "code": 200,
  395. "msg": "菜单删除成功"
  396. }
  397. except Exception as e:
  398. db.rollback()
  399. if str(e)=='':
  400. e = detail
  401. raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))