__init__.py 21 KB

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