api.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. from starlette.formparsers import MultiPartParser as StartletteMultiPartParser
  2. from fastapi import APIRouter, Request, Response, Depends
  3. from fastapi.responses import FileResponse
  4. from key import v1 as key_v1
  5. from hub import methods, Global
  6. import importlib
  7. router = APIRouter()
  8. config_dict = {
  9. 'v6': {
  10. # --- 用户管理 ---
  11. 1001: 'v6.code1000.code1001', # 新增用户
  12. 1002: 'v6.code1000.code1002', # 查询用户列表(分页)
  13. 1003: 'v6.code1000.code1003', # 删除指定用户
  14. 1004: 'v6.code1000.code1004', # 禁用指定用户
  15. 1005: 'v6.code1000.code1005', # 启用指定用户
  16. 1006: 'v6.code1000.code1006', # 获取指定用户详情
  17. 1007: 'v6.code1000.code1007', # 修改指定用户信息
  18. # --- 车辆管理 ---
  19. 2001: 'v6.code2000.code2001', # 新增车辆
  20. 2002: 'v6.code2000.code2002', # 查询车辆列表(分页)
  21. 2003: 'v6.code2000.code2003', # 修改指定车辆信息
  22. 2004: 'v6.code2000.code2004', # 禁止指定车辆远程操作
  23. 2005: 'v6.code2000.code2005', # 允许指定车辆远程操作
  24. 2006: 'v6.code2000.code2006', # 删除指定作业车辆
  25. 2007: 'v6.code2000.code2007', # 获取指定作业车辆详情
  26. # --- 关于日志 ---
  27. 3001: 'v6.code3000.code3001', # 查询驾驶人员操作记录列表
  28. 3002: 'v6.code3000.code3002', # 下载指定驾驶人员操作日志
  29. }
  30. }
  31. methods_dict = {} # {<tag>: {<method>: <path>}}
  32. def _get_method_by_code(code, tag):
  33. """
  34. 通过code获取method(不调用不加载)
  35. """
  36. # --- check ---
  37. if tag not in methods_dict:
  38. methods_dict[tag] = {}
  39. # --- check ---
  40. if code in methods_dict.get(tag):
  41. return methods_dict.get(tag).get(code)
  42. # --- get method ---
  43. method_path = config_dict.get(tag).get(code)
  44. tag, file_name, method_name = method_path.split('.')
  45. script = importlib.import_module(f"api.{tag}.{file_name}")
  46. method = getattr(script, method_name)
  47. # --- set method ---
  48. methods_dict[tag][code] = method
  49. return method
  50. @router.post('/{tag}/api')
  51. async def post(tag: str, request: Request, response: Response, user: dict = Depends(key_v1.login_required)):
  52. """"""
  53. # --- check ---
  54. if not user.get('skip_is'):
  55. response.headers['authorization'] = key_v1.get_token_by_user(user)
  56. # --- get sources ---
  57. sources = await request.json()
  58. code = int(sources.get('code'))
  59. page = sources.get('page', 1)
  60. size = sources.get('size', 10)
  61. ban_keys = ['code']
  62. # --- set global args ---
  63. sources = {key: val for key, val in sources.items() if key not in ban_keys}
  64. sources['g_user_id'] = user.get('uid')
  65. sources['g_user_name'] = user.get('username')
  66. sources['g_user_pass'] = user.get('password')
  67. sources['g_role_id'] = user.get('role_id')
  68. # --- call action ---
  69. try:
  70. run_at = methods.now_ts()
  71. method = _get_method_by_code(code=code, tag=tag)
  72. result = await method(**sources)
  73. methods.debug_log(f"api.post.95", f"#{tag}/{code}: use time {round(methods.now_ts() - run_at, 2)}s")
  74. # --- check ---
  75. if code in [
  76. # 8201, # 访客记录,列表
  77. ] and result.__class__.__name__ == 'dict':
  78. return dict(
  79. code=result.get('code'),
  80. data=result.get('data', [])[(page - 1) * size: page * size],
  81. page=page,
  82. size=size,
  83. total=len(result.get('data', [])),
  84. )
  85. elif result.__class__.__name__ in ['FileResponse', 'dict']:
  86. return result
  87. else:
  88. return dict(data=result, type=result.__class__.__name__)
  89. except Exception as exception:
  90. methods.debug_log('api.post.115', f"#tag: {tag}, #code: {code}")
  91. methods.debug_log('api.post.115', f"#exception: {exception}")
  92. methods.debug_log('api.post.115', f"#traceback: {methods.trace_log()}")
  93. return dict(code=-1, data=[], message=f"something is wrong. [{exception.__class__.__name__}]",
  94. details=f"{methods.trace_log()}")
  95. @router.put('/actions')
  96. async def upload(request: Request, user: dict = Depends(key_v1.login_required)):
  97. try:
  98. # --- get sources ---
  99. sources = dict()
  100. parser = StartletteMultiPartParser(request.headers, request.stream())
  101. params = await parser.parse()
  102. # sources['params'] = params
  103. # --- set sources --- fromdata列表处理
  104. for key, value in params.multi_items():
  105. # methods.debug_log('api.upload.137', f"#key: {key}, #value: {value}")
  106. # --- check list ---
  107. if key[-4:] == 'list' and key not in sources:
  108. sources[key] = list()
  109. if key[-4:] == 'list':
  110. sources[key].append(value)
  111. # --- make list ---
  112. else:
  113. if key in sources:
  114. sources[key] = [sources[key]]
  115. sources[key].append(value)
  116. else:
  117. sources[key] = value
  118. # methods.debug_log('actions.put', f"m-201: sources: {sources}")
  119. # --- clean ---
  120. tag = sources.get('tag', 'v1')
  121. code = int(sources.get('code'))
  122. del sources['tag']
  123. del sources['code']
  124. # --- set sources ---
  125. sources['g_user_id'] = user.get('uid')
  126. sources['g_user_name'] = user.get('username')
  127. sources['g_user_pass'] = user.get('password')
  128. sources['g_role_id'] = user.get('role_id')
  129. # --- set files ---
  130. files = dict()
  131. for key, value in sources.items():
  132. if value.__class__.__name__ == 'UploadFile':
  133. files[key] = value
  134. for key, value in files.items():
  135. del sources[key]
  136. sources['files'] = files
  137. # --- call action ---
  138. return await _get_method_by_code(code=code, tag=tag)(**sources)
  139. except Exception as exception:
  140. methods.debug_log('api.upload.176', f"#exception: {exception}")
  141. methods.debug_log('api.upload.176', f"#traceback: {methods.trace_log()}")
  142. return dict(code=-1, message=f"something is wrong. [{exception.__class__.__name__}]",
  143. details=f"{methods.trace_log()}")
  144. @router.get('/{tag}/api')
  145. async def download(request: Request, response: Response, tag: str):
  146. try:
  147. # --- get ---
  148. params = request.query_params
  149. # methods.debug_log('api.download.236', f"#params: {params}")
  150. method = _get_method_by_code(code=params.get('code'), tag=tag)
  151. result = await method(**params)
  152. # --- 是否弹框 ---
  153. if True:
  154. return FileResponse(result.get('file_path'),
  155. media_type="application/octet-stream", filename=result.get('file_name'))
  156. else:
  157. return FileResponse(result.get('file_path'))
  158. except Exception as exception:
  159. methods.debug_log('api.download.249', f"#exception: {exception}")
  160. methods.debug_log('api.download.249', f"#traceback: {methods.trace_log()}")
  161. return dict(code=-1, message=f"something is wrong. [{exception.__class__.__name__}]",
  162. details=f"{methods.trace_log()}")