__init__.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  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. @router.get('/{menuid}')
  261. async def get_list(
  262. # request: Request,
  263. menuid: str = Query(None, max_length=100),
  264. db: Session = Depends(get_db),
  265. user: AuthUser = Depends(get_auth_user)
  266. ):
  267. query = db.query(SysMenu)
  268. query = query.filter(SysMenu.del_flag != '2')
  269. if menuid:
  270. query = query.filter(SysMenu.menu_id.like(f'{menuid}'))
  271. menu= query.first()
  272. # 将模型实例转换为字典
  273. menu_list_dict = {
  274. "menuId": menu.menu_id,
  275. "menuName": menu.menu_name,
  276. "parentId": menu.parent_id,
  277. "orderNum": menu.order_num,
  278. "path": menu.path,
  279. "component": menu.component,
  280. "queryParam": menu.query_param,
  281. "isFrame": str(menu.is_frame),
  282. "isCache": str(menu.is_cache),
  283. "menuType": menu.menu_type,
  284. "visible": menu.visible,
  285. "status": menu.status,
  286. "perms": menu.perms,
  287. "icon": menu.icon,
  288. "createDept": menu.create_dept,
  289. "remark": menu.remark,
  290. "createTime": menu.create_time.strftime('%Y-%m-%d %H:%M:%S') if menu.create_time else '',
  291. "children": [] # 递归调用以获取子菜单
  292. }
  293. return {
  294. "code": 200,
  295. "data": menu_list_dict,
  296. "msg": "操作成功"
  297. }
  298. class SysMuneCreateForm(BaseModel):
  299. component:str = None
  300. icon : str
  301. isCache: str
  302. isFrame:str
  303. menuName: str
  304. menuType:str
  305. orderNum:int
  306. parentId:int
  307. path:str
  308. perms:str=None
  309. queryParam:str=None
  310. status:str
  311. visible:str
  312. @router.post('/create')
  313. async def create(
  314. form_data: SysMuneCreateForm,
  315. db: Session = Depends(get_db)
  316. ):
  317. try:
  318. new_menu = SysMenu(
  319. menu_name = form_data.menuName,
  320. parent_id = form_data.parentId,
  321. order_num = form_data.orderNum,
  322. path = form_data.path,
  323. is_frame = int(form_data.isFrame),
  324. is_cache = int(form_data.isCache),
  325. menu_type = form_data.menuType,
  326. visible = form_data.visible,
  327. status = form_data.status,
  328. icon = form_data.icon,
  329. component= form_data.component,
  330. perms=form_data.perms,
  331. query_param=form_data.queryParam
  332. )
  333. db.add(new_menu)
  334. db.commit()
  335. db.refresh(new_menu)
  336. return {
  337. "code": 200,
  338. "data": None,
  339. "msg": "操作成功"
  340. }
  341. except Exception as e:
  342. db.rollback()
  343. raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
  344. class SysMuneUpdateForm(BaseModel):
  345. menuId : str
  346. component:str = None
  347. icon : str = None
  348. isCache: str = None
  349. isFrame:str = None
  350. menuName: str = None
  351. menuType:str = None
  352. orderNum:int = None
  353. parentId:int = None
  354. path:str = None
  355. perms:str=None
  356. queryParam:str=None
  357. status:str = None
  358. visible:str = None
  359. @router.put('/update')
  360. async def update(
  361. request: Request,
  362. form_data: SysMuneUpdateForm,
  363. db: Session = Depends(get_db)
  364. ):
  365. try:
  366. query = db.query(SysMenu)
  367. query = query.filter(SysMenu.menu_id == form_data.menuId)
  368. query = query.filter(SysMenu.del_flag != '2')
  369. menu = query.first()
  370. if not menu:
  371. detail = "菜单不存在"
  372. raise HTTPException(status_code=404, detail="菜单不存在")
  373. # 更新字段,排除主键和不可更新的字段
  374. if form_data.component:
  375. menu.component=form_data.component
  376. if form_data.icon:
  377. menu.icon=form_data.icon
  378. if form_data.isCache:
  379. menu.is_cache=form_data.isCache
  380. if form_data.isFrame:
  381. menu.is_frame=form_data.isFrame
  382. if form_data.menuName:
  383. menu.menu_name=form_data.menuName
  384. if form_data.menuType:
  385. menu.menu_type=form_data.menuType
  386. if form_data.orderNum:
  387. menu.order_num=form_data.orderNum
  388. if form_data.parentId:
  389. menu.parent_id=form_data.parentId
  390. if form_data.path:
  391. menu.path=form_data.path
  392. if form_data.perms:
  393. menu.perms=form_data.perms
  394. if form_data.queryParam:
  395. menu.query_param=form_data.queryParam
  396. if form_data.status:
  397. menu.status=form_data.status
  398. if form_data.visible:
  399. menu.visible=form_data.visible
  400. # for field, value in menu_data.items():
  401. # if field != 'menu_id' and field in menu_to_update.__dict__:
  402. # setattr(menu_to_update, field, value)
  403. #
  404. # db.add(menu_to_update)
  405. db.commit()
  406. return {
  407. "code": 200,
  408. "msg": "菜单更新成功"
  409. }
  410. except Exception as e:
  411. # db.rollback()
  412. if str(e)=='':
  413. e = detail
  414. raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))
  415. @router.delete('/delete/{menu_id}')
  416. async def delete(
  417. menu_id: int,
  418. db: Session = Depends(get_db)
  419. ):
  420. try:
  421. query = db.query(SysMenu)
  422. query = query.filter(SysMenu.menu_id == menu_id)
  423. query = query.filter(SysMenu.del_flag != '2')
  424. menu_to_delete =query.first()
  425. if not menu_to_delete:
  426. detail = "菜单不存在"
  427. raise HTTPException(status_code=404, detail="菜单不存在")
  428. menu_to_delete.del_flag='2'
  429. # db.delete(menu_to_delete)
  430. db.commit()
  431. return {
  432. "code": 200,
  433. "msg": "菜单删除成功"
  434. }
  435. except Exception as e:
  436. db.rollback()
  437. if str(e)=='':
  438. e = detail
  439. raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))