__init__.py 15 KB

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