fred-admin 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. fred_admin/__init__.py +91 -0
  2. fred_admin/common/AliyunSms.py +66 -0
  3. fred_admin/common/Blueprints.py +99 -0
  4. fred_admin/common/Email.py +23 -0
  5. fred_admin/common/Extensions.py +319 -0
  6. fred_admin/common/HandleExcetion.py +204 -0
  7. fred_admin/common/ImageVerification.py +117 -0
  8. fred_admin/common/IoTDBClient.py +698 -0
  9. fred_admin/common/PageSchema.py +65 -0
  10. fred_admin/common/Response.py +251 -0
  11. fred_admin/common/Route.py +390 -0
  12. fred_admin/common/RuntimeHook.py +111 -0
  13. fred_admin/common/SchedulerLog.py +277 -0
  14. fred_admin/common/Sqlacodegen.py +170 -0
  15. fred_admin/common/Swagger.py +77 -0
  16. fred_admin/common/SystemLog.py +80 -0
  17. fred_admin/common/Utils.py +1060 -0
  18. fred_admin/common/WechatLogin.py +97 -0
  19. fred_admin/common/__init__.py +3 -0
  20. fred_admin/config/Config.py +104 -0
  21. fred_admin/config/Logger.py +34 -0
  22. fred_admin/config/__init__.py +3 -0
  23. fred_admin/create_module.py +787 -0
  24. fred_admin/demo/app.py +6 -0
  25. fred_admin/demo/common/__init__.py +1 -0
  26. fred_admin/demo/common/config/Config.py +82 -0
  27. fred_admin/demo/common/config/README.md +8 -0
  28. fred_admin/demo/common/config/__init__.py +1 -0
  29. fred_admin/demo/common/config/__pycache__/Config.cpython-312.pyc +0 -0
  30. fred_admin/demo/common/config/__pycache__/__init__.cpython-312.pyc +0 -0
  31. fred_admin/demo/common/config/jwt_secret_key +1 -0
  32. fred_admin/demo/common/config/session_secret_key +1 -0
  33. fred_admin/demo/common/model/__pycache__/__init__.cpython-312.pyc +0 -0
  34. fred_admin/demo/common/model/__pycache__/model.cpython-312.pyc +0 -0
  35. fred_admin/demo/common/model/model.py +274 -0
  36. fred_admin/demo/demo_.gitignore +42 -0
  37. fred_admin/demo/modules/__init__.py +1 -0
  38. fred_admin/demo/modules/admin/README.md +38 -0
  39. fred_admin/demo/modules/admin/__init__.py +3 -0
  40. fred_admin/demo/modules/admin/backend/__init__.py +7 -0
  41. fred_admin/demo/modules/admin/backend/constant/RedisKey.py +10 -0
  42. fred_admin/demo/modules/admin/backend/controller/AdminAuthController.py +39 -0
  43. fred_admin/demo/modules/admin/backend/controller/AdminController.py +226 -0
  44. fred_admin/demo/modules/admin/backend/controller/ApiAuthController.py +93 -0
  45. fred_admin/demo/modules/admin/backend/controller/ButtonManageController.py +90 -0
  46. fred_admin/demo/modules/admin/backend/controller/FileController.py +28 -0
  47. fred_admin/demo/modules/admin/backend/controller/OrganizationController.py +218 -0
  48. fred_admin/demo/modules/admin/backend/controller/RoleController.py +143 -0
  49. fred_admin/demo/modules/admin/backend/controller/SystemController.py +112 -0
  50. fred_admin/demo/modules/admin/backend/controller/SystemLogController.py +63 -0
  51. fred_admin/demo/modules/admin/backend/controller/TableController.py +175 -0
  52. fred_admin/demo/modules/admin/backend/controller/__init__.py +55 -0
  53. fred_admin/demo/modules/admin/backend/schema/AdminSchema.py +356 -0
  54. fred_admin/demo/modules/admin/backend/schema/ApiAuthSchema.py +72 -0
  55. fred_admin/demo/modules/admin/backend/schema/AuthMenuSchema.py +79 -0
  56. fred_admin/demo/modules/admin/backend/schema/ButtonManageSchema.py +98 -0
  57. fred_admin/demo/modules/admin/backend/schema/OrganizationSchema.py +134 -0
  58. fred_admin/demo/modules/admin/backend/schema/RoleSchema.py +94 -0
  59. fred_admin/demo/modules/admin/backend/schema/SystemConfigSchema.py +115 -0
  60. fred_admin/demo/modules/admin/backend/schema/TableSchema.py +153 -0
  61. fred_admin/demo/modules/admin/backend/schema/UploadImg.py +35 -0
  62. fred_admin/demo/modules/admin/backend/schema/__init__.py +0 -0
  63. fred_admin/demo/modules/admin/backend/schema/__pycache__/AdminSchema.cpython-312.pyc +0 -0
  64. fred_admin/demo/modules/admin/backend/schema/__pycache__/ApiAuthSchema.cpython-312.pyc +0 -0
  65. fred_admin/demo/modules/admin/backend/schema/__pycache__/AuthMenuSchema.cpython-312.pyc +0 -0
  66. fred_admin/demo/modules/admin/backend/schema/__pycache__/ButtonManageSchema.cpython-312.pyc +0 -0
  67. fred_admin/demo/modules/admin/backend/schema/__pycache__/OrganizationSchema.cpython-312.pyc +0 -0
  68. fred_admin/demo/modules/admin/backend/schema/__pycache__/RoleSchema.cpython-312.pyc +0 -0
  69. fred_admin/demo/modules/admin/backend/schema/__pycache__/SystemConfigSchema.cpython-312.pyc +0 -0
  70. fred_admin/demo/modules/admin/backend/schema/__pycache__/TableSchema.cpython-312.pyc +0 -0
  71. fred_admin/demo/modules/admin/backend/schema/__pycache__/UploadImg.cpython-312.pyc +0 -0
  72. fred_admin/demo/modules/admin/backend/schema/__pycache__/__init__.cpython-312.pyc +0 -0
  73. fred_admin/demo/modules/admin/backend/service/AdminService.py +377 -0
  74. fred_admin/demo/modules/admin/backend/service/ApiAuthService.py +237 -0
  75. fred_admin/demo/modules/admin/backend/service/AuthButtonsService.py +155 -0
  76. fred_admin/demo/modules/admin/backend/service/AuthMenuService.py +265 -0
  77. fred_admin/demo/modules/admin/backend/service/ButtonManageService.py +386 -0
  78. fred_admin/demo/modules/admin/backend/service/ButtonManageService.py.broken +113 -0
  79. fred_admin/demo/modules/admin/backend/service/FileService.py +33 -0
  80. fred_admin/demo/modules/admin/backend/service/OrganizationService.py +465 -0
  81. fred_admin/demo/modules/admin/backend/service/RoleService.py +445 -0
  82. fred_admin/demo/modules/admin/backend/service/SystemConfigService.py +89 -0
  83. fred_admin/demo/modules/admin/backend/service/SystemLogService.py +142 -0
  84. fred_admin/demo/modules/admin/backend/service/TableService.py +978 -0
  85. fred_admin/demo/modules/admin/backend/service/__init__.py +1 -0
  86. fred_admin/demo/modules/admin/backend/sql/app.db +0 -0
  87. fred_admin/demo/modules/admin/backend/sql/fred.sql +3780 -0
  88. fred_admin/demo/modules/admin/frontend/LICENSE +21 -0
  89. fred_admin/demo/modules/admin/frontend/build/getEnv.ts +46 -0
  90. fred_admin/demo/modules/admin/frontend/build/plugins.ts +118 -0
  91. fred_admin/demo/modules/admin/frontend/build/proxy.ts +30 -0
  92. fred_admin/demo/modules/admin/frontend/commitlint.config.cjs +162 -0
  93. fred_admin/demo/modules/admin/frontend/demo_editorconfig +15 -0
  94. fred_admin/demo/modules/admin/frontend/demo_env +15 -0
  95. fred_admin/demo/modules/admin/frontend/demo_env.development +21 -0
  96. fred_admin/demo/modules/admin/frontend/demo_env.production +25 -0
  97. fred_admin/demo/modules/admin/frontend/demo_eslintignore +15 -0
  98. fred_admin/demo/modules/admin/frontend/demo_eslintrc.cjs +61 -0
  99. fred_admin/demo/modules/admin/frontend/demo_gitignore +27 -0
  100. fred_admin/demo/modules/admin/frontend/demo_prettierignore +9 -0
  101. fred_admin/demo/modules/admin/frontend/demo_prettierrc.cjs +41 -0
  102. fred_admin/demo/modules/admin/frontend/demo_stylelintignore +4 -0
  103. fred_admin/demo/modules/admin/frontend/demo_stylelintrc.cjs +40 -0
  104. fred_admin/demo/modules/admin/frontend/index.html +105 -0
  105. fred_admin/demo/modules/admin/frontend/lint-staged.config.cjs +8 -0
  106. fred_admin/demo/modules/admin/frontend/package.json +129 -0
  107. fred_admin/demo/modules/admin/frontend/pnpm-lock.yaml +11150 -0
  108. fred_admin/demo/modules/admin/frontend/postcss.config.cjs +5 -0
  109. fred_admin/demo/modules/admin/frontend/public/logo.png +0 -0
  110. fred_admin/demo/modules/admin/frontend/public/vue.svg +1 -0
  111. fred_admin/demo/modules/admin/frontend/src/App.vue +44 -0
  112. fred_admin/demo/modules/admin/frontend/src/api/config/servicePort.ts +2 -0
  113. fred_admin/demo/modules/admin/frontend/src/api/helper/axiosCancel.ts +57 -0
  114. fred_admin/demo/modules/admin/frontend/src/api/helper/checkStatus.ts +43 -0
  115. fred_admin/demo/modules/admin/frontend/src/api/index.ts +167 -0
  116. fred_admin/demo/modules/admin/frontend/src/api/interface/index.ts +179 -0
  117. fred_admin/demo/modules/admin/frontend/src/api/model/adminModel.ts +135 -0
  118. fred_admin/demo/modules/admin/frontend/src/api/model/apiAuthModel.ts +72 -0
  119. fred_admin/demo/modules/admin/frontend/src/api/model/index.ts +24 -0
  120. fred_admin/demo/modules/admin/frontend/src/api/model/loginModel.ts +79 -0
  121. fred_admin/demo/modules/admin/frontend/src/api/model/roleModel.ts +68 -0
  122. fred_admin/demo/modules/admin/frontend/src/api/model/storeModel.ts +80 -0
  123. fred_admin/demo/modules/admin/frontend/src/api/model/systemModel.ts +162 -0
  124. fred_admin/demo/modules/admin/frontend/src/api/model/uploadModel.ts +153 -0
  125. fred_admin/demo/modules/admin/frontend/src/api/modules/admin.ts +76 -0
  126. fred_admin/demo/modules/admin/frontend/src/api/modules/apiAuth.ts +53 -0
  127. fred_admin/demo/modules/admin/frontend/src/api/modules/buttonManage.ts +119 -0
  128. fred_admin/demo/modules/admin/frontend/src/api/modules/dataBase.ts +60 -0
  129. fred_admin/demo/modules/admin/frontend/src/api/modules/login.ts +54 -0
  130. fred_admin/demo/modules/admin/frontend/src/api/modules/organization.ts +123 -0
  131. fred_admin/demo/modules/admin/frontend/src/api/modules/role.ts +61 -0
  132. fred_admin/demo/modules/admin/frontend/src/api/modules/store.ts +303 -0
  133. fred_admin/demo/modules/admin/frontend/src/api/modules/system.ts +125 -0
  134. fred_admin/demo/modules/admin/frontend/src/api/modules/upload.ts +132 -0
  135. fred_admin/demo/modules/admin/frontend/src/api/modules/user.ts +63 -0
  136. fred_admin/demo/modules/admin/frontend/src/assets/fonts/DIN.otf +0 -0
  137. fred_admin/demo/modules/admin/frontend/src/assets/fonts/MetroDF.ttf +0 -0
  138. fred_admin/demo/modules/admin/frontend/src/assets/fonts/YouSheBiaoTiHei.ttf +0 -0
  139. fred_admin/demo/modules/admin/frontend/src/assets/fonts/font.scss +14 -0
  140. fred_admin/demo/modules/admin/frontend/src/assets/iconfont/iconfont.scss +51 -0
  141. fred_admin/demo/modules/admin/frontend/src/assets/iconfont/iconfont.ttf +0 -0
  142. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingdaoyu.svg +1 -0
  143. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingdiqiu.svg +1 -0
  144. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingditu.svg +1 -0
  145. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingfanchuan.svg +1 -0
  146. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingfeiji.svg +1 -0
  147. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxinglvhangriji.svg +1 -0
  148. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingtianqiyubao.svg +1 -0
  149. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingxiangjipaizhao.svg +1 -0
  150. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingxiarilengyin.svg +1 -0
  151. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingyoulun.svg +1 -0
  152. fred_admin/demo/modules/admin/frontend/src/assets/icons/xianxingzijiayou.svg +1 -0
  153. fred_admin/demo/modules/admin/frontend/src/assets/images/403.png +0 -0
  154. fred_admin/demo/modules/admin/frontend/src/assets/images/404.png +0 -0
  155. fred_admin/demo/modules/admin/frontend/src/assets/images/500.png +0 -0
  156. fred_admin/demo/modules/admin/frontend/src/assets/images/avatar.gif +0 -0
  157. fred_admin/demo/modules/admin/frontend/src/assets/images/login_bg.svg +33 -0
  158. fred_admin/demo/modules/admin/frontend/src/assets/images/login_left.png +0 -0
  159. fred_admin/demo/modules/admin/frontend/src/assets/images/login_left1.png +0 -0
  160. fred_admin/demo/modules/admin/frontend/src/assets/images/login_left2.png +0 -0
  161. fred_admin/demo/modules/admin/frontend/src/assets/images/login_left3.png +0 -0
  162. fred_admin/demo/modules/admin/frontend/src/assets/images/login_left4.png +0 -0
  163. fred_admin/demo/modules/admin/frontend/src/assets/images/login_left5.png +0 -0
  164. fred_admin/demo/modules/admin/frontend/src/assets/images/logo.svg +1 -0
  165. fred_admin/demo/modules/admin/frontend/src/assets/images/msg01.png +0 -0
  166. fred_admin/demo/modules/admin/frontend/src/assets/images/msg02.png +0 -0
  167. fred_admin/demo/modules/admin/frontend/src/assets/images/msg03.png +0 -0
  168. fred_admin/demo/modules/admin/frontend/src/assets/images/msg04.png +0 -0
  169. fred_admin/demo/modules/admin/frontend/src/assets/images/msg05.png +0 -0
  170. fred_admin/demo/modules/admin/frontend/src/assets/images/notData.png +0 -0
  171. fred_admin/demo/modules/admin/frontend/src/assets/images/welcome.png +0 -0
  172. fred_admin/demo/modules/admin/frontend/src/assets/json/authButtonList.json +8 -0
  173. fred_admin/demo/modules/admin/frontend/src/assets/json/authMenuList.json +1075 -0
  174. fred_admin/demo/modules/admin/frontend/src/assets/mock/Easy-Mock-API.zip +0 -0
  175. fred_admin/demo/modules/admin/frontend/src/components/ECharts/config/index.ts +72 -0
  176. fred_admin/demo/modules/admin/frontend/src/components/ECharts/index.vue +104 -0
  177. fred_admin/demo/modules/admin/frontend/src/components/ErrorMessage/403.vue +19 -0
  178. fred_admin/demo/modules/admin/frontend/src/components/ErrorMessage/404.vue +19 -0
  179. fred_admin/demo/modules/admin/frontend/src/components/ErrorMessage/500.vue +19 -0
  180. fred_admin/demo/modules/admin/frontend/src/components/ErrorMessage/index.scss +32 -0
  181. fred_admin/demo/modules/admin/frontend/src/components/Grid/components/GridItem.vue +68 -0
  182. fred_admin/demo/modules/admin/frontend/src/components/Grid/index.vue +167 -0
  183. fred_admin/demo/modules/admin/frontend/src/components/Grid/interface/index.ts +6 -0
  184. fred_admin/demo/modules/admin/frontend/src/components/ImageCaptcha/index.vue +71 -0
  185. fred_admin/demo/modules/admin/frontend/src/components/ImportExcel/index.scss +3 -0
  186. fred_admin/demo/modules/admin/frontend/src/components/ImportExcel/index.vue +151 -0
  187. fred_admin/demo/modules/admin/frontend/src/components/JsonViewer/index.vue +249 -0
  188. fred_admin/demo/modules/admin/frontend/src/components/Loading/fullScreen.ts +45 -0
  189. fred_admin/demo/modules/admin/frontend/src/components/Loading/index.scss +67 -0
  190. fred_admin/demo/modules/admin/frontend/src/components/Loading/index.vue +13 -0
  191. fred_admin/demo/modules/admin/frontend/src/components/ProTable/components/ColSetting.vue +45 -0
  192. fred_admin/demo/modules/admin/frontend/src/components/ProTable/components/Pagination.vue +101 -0
  193. fred_admin/demo/modules/admin/frontend/src/components/ProTable/components/TableColumn.vue +58 -0
  194. fred_admin/demo/modules/admin/frontend/src/components/ProTable/index.vue +348 -0
  195. fred_admin/demo/modules/admin/frontend/src/components/ProTable/interface/index.ts +87 -0
  196. fred_admin/demo/modules/admin/frontend/src/components/SearchForm/components/SearchFormItem.vue +96 -0
  197. fred_admin/demo/modules/admin/frontend/src/components/SearchForm/index.vue +98 -0
  198. fred_admin/demo/modules/admin/frontend/src/components/SelectFilter/index.scss +63 -0
  199. fred_admin/demo/modules/admin/frontend/src/components/SelectFilter/index.vue +110 -0
  200. fred_admin/demo/modules/admin/frontend/src/components/SelectIcon/index.scss +39 -0
  201. fred_admin/demo/modules/admin/frontend/src/components/SelectIcon/index.vue +90 -0
  202. fred_admin/demo/modules/admin/frontend/src/components/StoreFilter/index.vue +356 -0
  203. fred_admin/demo/modules/admin/frontend/src/components/SvgIcon/index.vue +22 -0
  204. fred_admin/demo/modules/admin/frontend/src/components/SwitchDark/index.vue +12 -0
  205. fred_admin/demo/modules/admin/frontend/src/components/TreeFilter/index.scss +44 -0
  206. fred_admin/demo/modules/admin/frontend/src/components/TreeFilter/index.vue +165 -0
  207. fred_admin/demo/modules/admin/frontend/src/components/Upload/Img.vue +304 -0
  208. fred_admin/demo/modules/admin/frontend/src/components/Upload/Imgs.vue +316 -0
  209. fred_admin/demo/modules/admin/frontend/src/components/WangEditor/index.scss +28 -0
  210. fred_admin/demo/modules/admin/frontend/src/components/WangEditor/index.vue +154 -0
  211. fred_admin/demo/modules/admin/frontend/src/config/amapMap.ts +11 -0
  212. fred_admin/demo/modules/admin/frontend/src/config/index.ts +16 -0
  213. fred_admin/demo/modules/admin/frontend/src/config/nprogress.ts +12 -0
  214. fred_admin/demo/modules/admin/frontend/src/directives/index.ts +28 -0
  215. fred_admin/demo/modules/admin/frontend/src/directives/modules/auth.ts +26 -0
  216. fred_admin/demo/modules/admin/frontend/src/directives/modules/copy.ts +37 -0
  217. fred_admin/demo/modules/admin/frontend/src/directives/modules/debounce.ts +31 -0
  218. fred_admin/demo/modules/admin/frontend/src/directives/modules/draggable.ts +49 -0
  219. fred_admin/demo/modules/admin/frontend/src/directives/modules/longpress.ts +49 -0
  220. fred_admin/demo/modules/admin/frontend/src/directives/modules/throttle.ts +41 -0
  221. fred_admin/demo/modules/admin/frontend/src/directives/modules/waterMarker.ts +36 -0
  222. fred_admin/demo/modules/admin/frontend/src/enums/httpEnum.ts +35 -0
  223. fred_admin/demo/modules/admin/frontend/src/hooks/interface/index.ts +32 -0
  224. fred_admin/demo/modules/admin/frontend/src/hooks/useAuthButtons.ts +22 -0
  225. fred_admin/demo/modules/admin/frontend/src/hooks/useDownload.ts +42 -0
  226. fred_admin/demo/modules/admin/frontend/src/hooks/useHandleData.ts +41 -0
  227. fred_admin/demo/modules/admin/frontend/src/hooks/useI18n.ts +51 -0
  228. fred_admin/demo/modules/admin/frontend/src/hooks/useOnline.ts +31 -0
  229. fred_admin/demo/modules/admin/frontend/src/hooks/useSelection.ts +34 -0
  230. fred_admin/demo/modules/admin/frontend/src/hooks/useTable.ts +150 -0
  231. fred_admin/demo/modules/admin/frontend/src/hooks/useTheme.ts +111 -0
  232. fred_admin/demo/modules/admin/frontend/src/hooks/useTime.ts +38 -0
  233. fred_admin/demo/modules/admin/frontend/src/languages/index.ts +32 -0
  234. fred_admin/demo/modules/admin/frontend/src/languages/modules/en.ts +978 -0
  235. fred_admin/demo/modules/admin/frontend/src/languages/modules/zh.ts +996 -0
  236. fred_admin/demo/modules/admin/frontend/src/layouts/LayoutClassic/index.scss +60 -0
  237. fred_admin/demo/modules/admin/frontend/src/layouts/LayoutClassic/index.vue +62 -0
  238. fred_admin/demo/modules/admin/frontend/src/layouts/LayoutColumns/index.scss +95 -0
  239. fred_admin/demo/modules/admin/frontend/src/layouts/LayoutColumns/index.vue +103 -0
  240. fred_admin/demo/modules/admin/frontend/src/layouts/LayoutTransverse/index.scss +60 -0
  241. fred_admin/demo/modules/admin/frontend/src/layouts/LayoutTransverse/index.vue +61 -0
  242. fred_admin/demo/modules/admin/frontend/src/layouts/LayoutVertical/index.scss +48 -0
  243. fred_admin/demo/modules/admin/frontend/src/layouts/LayoutVertical/index.vue +56 -0
  244. fred_admin/demo/modules/admin/frontend/src/layouts/components/Footer/index.scss +11 -0
  245. fred_admin/demo/modules/admin/frontend/src/layouts/components/Footer/index.vue +9 -0
  246. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/ToolBarLeft.vue +23 -0
  247. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/ToolBarRight.vue +51 -0
  248. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/AssemblySize.vue +37 -0
  249. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/Avatar.vue +79 -0
  250. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/Breadcrumb.vue +122 -0
  251. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/CollapseIcon.vue +21 -0
  252. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/Fullscreen.vue +25 -0
  253. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/InfoDialog.vue +22 -0
  254. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/Language.vue +38 -0
  255. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/Message.vue +109 -0
  256. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/PasswordDialog.vue +81 -0
  257. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/SearchMenu.vue +183 -0
  258. fred_admin/demo/modules/admin/frontend/src/layouts/components/Header/components/ThemeSetting.vue +12 -0
  259. fred_admin/demo/modules/admin/frontend/src/layouts/components/Main/components/Maximize.vue +39 -0
  260. fred_admin/demo/modules/admin/frontend/src/layouts/components/Main/index.scss +10 -0
  261. fred_admin/demo/modules/admin/frontend/src/layouts/components/Main/index.vue +88 -0
  262. fred_admin/demo/modules/admin/frontend/src/layouts/components/Menu/SubMenu.vue +85 -0
  263. fred_admin/demo/modules/admin/frontend/src/layouts/components/Tabs/components/MoreButton.vue +85 -0
  264. fred_admin/demo/modules/admin/frontend/src/layouts/components/Tabs/index.scss +69 -0
  265. fred_admin/demo/modules/admin/frontend/src/layouts/components/Tabs/index.vue +115 -0
  266. fred_admin/demo/modules/admin/frontend/src/layouts/components/ThemeDrawer/index.scss +137 -0
  267. fred_admin/demo/modules/admin/frontend/src/layouts/components/ThemeDrawer/index.vue +191 -0
  268. fred_admin/demo/modules/admin/frontend/src/layouts/index.vue +42 -0
  269. fred_admin/demo/modules/admin/frontend/src/layouts/indexAsync.vue +46 -0
  270. fred_admin/demo/modules/admin/frontend/src/main.ts +45 -0
  271. fred_admin/demo/modules/admin/frontend/src/routers/index.ts +106 -0
  272. fred_admin/demo/modules/admin/frontend/src/routers/modules/dynamicRouter.ts +99 -0
  273. fred_admin/demo/modules/admin/frontend/src/routers/modules/staticRouter.ts +63 -0
  274. fred_admin/demo/modules/admin/frontend/src/stores/helper/persist.ts +19 -0
  275. fred_admin/demo/modules/admin/frontend/src/stores/index.ts +8 -0
  276. fred_admin/demo/modules/admin/frontend/src/stores/interface/index.ts +63 -0
  277. fred_admin/demo/modules/admin/frontend/src/stores/modules/auth.ts +50 -0
  278. fred_admin/demo/modules/admin/frontend/src/stores/modules/global.ts +55 -0
  279. fred_admin/demo/modules/admin/frontend/src/stores/modules/keepAlive.ts +25 -0
  280. fred_admin/demo/modules/admin/frontend/src/stores/modules/tabs.ts +78 -0
  281. fred_admin/demo/modules/admin/frontend/src/stores/modules/user.ts +23 -0
  282. fred_admin/demo/modules/admin/frontend/src/styles/common.scss +129 -0
  283. fred_admin/demo/modules/admin/frontend/src/styles/element-dark.scss +28 -0
  284. fred_admin/demo/modules/admin/frontend/src/styles/element.scss +264 -0
  285. fred_admin/demo/modules/admin/frontend/src/styles/modules/annotation.scss +746 -0
  286. fred_admin/demo/modules/admin/frontend/src/styles/modules/assembly.scss +714 -0
  287. fred_admin/demo/modules/admin/frontend/src/styles/modules/device-manager.scss +659 -0
  288. fred_admin/demo/modules/admin/frontend/src/styles/modules/directives.scss +381 -0
  289. fred_admin/demo/modules/admin/frontend/src/styles/reset.scss +143 -0
  290. fred_admin/demo/modules/admin/frontend/src/styles/table-optimization.scss +242 -0
  291. fred_admin/demo/modules/admin/frontend/src/styles/theme/aside.ts +16 -0
  292. fred_admin/demo/modules/admin/frontend/src/styles/theme/header.ts +25 -0
  293. fred_admin/demo/modules/admin/frontend/src/styles/theme/menu.ts +31 -0
  294. fred_admin/demo/modules/admin/frontend/src/styles/var.scss +2 -0
  295. fred_admin/demo/modules/admin/frontend/src/typings/global.d.ts +74 -0
  296. fred_admin/demo/modules/admin/frontend/src/typings/utils.d.ts +17 -0
  297. fred_admin/demo/modules/admin/frontend/src/typings/window.d.ts +8 -0
  298. fred_admin/demo/modules/admin/frontend/src/utils/color.ts +59 -0
  299. fred_admin/demo/modules/admin/frontend/src/utils/dict.ts +17 -0
  300. fred_admin/demo/modules/admin/frontend/src/utils/eleValidate.ts +14 -0
  301. fred_admin/demo/modules/admin/frontend/src/utils/errorHandler.ts +28 -0
  302. fred_admin/demo/modules/admin/frontend/src/utils/index.ts +327 -0
  303. fred_admin/demo/modules/admin/frontend/src/utils/is/index.ts +125 -0
  304. fred_admin/demo/modules/admin/frontend/src/utils/mittBus.ts +5 -0
  305. fred_admin/demo/modules/admin/frontend/src/utils/svg.ts +13 -0
  306. fred_admin/demo/modules/admin/frontend/src/views/dataBase/fieldType/components/FieldTypeDrawer.vue +89 -0
  307. fred_admin/demo/modules/admin/frontend/src/views/dataBase/fieldType/index.vue +99 -0
  308. fred_admin/demo/modules/admin/frontend/src/views/dataBase/tableManage/components/DataBaseDrawer.vue +254 -0
  309. fred_admin/demo/modules/admin/frontend/src/views/dataBase/tableManage/components/IndexDrawer.vue +226 -0
  310. fred_admin/demo/modules/admin/frontend/src/views/dataBase/tableManage/components/TableDataDrawer.vue +136 -0
  311. fred_admin/demo/modules/admin/frontend/src/views/dataBase/tableManage/index.vue +234 -0
  312. fred_admin/demo/modules/admin/frontend/src/views/echarts/columnChart/index.scss +0 -0
  313. fred_admin/demo/modules/admin/frontend/src/views/echarts/columnChart/index.vue +139 -0
  314. fred_admin/demo/modules/admin/frontend/src/views/echarts/lineChart/index.scss +0 -0
  315. fred_admin/demo/modules/admin/frontend/src/views/echarts/lineChart/index.vue +123 -0
  316. fred_admin/demo/modules/admin/frontend/src/views/echarts/nestedChart/index.scss +0 -0
  317. fred_admin/demo/modules/admin/frontend/src/views/echarts/nestedChart/index.vue +97 -0
  318. fred_admin/demo/modules/admin/frontend/src/views/echarts/pieChart/index.scss +0 -0
  319. fred_admin/demo/modules/admin/frontend/src/views/echarts/pieChart/index.vue +68 -0
  320. fred_admin/demo/modules/admin/frontend/src/views/echarts/radarChart/index.scss +0 -0
  321. fred_admin/demo/modules/admin/frontend/src/views/echarts/radarChart/index.vue +56 -0
  322. fred_admin/demo/modules/admin/frontend/src/views/echarts/waterChart/index.scss +0 -0
  323. fred_admin/demo/modules/admin/frontend/src/views/echarts/waterChart/index.vue +298 -0
  324. fred_admin/demo/modules/admin/frontend/src/views/home/index.scss +12 -0
  325. fred_admin/demo/modules/admin/frontend/src/views/home/index.vue +11 -0
  326. fred_admin/demo/modules/admin/frontend/src/views/login/components/LoginForm.vue +147 -0
  327. fred_admin/demo/modules/admin/frontend/src/views/login/index.scss +83 -0
  328. fred_admin/demo/modules/admin/frontend/src/views/login/index.vue +27 -0
  329. fred_admin/demo/modules/admin/frontend/src/views/proTable/complexProTable/index.vue +176 -0
  330. fred_admin/demo/modules/admin/frontend/src/views/proTable/components/UserDrawer.vue +152 -0
  331. fred_admin/demo/modules/admin/frontend/src/views/proTable/document/index.vue +13 -0
  332. fred_admin/demo/modules/admin/frontend/src/views/proTable/treeProTable/index.vue +129 -0
  333. fred_admin/demo/modules/admin/frontend/src/views/proTable/useProTable/detail.vue +12 -0
  334. fred_admin/demo/modules/admin/frontend/src/views/proTable/useProTable/index.vue +258 -0
  335. fred_admin/demo/modules/admin/frontend/src/views/proTable/useSelectFilter/index.vue +184 -0
  336. fred_admin/demo/modules/admin/frontend/src/views/proTable/useTreeFilter/detail.vue +12 -0
  337. fred_admin/demo/modules/admin/frontend/src/views/proTable/useTreeFilter/index.vue +147 -0
  338. fred_admin/demo/modules/admin/frontend/src/views/system/accountManage/index.vue +244 -0
  339. fred_admin/demo/modules/admin/frontend/src/views/system/apiAuth/components/ApiDrawer.vue +114 -0
  340. fred_admin/demo/modules/admin/frontend/src/views/system/apiAuth/components/TokenDrawer.vue +160 -0
  341. fred_admin/demo/modules/admin/frontend/src/views/system/apiAuth/index.vue +354 -0
  342. fred_admin/demo/modules/admin/frontend/src/views/system/buttonManage/components/ButtonDrawer.vue +460 -0
  343. fred_admin/demo/modules/admin/frontend/src/views/system/buttonManage/index.vue +426 -0
  344. fred_admin/demo/modules/admin/frontend/src/views/system/configManage/components/ConfigDrawer.vue +106 -0
  345. fred_admin/demo/modules/admin/frontend/src/views/system/configManage/index.vue +116 -0
  346. fred_admin/demo/modules/admin/frontend/src/views/system/departmentManage/index.vue +7 -0
  347. fred_admin/demo/modules/admin/frontend/src/views/system/dictManage/index.vue +7 -0
  348. fred_admin/demo/modules/admin/frontend/src/views/system/menuManage/components/MenuDrawer.vue +262 -0
  349. fred_admin/demo/modules/admin/frontend/src/views/system/menuManage/index.vue +310 -0
  350. fred_admin/demo/modules/admin/frontend/src/views/system/organizationManage/components/CompanyDrawer.vue +72 -0
  351. fred_admin/demo/modules/admin/frontend/src/views/system/organizationManage/components/DepartmentDrawer.vue +120 -0
  352. fred_admin/demo/modules/admin/frontend/src/views/system/organizationManage/components/TeamDrawer.vue +162 -0
  353. fred_admin/demo/modules/admin/frontend/src/views/system/organizationManage/components/TeamMemberDrawer.vue +243 -0
  354. fred_admin/demo/modules/admin/frontend/src/views/system/organizationManage/index.vue +414 -0
  355. fred_admin/demo/modules/admin/frontend/src/views/system/roleManage/components/RoleButtonDrawer.vue +587 -0
  356. fred_admin/demo/modules/admin/frontend/src/views/system/roleManage/components/RoleDrawer.vue +77 -0
  357. fred_admin/demo/modules/admin/frontend/src/views/system/roleManage/components/RoleMenuDrawer.vue +236 -0
  358. fred_admin/demo/modules/admin/frontend/src/views/system/roleManage/components/RoleUserDrawer.vue +125 -0
  359. fred_admin/demo/modules/admin/frontend/src/views/system/roleManage/index.vue +143 -0
  360. fred_admin/demo/modules/admin/frontend/src/views/system/systemLog/components/SystemLogDrawer.vue +207 -0
  361. fred_admin/demo/modules/admin/frontend/src/views/system/systemLog/index.vue +219 -0
  362. fred_admin/demo/modules/admin/frontend/src/views/system/timingTask/index.vue +7 -0
  363. fred_admin/demo/modules/admin/frontend/src/vite-env.d.ts +7 -0
  364. fred_admin/demo/modules/admin/frontend/tsconfig.json +42 -0
  365. fred_admin/demo/modules/admin/frontend/vite.config.ts +91 -0
  366. fred_admin/demo/modules/admin/frontend//321/205/320/231/320/235/321/207/320/273/320/277/321/204/342/225/227/320/263/321/207/320/260/320/221/321/210/320/277/342/224/244/321/206/320/250/320/236.md +100 -0
  367. fred_admin/demo/requirements.txt +1 -0
  368. fred_admin/fonts/NotoSansSC-VariableFont_wght.ttf +0 -0
  369. fred_admin/install_hook.py +1633 -0
  370. fred_admin/setup.py +18 -0
  371. fred_admin-1.0.0.dist-info/METADATA +97 -0
  372. fred_admin-1.0.0.dist-info/RECORD +376 -0
  373. fred_admin-1.0.0.dist-info/WHEEL +5 -0
  374. fred_admin-1.0.0.dist-info/entry_points.txt +3 -0
  375. fred_admin-1.0.0.dist-info/licenses/LICENSE +21 -0
  376. fred_admin-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,698 @@
1
+ from datetime import datetime
2
+ from typing import List, Dict, Any, Optional
3
+ from flask import current_app
4
+ from iotdb.Session import Session
5
+ from iotdb.utils.IoTDBConstants import TSDataType
6
+
7
+
8
+ class IoTDBClient:
9
+ """
10
+ IoTDB 数据库操作工具类
11
+ 封装 IoTDB 的增删改查操作
12
+ """
13
+
14
+ def __init__(self):
15
+ """
16
+ 初始化 IoTDB 连接
17
+ """
18
+ self.iotdb_client = None
19
+ self._connection_error = None
20
+ self._init_iotdb_connection()
21
+
22
+ def _init_iotdb_connection(self):
23
+ """
24
+ 初始化 IoTDB 数据库连接
25
+ """
26
+ try:
27
+ # 获取 IoTDB 配置
28
+ iotdb_config = current_app.config.get('IOTDB_CONFIG', {})
29
+ host = iotdb_config.get('host', '127.0.0.1')
30
+ port = iotdb_config.get('port', 6667)
31
+ username = iotdb_config.get('username', 'root')
32
+ password = iotdb_config.get('password', 'root')
33
+
34
+ # 建立连接
35
+ self.iotdb_client = Session(host, port, username, password)
36
+ self.iotdb_client.open()
37
+ except Exception as e:
38
+ # 连接失败时,将 iotdb_client 设置为 None,并记录错误信息
39
+ self.iotdb_client = None
40
+ self._connection_error = str(e)
41
+
42
+ def _check_connection(self):
43
+ """
44
+ 检查 IoTDB 连接状态
45
+ 如果连接失败,抛出异常
46
+ """
47
+ if self.iotdb_client is None:
48
+ error_msg = self._connection_error or "IoTDB 连接失败"
49
+ from flask import abort
50
+ from flask_babelplus import gettext
51
+ abort(500, gettext(f"IoTDB 连接失败: {error_msg}"))
52
+
53
+ def _get_data_type(self, data_type_str: str):
54
+ """
55
+ 获取数据类型常量
56
+ :param data_type_str: 数据类型字符串,如 'INT32', 'INT64', 'FLOAT', 'DOUBLE', 'TEXT', 'BOOLEAN', 'INT'
57
+ :return: TSDataType 常量
58
+ """
59
+ type_map = {
60
+ 'INT32': TSDataType.INT32,
61
+ 'INT64': TSDataType.INT64,
62
+ 'FLOAT': TSDataType.FLOAT,
63
+ 'DOUBLE': TSDataType.DOUBLE,
64
+ 'TEXT': TSDataType.TEXT,
65
+ 'BOOLEAN': TSDataType.BOOLEAN,
66
+ 'INT': TSDataType.INT64, # INT 映射到 INT64
67
+ }
68
+ return type_map.get(data_type_str.upper(), TSDataType.TEXT)
69
+
70
+ def create_device(self, device_path: str, measurements: list, data_types: list) -> bool:
71
+ """
72
+ 创建设备时序数据(如果时序已存在则跳过)
73
+ :param device_path: 设备路径,如 'root.inference.camera_1_inference'
74
+ :param measurements: 测量项列表
75
+ :param data_types: 数据类型列表
76
+ :return: 操作成功与否
77
+ """
78
+ self._check_connection()
79
+ try:
80
+ # 确保设备路径以 root 开头
81
+ if not device_path.startswith('root.'):
82
+ device_path = f'root.{device_path}'
83
+
84
+ created_count = 0
85
+ skipped_count = 0
86
+
87
+ # 为每个测量项创建时序
88
+ for measurement, data_type in zip(measurements, data_types):
89
+ # IoTDB 需要完整的路径格式:root.xxx.xxx.measurement
90
+ full_path = f"{device_path}.{measurement}"
91
+ # 将字符串类型转换为 IoTDB 数据类型
92
+ iotdb_data_type = self._get_data_type(data_type).name
93
+ create_sql = f"CREATE TIMESERIES {full_path} WITH DATATYPE={iotdb_data_type} ENCODING=PLAIN"
94
+
95
+ try:
96
+ # 使用 execute_non_query_statement 执行非查询语句
97
+ self.iotdb_client.execute_non_query_statement(create_sql)
98
+ created_count += 1
99
+ except Exception as e:
100
+ error_msg = str(e)
101
+ # 如果时序已存在(错误码 503),则跳过
102
+ if "already exist" in error_msg or "503" in error_msg:
103
+ skipped_count += 1
104
+ continue
105
+ else:
106
+ # 其他错误则抛出
107
+ raise
108
+
109
+ return True
110
+ except Exception as e:
111
+ return False
112
+
113
+ def insert_data(self, device_path: str, timestamp: int, measurements: list, types_lst: list, values: list) -> bool:
114
+ """
115
+ 插入数据
116
+ :param device_path: 设备路径,如 'root.inference.camera_1_inference'
117
+ :param timestamp: 时间戳(时序值,单位由 Config.TIMESTAMP_TO_MS_MULTIPLIER 决定)
118
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000,则为毫秒
119
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000000,则为微秒
120
+ :param measurements: 测量项列表
121
+ :param types_lst: 数据类型列表
122
+ :param values: 数据值列表(单条记录)
123
+ :return: 插入是否成功
124
+ """
125
+ self._check_connection()
126
+ try:
127
+ # 确保设备路径以 root 开头
128
+ if not device_path.startswith('root.'):
129
+ device_path = f'root.{device_path}'
130
+
131
+ # 将数据类型字符串转换为 TSDataType 常量
132
+ data_types = [self._get_data_type(dt) for dt in types_lst]
133
+
134
+ # 使用 insert_record 插入单条数据
135
+ # 参数顺序:device_path, timestamp, measurements, data_types, values
136
+ self.iotdb_client.insert_record(
137
+ device_path,
138
+ timestamp,
139
+ measurements,
140
+ data_types,
141
+ values
142
+ )
143
+ return True
144
+ except Exception as e:
145
+ return False
146
+
147
+ def _build_query_sql(self, device_path: str, start_time: Optional[int] = None,
148
+ end_time: Optional[int] = None, limit: Optional[int] = None,
149
+ order_by: Optional[str] = None, offset: Optional[int] = None,
150
+ enable_tracing: bool = False) -> str:
151
+ """
152
+ 构建查询 SQL 语句
153
+ :param device_path: 设备路径,支持通配符如 'root.inference.**'
154
+ :param start_time: 开始时间戳(时序值,单位由 Config.TIMESTAMP_TO_MS_MULTIPLIER 决定)
155
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000,则为毫秒
156
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000000,则为微秒
157
+ 通过时序值(timestamp)进行时间区间查询
158
+ :param end_time: 结束时间戳(时序值,单位由 Config.TIMESTAMP_TO_MS_MULTIPLIER 决定)
159
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000,则为毫秒
160
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000000,则为微秒
161
+ 通过时序值(timestamp)进行时间区间查询
162
+ :param limit: 返回结果数量限制
163
+ :param order_by: 排序方式,如 'time DESC' 或 'time ASC',默认为 None(不排序)
164
+ :param offset: 跳过前 N 行,用于分页查询
165
+ :param enable_tracing: 是否启用性能追踪(TRACING),用于分析查询性能
166
+ :return: SQL 语句
167
+ """
168
+ # 确保设备路径以 root 开头
169
+ if not device_path.startswith('root.'):
170
+ device_path = f'root.{device_path}'
171
+
172
+ # 构建 WHERE 子句
173
+ where_parts = []
174
+
175
+ # 时间区间查询:使用时序值(timestamp)进行过滤
176
+ # IoTDB 的 time 字段是时序值,这是最有效的查询方式
177
+ if start_time is not None:
178
+ where_parts.append(f"time >= {start_time}")
179
+ if end_time is not None:
180
+ where_parts.append(f"time <= {end_time}")
181
+
182
+ # 注意:IoTDB 的 WHERE 子句主要用于时间范围查询(通过时序值 timestamp)
183
+ # 对于测量值的过滤,IoTDB 支持有限,通常需要在应用层(内存中)进行过滤
184
+ # 如果需要过滤测量值,建议在查询结果返回后在应用层进行过滤
185
+
186
+ where_clause = f" WHERE {' AND '.join(where_parts)}" if where_parts else ""
187
+
188
+ # 构建 ORDER BY 子句
189
+ order_by_clause = f" ORDER BY {order_by}" if order_by else ""
190
+
191
+ # 构建 LIMIT 和 OFFSET 子句
192
+ # IoTDB 支持 LIMIT N OFFSET M 语法进行分页查询
193
+ if limit is not None:
194
+ if offset is not None and offset > 0:
195
+ limit_clause = f" LIMIT {limit} OFFSET {offset}"
196
+ else:
197
+ limit_clause = f" LIMIT {limit}"
198
+ else:
199
+ limit_clause = ""
200
+
201
+ # 使用 SELECT * 语法,支持通配符路径
202
+ # IoTDB 支持使用 ** 进行递归查询
203
+ # 注意:在 IoTDB 中,SELECT * FROM device_path 会自动查询该设备下的所有测量值
204
+ # 不需要添加 .* 后缀,添加 .* 反而可能导致查询失败
205
+ # 如果路径已经以 .* 结尾,去掉它
206
+ if device_path.endswith('.*'):
207
+ device_path = device_path[:-2]
208
+
209
+ # 如果启用追踪,在 SQL 前添加 TRACING 关键词
210
+ tracing_prefix = "TRACING " if enable_tracing else ""
211
+ sql = f"{tracing_prefix}SELECT * FROM {device_path}{where_clause}{order_by_clause}{limit_clause}"
212
+ return sql.strip()
213
+
214
+ @staticmethod
215
+ def _extract_measurement_name(col_name: str) -> str:
216
+ """
217
+ 从列名提取测量值名称(移除设备路径前缀)
218
+ :param col_name: 列名,如 'root.inference.camera_1_inference.frame_stamp'
219
+ :return: 测量值名称,如 'frame_stamp'
220
+ """
221
+ return col_name.split('.')[-1] if '.' in col_name else col_name
222
+
223
+ def _convert_field_value(self, field_obj, data_type) -> Any:
224
+ """
225
+ 根据数据类型转换字段值为 Python 原生类型
226
+ :param field_obj: IoTDB 字段对象
227
+ :param data_type: 数据类型
228
+ :return: 转换后的值
229
+ """
230
+ try:
231
+ if field_obj.is_null():
232
+ return None
233
+
234
+ if data_type == TSDataType.BOOLEAN:
235
+ return bool(field_obj.get_bool_value())
236
+ elif data_type == TSDataType.INT32:
237
+ return int(field_obj.get_int_value())
238
+ elif data_type == TSDataType.INT64:
239
+ return int(field_obj.get_long_value())
240
+ elif data_type == TSDataType.FLOAT:
241
+ return float(field_obj.get_float_value())
242
+ elif data_type == TSDataType.DOUBLE:
243
+ return float(field_obj.get_double_value())
244
+ elif data_type == TSDataType.TEXT:
245
+ return str(field_obj.get_string_value())
246
+ else:
247
+ value = field_obj.get_object_value(data_type)
248
+ if value is not None:
249
+ type_name = value.__class__.__name__.lower()
250
+ if 'int' in type_name:
251
+ return int(value)
252
+ elif 'float' in type_name or 'double' in type_name:
253
+ return float(value)
254
+ elif 'bool' in type_name:
255
+ return bool(value)
256
+ elif not isinstance(value, (str, int, float, bool, type(None))):
257
+ return str(value)
258
+ return value
259
+ except Exception:
260
+ return None
261
+
262
+ def _parse_query_result(self, session_data_set, measurements: Optional[List[str]] = None) -> List[Dict[str, Any]]:
263
+ """
264
+ 解析查询结果集
265
+ :param session_data_set: IoTDB 查询结果集
266
+ :param measurements: 要查询的测量值列表,如果为 None 则查询所有测量值
267
+ :return: 查询结果列表
268
+ """
269
+ results = []
270
+ column_names = session_data_set.get_column_names()
271
+
272
+ # 如果指定了 measurements,转换为集合以提高查找效率
273
+ measurements_set = set(measurements) if measurements else None
274
+
275
+ while session_data_set.has_next():
276
+ row = session_data_set.next()
277
+ # 确保 timestamp 是整数类型
278
+ timestamp = row.get_timestamp()
279
+ record = {'timestamp': int(timestamp) if timestamp is not None else None}
280
+ fields = row.get_fields()
281
+
282
+ # 构建列名到字段值的映射(不包括 Time 列)
283
+ col_name_to_field = {}
284
+ field_index = 0
285
+ for col_name in column_names:
286
+ if col_name == 'Time':
287
+ continue
288
+
289
+ if field_index < len(fields):
290
+ col_name_to_field[col_name] = fields[field_index]
291
+ field_index += 1
292
+
293
+ # 遍历所有列名(除了 Time),提取 measurement 名称并处理值
294
+ for col_name in column_names:
295
+ if col_name == 'Time':
296
+ continue
297
+
298
+ if col_name not in col_name_to_field:
299
+ continue
300
+
301
+ field_obj = col_name_to_field[col_name]
302
+ data_type = field_obj.get_data_type()
303
+
304
+ # 转换字段值
305
+ value = self._convert_field_value(field_obj, data_type)
306
+
307
+ # 提取测量值名称
308
+ measurement_name = self._extract_measurement_name(col_name)
309
+
310
+ # 如果指定了 measurements,只处理指定的测量值
311
+ if measurements_set is None or measurement_name in measurements_set:
312
+ # 对于同一个 measurement_name,优先保留非 None 值
313
+ if measurement_name in record:
314
+ if record[measurement_name] is not None:
315
+ if value is not None:
316
+ pass # 保留旧值
317
+ else:
318
+ record[measurement_name] = value
319
+ else:
320
+ record[measurement_name] = value
321
+
322
+ results.append(record)
323
+
324
+ return results
325
+
326
+ def list_timeseries(self, path_pattern: str = "root.**") -> List[str]:
327
+ """
328
+ 列出所有时序路径
329
+ :param path_pattern: 路径模式,如 'root.inference.**'
330
+ :return: 时序路径列表
331
+ """
332
+ self._check_connection()
333
+ try:
334
+ # 确保路径以 root 开头
335
+ if not path_pattern.startswith('root.'):
336
+ path_pattern = f'root.{path_pattern}'
337
+
338
+ # 使用 SHOW TIMESERIES 查询
339
+ # IoTDB 的 SHOW TIMESERIES 语法:SHOW TIMESERIES [pathPattern]
340
+ sql = f"SHOW TIMESERIES {path_pattern}"
341
+
342
+ session_data_set = self.iotdb_client.execute_query_statement(sql)
343
+ session_data_set.set_fetch_size(10000)
344
+
345
+ timeseries_list = []
346
+ while session_data_set.has_next():
347
+ row = session_data_set.next()
348
+ # SHOW TIMESERIES 返回的列:timeseries, alias, storage group, dataType, encoding, compression, tags, attributes
349
+ fields = row.get_fields()
350
+ if fields and len(fields) > 0:
351
+ timeseries_path = fields[0].get_string_value()
352
+ timeseries_list.append(timeseries_path)
353
+
354
+ session_data_set.close_operation_handle()
355
+ return timeseries_list
356
+ except Exception as e:
357
+ return []
358
+
359
+ def query_count(self, device_path: str, start_time: Optional[int] = None,
360
+ end_time: Optional[int] = None) -> int:
361
+ """
362
+ 使用 COUNT 聚合查询获取记录总数(优化性能)
363
+ :param device_path: 设备路径,如 'root.inference.camera_1_inference' 或 'root.inference.**'
364
+ :param start_time: 开始时间戳(时序值)
365
+ :param end_time: 结束时间戳(时序值)
366
+ :return: 记录总数,如果查询失败返回 0
367
+ """
368
+ self._check_connection()
369
+ try:
370
+ # 确保设备路径以 root 开头
371
+ if not device_path.startswith('root.'):
372
+ device_path = f'root.{device_path}'
373
+
374
+ # 构建 WHERE 子句
375
+ where_parts = []
376
+ if start_time is not None:
377
+ where_parts.append(f"time >= {start_time}")
378
+ if end_time is not None:
379
+ where_parts.append(f"time <= {end_time}")
380
+ where_clause = f" WHERE {' AND '.join(where_parts)}" if where_parts else ""
381
+
382
+ # 构建 COUNT 查询 SQL
383
+ # 注意:IoTDB 的 COUNT 查询需要指定具体的测量值,不能使用 COUNT(*)
384
+ # 对于通配符路径,需要指定一个具体的测量值,比如第一个测量值
385
+ # 这里尝试使用一个常见的测量值(如 frame_stamp)来统计记录数
386
+ # 如果 device_path 包含通配符,需要先获取一个具体的测量值
387
+ if '**' in device_path or '*' in device_path:
388
+ # 对于通配符路径,尝试使用 COUNT(第一个测量值)
389
+ # 先尝试使用 frame_stamp(推理日志中常见的字段)
390
+ sql = f"SELECT COUNT(frame_stamp) FROM {device_path}{where_clause}"
391
+ else:
392
+ # 对于具体路径,可以使用任意测量值
393
+ sql = f"SELECT COUNT(frame_stamp) FROM {device_path}{where_clause}"
394
+
395
+ # 执行查询
396
+ session_data_set = self.iotdb_client.execute_query_statement(sql)
397
+ session_data_set.set_fetch_size(10000)
398
+
399
+ # 解析结果
400
+ count = 0
401
+ if session_data_set.has_next():
402
+ row = session_data_set.next()
403
+ fields = row.get_fields()
404
+ if fields and len(fields) > 0:
405
+ # COUNT 查询返回的是聚合结果
406
+ count_value = fields[0].get_long_value() if hasattr(fields[0], 'get_long_value') else fields[0].get_int_value()
407
+ count = int(count_value) if count_value is not None else 0
408
+
409
+ session_data_set.close_operation_handle()
410
+ return count
411
+ except Exception as e:
412
+ return -1 # 返回 -1 表示 COUNT 查询失败,需要使用其他方法
413
+
414
+ def query_data(self, device_path: str, measurements: Optional[List[str]] = None,
415
+ start_time: Optional[int] = None, end_time: Optional[int] = None,
416
+ limit: Optional[int] = None, order_by: Optional[str] = None,
417
+ offset: Optional[int] = None, enable_tracing: bool = False) -> List[Dict[str, Any]]:
418
+ """
419
+ 查询数据
420
+ :param device_path: 设备路径,如 'root.inference.camera_1_inference' 或 'root.inference.**'
421
+ :param measurements: 要查询的测量值列表,如果为 None 则查询所有测量值
422
+ :param start_time: 开始时间戳(时序值,单位由 Config.TIMESTAMP_TO_MS_MULTIPLIER 决定)
423
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000,则为毫秒
424
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000000,则为微秒
425
+ 通过时序值(timestamp)进行时间区间查询,如果为 None 则不限制开始时间
426
+ :param end_time: 结束时间戳(时序值,单位由 Config.TIMESTAMP_TO_MS_MULTIPLIER 决定)
427
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000,则为毫秒
428
+ 如果 TIMESTAMP_TO_MS_MULTIPLIER = 1000000,则为微秒
429
+ 通过时序值(timestamp)进行时间区间查询,如果为 None 则不限制结束时间
430
+ :param limit: 返回结果数量限制
431
+ :param order_by: 排序方式,如 'time DESC' 或 'time ASC',默认为 None(不排序)
432
+ :param offset: 跳过前 N 行,用于分页查询
433
+ :param enable_tracing: 是否启用性能追踪(TRACING),用于分析查询性能
434
+ :return: 查询结果列表,每个元素是一个字典,包含 timestamp 和各个测量值
435
+ """
436
+ self._check_connection()
437
+ try:
438
+ # 构建 SQL 语句
439
+ sql = self._build_query_sql(device_path, start_time, end_time, limit, order_by, offset, enable_tracing)
440
+
441
+ # 执行查询
442
+ session_data_set = self.iotdb_client.execute_query_statement(sql)
443
+ session_data_set.set_fetch_size(10000)
444
+
445
+ # 解析结果
446
+ results = self._parse_query_result(session_data_set, measurements)
447
+
448
+ session_data_set.close_operation_handle()
449
+
450
+ return results
451
+ except Exception as e:
452
+ return []
453
+
454
+ def delete_data(self, device_path: str, start_time: Optional[int] = None,
455
+ end_time: Optional[int] = None, measurements: Optional[List[str]] = None) -> bool:
456
+ """
457
+ 删除数据
458
+ :param device_path: 设备路径,如 'root.inference.camera_1_inference' 或 'root.inference.**'
459
+ :param start_time: 开始时间戳(毫秒),如果为 None 则删除所有数据
460
+ :param end_time: 结束时间戳(毫秒),如果为 None 则删除到最新
461
+ :param measurements: 要删除的测量值列表,如果为 None 则删除所有测量值
462
+ :return: 删除是否成功
463
+ """
464
+ self._check_connection()
465
+ try:
466
+ # 确保设备路径以 root 开头
467
+ if not device_path.startswith('root.'):
468
+ device_path = f'root.{device_path}'
469
+
470
+ # 如果使用通配符路径,需要先列出所有时序路径,然后逐个删除
471
+ if '**' in device_path or '*' in device_path:
472
+ # 列出所有时序路径
473
+ timeseries_list = self.list_timeseries(device_path)
474
+
475
+ if not timeseries_list:
476
+ return True # 没有数据可删,返回成功
477
+
478
+ # 提取所有唯一的设备路径(用于统计)
479
+ device_paths = set()
480
+ for ts_path in timeseries_list:
481
+ # 时序路径格式:root.inference.camera_1_inference.frame_stamp
482
+ # 提取设备路径:root.inference.camera_1_inference
483
+ parts = ts_path.split('.')
484
+ if len(parts) >= 3:
485
+ device_path_extracted = '.'.join(parts[:3])
486
+ device_paths.add(device_path_extracted)
487
+
488
+ # 如果指定了 measurements,只删除指定的测量值
489
+ # 否则删除所有时序路径
490
+ if measurements:
491
+ # 只删除指定测量值的时序路径
492
+ paths_to_delete = []
493
+ for ts_path in timeseries_list:
494
+ measurement_name = ts_path.split('.')[-1] # 获取测量值名称
495
+ if measurement_name in measurements:
496
+ paths_to_delete.append(ts_path)
497
+ else:
498
+ # 删除所有时序路径
499
+ paths_to_delete = timeseries_list
500
+
501
+ # 按设备路径分组删除(更高效)
502
+ device_path_to_timeseries = {}
503
+ for ts_path in paths_to_delete:
504
+ parts = ts_path.split('.')
505
+ if len(parts) >= 3:
506
+ dev_path = '.'.join(parts[:3])
507
+ if dev_path not in device_path_to_timeseries:
508
+ device_path_to_timeseries[dev_path] = []
509
+ device_path_to_timeseries[dev_path].append(ts_path)
510
+
511
+ # 直接删除所有时序路径(IoTDB 的 DELETE FROM 需要精确的时序路径)
512
+ # 因为时序路径格式复杂(如 root.inference.camera_1.model_5.tag_1.xxx),
513
+ # 删除设备路径可能无法删除子路径数据,所以直接删除所有时序路径
514
+ # 注意:IoTDB 的 DELETE FROM 只删除数据点,不删除时序路径定义
515
+ for ts_path in paths_to_delete:
516
+ try:
517
+ if start_time is not None and end_time is not None:
518
+ delete_sql = f"DELETE FROM {ts_path} WHERE time >= {start_time} AND time <= {end_time}"
519
+ elif start_time is not None:
520
+ delete_sql = f"DELETE FROM {ts_path} WHERE time >= {start_time}"
521
+ elif end_time is not None:
522
+ delete_sql = f"DELETE FROM {ts_path} WHERE time <= {end_time}"
523
+ else:
524
+ # 删除所有数据,使用 DELETE FROM 或 DELETE DATABASE
525
+ # 对于单个时序路径,使用 DELETE FROM
526
+ delete_sql = f"DELETE FROM {ts_path}"
527
+
528
+ self.iotdb_client.execute_non_query_statement(delete_sql)
529
+ except Exception as e:
530
+ pass
531
+ else:
532
+ # 构建删除路径列表
533
+ if measurements:
534
+ # 删除指定测量值
535
+ paths = [f"{device_path}.{measurement}" for measurement in measurements]
536
+ else:
537
+ # 删除整个设备的所有数据
538
+ paths = [device_path]
539
+
540
+ # 构建删除 SQL
541
+ if start_time is not None and end_time is not None:
542
+ # 删除指定时间范围的数据
543
+ for path in paths:
544
+ delete_sql = f"DELETE FROM {path} WHERE time >= {start_time} AND time <= {end_time}"
545
+ self.iotdb_client.execute_non_query_statement(delete_sql)
546
+ elif start_time is not None:
547
+ # 删除从开始时间到现在的数据
548
+ for path in paths:
549
+ delete_sql = f"DELETE FROM {path} WHERE time >= {start_time}"
550
+ self.iotdb_client.execute_non_query_statement(delete_sql)
551
+ elif end_time is not None:
552
+ # 删除到结束时间的数据
553
+ for path in paths:
554
+ delete_sql = f"DELETE FROM {path} WHERE time <= {end_time}"
555
+ self.iotdb_client.execute_non_query_statement(delete_sql)
556
+ else:
557
+ # 删除所有数据
558
+ for path in paths:
559
+ delete_sql = f"DELETE FROM {path}"
560
+ self.iotdb_client.execute_non_query_statement(delete_sql)
561
+
562
+ return True
563
+ except Exception as e:
564
+ return False
565
+
566
+ def clear_all_data(self, path_pattern: str = "root.inference.**") -> bool:
567
+ """
568
+ 清空所有数据
569
+ :param path_pattern: 路径模式,如 'root.inference.**'
570
+ :return: 清空是否成功
571
+ """
572
+ self._check_connection()
573
+ try:
574
+ # 列出所有时序路径
575
+ timeseries_list = self.list_timeseries(path_pattern)
576
+
577
+ if not timeseries_list:
578
+ return True
579
+
580
+ # 提取所有唯一的设备路径
581
+ device_paths = set()
582
+ for ts_path in timeseries_list:
583
+ parts = ts_path.split('.')
584
+ if len(parts) >= 3:
585
+ device_path = '.'.join(parts[:3])
586
+ device_paths.add(device_path)
587
+
588
+ # 逐个清空每个设备的所有数据
589
+ for device_path in device_paths:
590
+ try:
591
+ delete_sql = f"DELETE FROM {device_path}"
592
+ self.iotdb_client.execute_non_query_statement(delete_sql)
593
+ except Exception as e:
594
+ pass
595
+
596
+ return True
597
+ except Exception as e:
598
+ return False
599
+
600
+ def delete_timeseries(self, path_pattern: str) -> bool:
601
+ """
602
+ 删除时序路径定义(删除路径结构,不仅仅是数据)
603
+ :param path_pattern: 路径模式,支持通配符,如 'root.inference.**' 或 'root.inference.camera_1.label_2.**'
604
+ :return: 删除是否成功
605
+ """
606
+ self._check_connection()
607
+ try:
608
+ # 确保路径以 root 开头
609
+ if not path_pattern.startswith('root.'):
610
+ path_pattern = f'root.{path_pattern}'
611
+
612
+ # 如果使用通配符路径,需要先列出所有时序路径,然后逐个删除
613
+ if '**' in path_pattern or '*' in path_pattern:
614
+ # 列出所有匹配的时序路径
615
+ timeseries_list = self.list_timeseries(path_pattern)
616
+
617
+ if not timeseries_list:
618
+ return True # 没有路径可删,返回成功
619
+
620
+ # 逐个删除每个时序路径
621
+ for ts_path in timeseries_list:
622
+ try:
623
+ delete_sql = f"DELETE TIMESERIES {ts_path}"
624
+ self.iotdb_client.execute_non_query_statement(delete_sql)
625
+ except Exception as e:
626
+ error_msg = str(e)
627
+ # 如果路径不存在(508错误)或由设备模板表示,视为成功(幂等性)
628
+ if "508" in error_msg or "does not exist" in error_msg or "device template" in error_msg.lower():
629
+ continue
630
+ # 其他错误记录警告但继续删除其他路径
631
+ continue
632
+ else:
633
+ # 对于具体路径,判断是设备路径还是时序路径
634
+ # 先尝试列出该路径下的所有时序路径(使用通配符)
635
+ # 如果路径以 .** 结尾,直接使用;否则添加 .** 来匹配该路径下的所有时序路径
636
+ if path_pattern.endswith('.**'):
637
+ search_pattern = path_pattern
638
+ else:
639
+ # 对于设备路径(如 root.inference.camera_1.tag_1),添加 .** 来匹配所有时序路径
640
+ search_pattern = f"{path_pattern}.**"
641
+
642
+ # 列出该路径下的所有时序路径
643
+ timeseries_list = self.list_timeseries(search_pattern)
644
+
645
+ if not timeseries_list:
646
+ # 如果没有找到时序路径,可能是:
647
+ # 1. 路径不存在(已删除)
648
+ # 2. 传入的是完整的时序路径,尝试直接删除
649
+ if not path_pattern.endswith('.**'):
650
+ # 尝试作为完整的时序路径直接删除
651
+ try:
652
+ delete_sql = f"DELETE TIMESERIES {path_pattern}"
653
+ self.iotdb_client.execute_non_query_statement(delete_sql)
654
+ return True
655
+ except Exception as e:
656
+ error_msg = str(e)
657
+ # 如果路径不存在(508错误)或由设备模板表示,视为成功(幂等性)
658
+ if "508" in error_msg or "does not exist" in error_msg or "device template" in error_msg.lower():
659
+ return True
660
+ # 其他错误才视为失败
661
+ return False
662
+ else:
663
+ # 路径下没有时序路径,视为删除成功
664
+ return True
665
+
666
+ # 逐个删除每个时序路径
667
+ success_count = 0
668
+ fail_count = 0
669
+ for ts_path in timeseries_list:
670
+ try:
671
+ delete_sql = f"DELETE TIMESERIES {ts_path}"
672
+ self.iotdb_client.execute_non_query_statement(delete_sql)
673
+ success_count += 1
674
+ except Exception as e:
675
+ error_msg = str(e)
676
+ # 如果路径不存在(508错误)或由设备模板表示,视为成功(幂等性)
677
+ if "508" in error_msg or "does not exist" in error_msg or "device template" in error_msg.lower():
678
+ success_count += 1
679
+ else:
680
+ # 其他错误记录警告
681
+ fail_count += 1
682
+
683
+ # 如果至少有一个成功,或者所有都因为不存在而跳过,视为成功
684
+ if success_count > 0 or fail_count == 0:
685
+ return True
686
+ else:
687
+ return False
688
+
689
+ return True
690
+ except Exception as e:
691
+ return False
692
+
693
+ def close_connection(self):
694
+ """关闭 IoTDB 连接"""
695
+ try:
696
+ self.iotdb_client.close()
697
+ except Exception as e:
698
+ pass