__init__.py 17 KB

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