__init__.py 19 KB

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