smart-admin-web 10.15.0 → 10.20.0

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 (432) hide show
  1. package/README.md +1 -1
  2. package/dist/api/index.d.ts +4 -2
  3. package/dist/api/index.js +1 -1
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/schema.d.ts +39 -5
  6. package/dist/assets/icons/ph-subset.json.js +5 -5
  7. package/dist/components/AppIcon.vue.js +9 -9
  8. package/dist/components/AppIcon.vue.js.map +1 -1
  9. package/dist/components/AppWatermark.vue.d.ts +14 -0
  10. package/dist/components/AppWatermark.vue.js +38 -0
  11. package/dist/components/AppWatermark.vue.js.map +1 -0
  12. package/dist/components/AppWatermark2.vue.js +5 -0
  13. package/dist/components/AppWatermark2.vue.js.map +1 -0
  14. package/dist/components/Chart/PieChart.vue.d.ts +1 -1
  15. package/dist/components/Chart/echarts.js +15 -20
  16. package/dist/components/Chart/echarts.js.map +1 -1
  17. package/dist/components/CronEditor/index.vue.js +1 -1
  18. package/dist/components/CronEditor/index2.vue.js +2 -1
  19. package/dist/components/CronEditor/index2.vue.js.map +1 -1
  20. package/dist/components/DetailPage/index.vue.js +2 -2
  21. package/dist/components/DetailPage/index2.vue.js.map +1 -1
  22. package/dist/components/DictTag/index.vue.js.map +1 -1
  23. package/dist/components/ErrorBoundary/index.vue.js +2 -2
  24. package/dist/components/ErrorBoundary/index2.vue.js +1 -1
  25. package/dist/components/ErrorBoundary/index2.vue.js.map +1 -1
  26. package/dist/components/FormContainer/index.vue.js +91 -56
  27. package/dist/components/FormContainer/index.vue.js.map +1 -1
  28. package/dist/components/ImportWizard/index.vue.js +1 -1
  29. package/dist/components/ImportWizard/index2.vue.js +44 -41
  30. package/dist/components/ImportWizard/index2.vue.js.map +1 -1
  31. package/dist/components/MenuSearch.vue.js +2 -2
  32. package/dist/components/MenuSearch2.vue.js +19 -18
  33. package/dist/components/MenuSearch2.vue.js.map +1 -1
  34. package/dist/components/PasswordStrength/index.vue.js +2 -2
  35. package/dist/components/PasswordStrength/index2.vue.js +20 -18
  36. package/dist/components/PasswordStrength/index2.vue.js.map +1 -1
  37. package/dist/components/TableTotal/index.vue.d.ts +6 -0
  38. package/dist/components/{SelectTable → TableTotal}/index.vue.js +1 -1
  39. package/dist/components/TableTotal/index2.vue.js +16 -0
  40. package/dist/components/TableTotal/index2.vue.js.map +1 -0
  41. package/dist/components/TableZoomButton/index.vue.js.map +1 -1
  42. package/dist/components/UserPicker/index.vue.js +2 -2
  43. package/dist/components/UserPicker/index2.vue.js +176 -117
  44. package/dist/components/UserPicker/index2.vue.js.map +1 -1
  45. package/dist/composables/useBatchDelete.js.map +1 -1
  46. package/dist/composables/useLayoutMenu.js +17 -16
  47. package/dist/composables/useLayoutMenu.js.map +1 -1
  48. package/dist/composables/useModule.js +39 -29
  49. package/dist/composables/useModule.js.map +1 -1
  50. package/dist/composables/useShellBreakpoint.d.ts +19 -0
  51. package/dist/composables/useShellBreakpoint.js +37 -0
  52. package/dist/composables/useShellBreakpoint.js.map +1 -0
  53. package/dist/composables/useSite.d.ts +15 -0
  54. package/dist/composables/useSite.js +16 -14
  55. package/dist/composables/useSite.js.map +1 -1
  56. package/dist/composables/useTabTitle.js.map +1 -1
  57. package/dist/composables/useTableTitle.d.ts +6 -0
  58. package/dist/composables/useTableTitle.js +11 -0
  59. package/dist/composables/useTableTitle.js.map +1 -0
  60. package/dist/composables/useTableZoom.d.ts +5 -0
  61. package/dist/composables/useTableZoom.js.map +1 -1
  62. package/dist/composables/useTheme.d.ts +2 -2
  63. package/dist/composables/useTheme.js +23 -20
  64. package/dist/composables/useTheme.js.map +1 -1
  65. package/dist/createSmartAdmin.d.ts +12 -2
  66. package/dist/createSmartAdmin.js +72 -60
  67. package/dist/createSmartAdmin.js.map +1 -1
  68. package/dist/index.d.ts +5 -2
  69. package/dist/index.js +219 -205
  70. package/dist/index.js.map +1 -1
  71. package/dist/layouts/AccentPicker.vue.js +8 -0
  72. package/dist/layouts/AccentPicker.vue.js.map +1 -0
  73. package/dist/layouts/AccentPicker2.vue.js +131 -0
  74. package/dist/layouts/AccentPicker2.vue.js.map +1 -0
  75. package/dist/layouts/AppHeader.vue.d.ts +8 -1
  76. package/dist/layouts/AppHeader.vue.js +2 -2
  77. package/dist/layouts/AppHeader2.vue.js +317 -235
  78. package/dist/layouts/AppHeader2.vue.js.map +1 -1
  79. package/dist/layouts/NoticeBell.vue.js +2 -2
  80. package/dist/layouts/NoticeBell2.vue.js +1 -1
  81. package/dist/layouts/NoticeBell2.vue.js.map +1 -1
  82. package/dist/layouts/PersonalLayout.vue.js +2 -2
  83. package/dist/layouts/PersonalLayout2.vue.js +69 -47
  84. package/dist/layouts/PersonalLayout2.vue.js.map +1 -1
  85. package/dist/layouts/SettingsDrawer.vue.js +3 -3
  86. package/dist/layouts/SettingsDrawer2.vue.js +261 -325
  87. package/dist/layouts/SettingsDrawer2.vue.js.map +1 -1
  88. package/dist/layouts/TabsBar.vue.js +2 -2
  89. package/dist/layouts/TabsBar2.vue.js +97 -69
  90. package/dist/layouts/TabsBar2.vue.js.map +1 -1
  91. package/dist/layouts/components/SideNav.vue.d.ts +3 -0
  92. package/dist/layouts/components/SideNav.vue.js +1 -1
  93. package/dist/layouts/components/SideNav2.vue.js +54 -26
  94. package/dist/layouts/components/SideNav2.vue.js.map +1 -1
  95. package/dist/layouts/default.vue.js +1 -1
  96. package/dist/layouts/default2.vue.js +170 -140
  97. package/dist/layouts/default2.vue.js.map +1 -1
  98. package/dist/lib/loginHero.d.ts +2 -2
  99. package/dist/lib/loginHero.js.map +1 -1
  100. package/dist/lib/runtime.js +1 -1
  101. package/dist/lib/watermark.d.ts +110 -0
  102. package/dist/lib/watermark.js +151 -0
  103. package/dist/lib/watermark.js.map +1 -0
  104. package/dist/locales/en-US.d.ts +221 -15
  105. package/dist/locales/en-US.js +230 -21
  106. package/dist/locales/en-US.js.map +1 -1
  107. package/dist/locales/kernelMenuTitles.d.ts +1 -0
  108. package/dist/locales/kernelMenuTitles.js +128 -0
  109. package/dist/locales/kernelMenuTitles.js.map +1 -0
  110. package/dist/locales/menuTitle.d.ts +3 -0
  111. package/dist/locales/menuTitle.js +14 -12
  112. package/dist/locales/menuTitle.js.map +1 -1
  113. package/dist/locales/zh-CN.d.ts +221 -15
  114. package/dist/locales/zh-CN.js +238 -28
  115. package/dist/locales/zh-CN.js.map +1 -1
  116. package/dist/router/index.js +41 -32
  117. package/dist/router/index.js.map +1 -1
  118. package/dist/router/namedPage.d.ts +4 -0
  119. package/dist/router/namedPage.js +7 -7
  120. package/dist/router/namedPage.js.map +1 -1
  121. package/dist/router/viewRegistry.js +8 -8
  122. package/dist/router/viewRegistry.js.map +1 -1
  123. package/dist/stores/app.d.ts +0 -12
  124. package/dist/stores/app.js +11 -12
  125. package/dist/stores/app.js.map +1 -1
  126. package/dist/stores/tabs.js.map +1 -1
  127. package/dist/stores/user.d.ts +10 -0
  128. package/dist/stores/user.js.map +1 -1
  129. package/dist/style.css +1 -1
  130. package/dist/theme/accentTokens.d.ts +27 -0
  131. package/dist/theme/accentTokens.js +54 -0
  132. package/dist/theme/accentTokens.js.map +1 -0
  133. package/dist/theme/accents.d.ts +21 -1
  134. package/dist/theme/accents.js +11 -2
  135. package/dist/theme/accents.js.map +1 -1
  136. package/dist/theme/mix.d.ts +58 -7
  137. package/dist/theme/mix.js +115 -30
  138. package/dist/theme/mix.js.map +1 -1
  139. package/dist/theme/naive-theme.d.ts +5 -2
  140. package/dist/theme/naive-theme.js +405 -75
  141. package/dist/theme/naive-theme.js.map +1 -1
  142. package/dist/utils/jwt.d.ts +8 -0
  143. package/dist/utils/jwt.js +14 -0
  144. package/dist/utils/jwt.js.map +1 -0
  145. package/dist/utils/menuIcon.d.ts +2 -0
  146. package/dist/utils/menuIcon.js +8 -0
  147. package/dist/utils/menuIcon.js.map +1 -0
  148. package/dist/utils/oauthBrand.js.map +1 -1
  149. package/dist/utils/tableFilter.d.ts +88 -0
  150. package/dist/utils/tableFilter.js +116 -0
  151. package/dist/utils/tableFilter.js.map +1 -0
  152. package/dist/utils/tableToolbar.d.ts +18 -0
  153. package/dist/utils/tableToolbar.js +11 -0
  154. package/dist/utils/tableToolbar.js.map +1 -0
  155. package/dist/utils/treeFilter.d.ts +20 -0
  156. package/dist/utils/treeFilter.js +24 -0
  157. package/dist/utils/treeFilter.js.map +1 -0
  158. package/dist/views/dashboard/ShortcutPicker.vue.js +1 -1
  159. package/dist/views/dashboard/ShortcutPicker2.vue.js +73 -48
  160. package/dist/views/dashboard/ShortcutPicker2.vue.js.map +1 -1
  161. package/dist/views/dashboard/biz.vue.js +1 -1
  162. package/dist/views/dashboard/biz2.vue.js +310 -257
  163. package/dist/views/dashboard/biz2.vue.js.map +1 -1
  164. package/dist/views/dashboard/workbench.vue.js +2 -2
  165. package/dist/views/dashboard/workbench2.vue.js +141 -155
  166. package/dist/views/dashboard/workbench2.vue.js.map +1 -1
  167. package/dist/views/embed/iframe.vue.js +2 -2
  168. package/dist/views/embed/iframe2.vue.js +22 -15
  169. package/dist/views/embed/iframe2.vue.js.map +1 -1
  170. package/dist/views/error/404.vue.js +2 -2
  171. package/dist/views/error/4042.vue.js +33 -24
  172. package/dist/views/error/4042.vue.js.map +1 -1
  173. package/dist/views/error/BootError.vue.js +1 -1
  174. package/dist/views/error/BootError2.vue.js +59 -48
  175. package/dist/views/error/BootError2.vue.js.map +1 -1
  176. package/dist/views/error/MissingRoute.vue.js +2 -2
  177. package/dist/views/error/MissingRoute2.vue.js +34 -15
  178. package/dist/views/error/MissingRoute2.vue.js.map +1 -1
  179. package/dist/views/login/LoginForm.vue.d.ts +7 -1
  180. package/dist/views/login/LoginForm.vue.js +2 -2
  181. package/dist/views/login/LoginForm2.vue.js +580 -488
  182. package/dist/views/login/LoginForm2.vue.js.map +1 -1
  183. package/dist/views/login/components/LoginDesk.vue.d.ts +36 -0
  184. package/dist/views/login/components/LoginDesk.vue.js +9 -0
  185. package/dist/views/login/components/LoginDesk.vue.js.map +1 -0
  186. package/dist/views/login/components/LoginDesk2.vue.js +100 -0
  187. package/dist/views/login/components/LoginDesk2.vue.js.map +1 -0
  188. package/dist/views/login/components/LoginHeroPanel.vue.js +3 -3
  189. package/dist/views/login/components/LoginHeroPanel2.vue.js +34 -39
  190. package/dist/views/login/components/LoginHeroPanel2.vue.js.map +1 -1
  191. package/dist/views/login/index.vue.js +1 -1
  192. package/dist/views/login/index2.vue.js +141 -71
  193. package/dist/views/login/index2.vue.js.map +1 -1
  194. package/dist/views/login/layout.d.ts +11 -0
  195. package/dist/views/login/layout.js +27 -0
  196. package/dist/views/login/layout.js.map +1 -0
  197. package/dist/views/mfa/index.vue.js +2 -2
  198. package/dist/views/mfa/index2.vue.js +367 -321
  199. package/dist/views/mfa/index2.vue.js.map +1 -1
  200. package/dist/views/module/index.vue.js +2 -2
  201. package/dist/views/module/index2.vue.js +132 -99
  202. package/dist/views/module/index2.vue.js.map +1 -1
  203. package/dist/views/oauth/callback.vue.js +2 -2
  204. package/dist/views/oauth/callback2.vue.js +65 -51
  205. package/dist/views/oauth/callback2.vue.js.map +1 -1
  206. package/dist/views/personal/bindings.vue.js +2 -2
  207. package/dist/views/personal/bindings2.vue.js +98 -94
  208. package/dist/views/personal/bindings2.vue.js.map +1 -1
  209. package/dist/views/personal/notice2.vue.js +103 -76
  210. package/dist/views/personal/notice2.vue.js.map +1 -1
  211. package/dist/views/personal/password2.vue.js +47 -40
  212. package/dist/views/personal/password2.vue.js.map +1 -1
  213. package/dist/views/personal/profile.vue.js +3 -3
  214. package/dist/views/personal/profile2.vue.js +24 -18
  215. package/dist/views/personal/profile2.vue.js.map +1 -1
  216. package/dist/views/personal/security.vue.js +2 -2
  217. package/dist/views/personal/security2.vue.js +65 -53
  218. package/dist/views/personal/security2.vue.js.map +1 -1
  219. package/dist/views/personal/sessions.vue.js +2 -2
  220. package/dist/views/personal/sessions2.vue.js +67 -62
  221. package/dist/views/personal/sessions2.vue.js.map +1 -1
  222. package/dist/views/system/ai-model/components/ProviderCard.vue.js +2 -2
  223. package/dist/views/system/ai-model/components/ProviderCard2.vue.js +142 -130
  224. package/dist/views/system/ai-model/components/ProviderCard2.vue.js.map +1 -1
  225. package/dist/views/system/ai-model/components/ProviderForm.vue.js +2 -2
  226. package/dist/views/system/ai-model/components/ProviderForm2.vue.js +71 -70
  227. package/dist/views/system/ai-model/components/ProviderForm2.vue.js.map +1 -1
  228. package/dist/views/system/ai-model/index.vue.js +2 -2
  229. package/dist/views/system/ai-model/index2.vue.js +99 -99
  230. package/dist/views/system/ai-model/index2.vue.js.map +1 -1
  231. package/dist/views/system/ai-model/presets.d.ts +1 -1
  232. package/dist/views/system/ai-model/presets.js +18 -18
  233. package/dist/views/system/ai-model/presets.js.map +1 -1
  234. package/dist/views/system/ai-usage/index.vue.js +2 -2
  235. package/dist/views/system/ai-usage/index2.vue.js +356 -258
  236. package/dist/views/system/ai-usage/index2.vue.js.map +1 -1
  237. package/dist/views/system/api-docs/index.vue.js +5 -2
  238. package/dist/views/system/api-docs/index.vue.js.map +1 -1
  239. package/dist/views/system/api-docs/index2.vue.js +92 -42
  240. package/dist/views/system/api-docs/index2.vue.js.map +1 -1
  241. package/dist/views/system/cache/index.vue.js +2 -2
  242. package/dist/views/system/cache/index2.vue.js +74 -80
  243. package/dist/views/system/cache/index2.vue.js.map +1 -1
  244. package/dist/views/system/config/components/AdminMock.vue.js +2 -2
  245. package/dist/views/system/config/components/AdminMock2.vue.js +60 -43
  246. package/dist/views/system/config/components/AdminMock2.vue.js.map +1 -1
  247. package/dist/views/system/config/components/AdvancedSection.vue.js +5 -2
  248. package/dist/views/system/config/components/AdvancedSection.vue.js.map +1 -1
  249. package/dist/views/system/config/components/AdvancedSection2.vue.js +98 -70
  250. package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -1
  251. package/dist/views/system/config/components/BrandSection.vue.js +2 -2
  252. package/dist/views/system/config/components/BrandSection2.vue.js +121 -119
  253. package/dist/views/system/config/components/BrandSection2.vue.js.map +1 -1
  254. package/dist/views/system/config/components/CfgGroup.vue.js +3 -3
  255. package/dist/views/system/config/components/CfgGroup2.vue.js.map +1 -1
  256. package/dist/views/system/config/components/CfgRow.vue.js +1 -1
  257. package/dist/views/system/config/components/CfgRow2.vue.js +24 -23
  258. package/dist/views/system/config/components/CfgRow2.vue.js.map +1 -1
  259. package/dist/views/system/config/components/CfgSegment.vue.js +1 -1
  260. package/dist/views/system/config/components/CfgSegment2.vue.js +16 -15
  261. package/dist/views/system/config/components/CfgSegment2.vue.js.map +1 -1
  262. package/dist/views/system/config/components/ConfigFormModal.vue.js +2 -2
  263. package/dist/views/system/config/components/ConfigFormModal2.vue.js +35 -33
  264. package/dist/views/system/config/components/ConfigFormModal2.vue.js.map +1 -1
  265. package/dist/views/system/config/components/JobSection.vue.js +2 -2
  266. package/dist/views/system/config/components/JobSection2.vue.js +46 -44
  267. package/dist/views/system/config/components/JobSection2.vue.js.map +1 -1
  268. package/dist/views/system/config/components/LoginMock.vue.js +3 -3
  269. package/dist/views/system/config/components/LoginMock2.vue.js +83 -72
  270. package/dist/views/system/config/components/LoginMock2.vue.js.map +1 -1
  271. package/dist/views/system/config/components/LogoCropper.vue.js +1 -1
  272. package/dist/views/system/config/components/LogoCropper2.vue.js.map +1 -1
  273. package/dist/views/system/config/components/LogoEditor.vue.js +2 -2
  274. package/dist/views/system/config/components/LogoEditor2.vue.js +11 -13
  275. package/dist/views/system/config/components/LogoEditor2.vue.js.map +1 -1
  276. package/dist/views/system/config/components/ProviderSheet.vue.js +3 -3
  277. package/dist/views/system/config/components/ProviderSheet2.vue.js.map +1 -1
  278. package/dist/views/system/config/components/SectionLayout.vue.d.ts +4 -2
  279. package/dist/views/system/config/components/SectionLayout.vue.js +2 -2
  280. package/dist/views/system/config/components/SectionLayout2.vue.js +51 -27
  281. package/dist/views/system/config/components/SectionLayout2.vue.js.map +1 -1
  282. package/dist/views/system/config/components/SecuritySection.vue.js +2 -2
  283. package/dist/views/system/config/components/SecuritySection2.vue.js +207 -206
  284. package/dist/views/system/config/components/SecuritySection2.vue.js.map +1 -1
  285. package/dist/views/system/config/components/SensitiveSection.vue.js +2 -2
  286. package/dist/views/system/config/components/SensitiveSection2.vue.js +107 -102
  287. package/dist/views/system/config/components/SensitiveSection2.vue.js.map +1 -1
  288. package/dist/views/system/config/components/UploadSection.vue.js +2 -2
  289. package/dist/views/system/config/components/UploadSection2.vue.js +86 -77
  290. package/dist/views/system/config/components/UploadSection2.vue.js.map +1 -1
  291. package/dist/views/system/config/components/WatermarkSection.vue.js +8 -0
  292. package/dist/views/system/config/components/WatermarkSection.vue.js.map +1 -0
  293. package/dist/views/system/config/components/WatermarkSection2.vue.js +284 -0
  294. package/dist/views/system/config/components/WatermarkSection2.vue.js.map +1 -0
  295. package/dist/views/system/config/draft.d.ts +2 -2
  296. package/dist/views/system/config/draft.js.map +1 -1
  297. package/dist/views/system/config/groups.d.ts +4 -1
  298. package/dist/views/system/config/groups.js +54 -49
  299. package/dist/views/system/config/groups.js.map +1 -1
  300. package/dist/views/system/config/index.vue.js +3 -2
  301. package/dist/views/system/config/index.vue.js.map +1 -1
  302. package/dist/views/system/config/index2.vue.js +173 -148
  303. package/dist/views/system/config/index2.vue.js.map +1 -1
  304. package/dist/views/system/config/layoutMode.d.ts +23 -0
  305. package/dist/views/system/config/layoutMode.js +28 -0
  306. package/dist/views/system/config/layoutMode.js.map +1 -0
  307. package/dist/views/system/dict/index.vue.js +2 -2
  308. package/dist/views/system/dict/index2.vue.js +471 -366
  309. package/dist/views/system/dict/index2.vue.js.map +1 -1
  310. package/dist/views/system/file/index2.vue.js +91 -76
  311. package/dist/views/system/file/index2.vue.js.map +1 -1
  312. package/dist/views/system/job/index.vue.js +3 -3
  313. package/dist/views/system/job/index2.vue.js +897 -828
  314. package/dist/views/system/job/index2.vue.js.map +1 -1
  315. package/dist/views/system/job-log/components/AttemptTable.vue.d.ts +8 -0
  316. package/dist/views/system/job-log/components/AttemptTable.vue.js +5 -0
  317. package/dist/views/system/job-log/components/AttemptTable.vue.js.map +1 -0
  318. package/dist/views/system/job-log/components/AttemptTable2.vue.js +54 -0
  319. package/dist/views/system/job-log/components/AttemptTable2.vue.js.map +1 -0
  320. package/dist/views/system/job-log/index.vue.js +2 -2
  321. package/dist/views/system/job-log/index2.vue.js +193 -207
  322. package/dist/views/system/job-log/index2.vue.js.map +1 -1
  323. package/dist/views/system/job-log/runStatus.d.ts +13 -0
  324. package/dist/views/system/job-log/runStatus.js +26 -0
  325. package/dist/views/system/job-log/runStatus.js.map +1 -0
  326. package/dist/views/system/job-monitor/index.vue.js +2 -2
  327. package/dist/views/system/job-monitor/index2.vue.js +172 -180
  328. package/dist/views/system/job-monitor/index2.vue.js.map +1 -1
  329. package/dist/views/system/log/exception/index.vue.js +2 -2
  330. package/dist/views/system/log/exception/index2.vue.js +135 -96
  331. package/dist/views/system/log/exception/index2.vue.js.map +1 -1
  332. package/dist/views/system/log/login/index2.vue.js +62 -41
  333. package/dist/views/system/log/login/index2.vue.js.map +1 -1
  334. package/dist/views/system/log/op/index.vue.js +2 -2
  335. package/dist/views/system/log/op/index2.vue.js +200 -162
  336. package/dist/views/system/log/op/index2.vue.js.map +1 -1
  337. package/dist/views/system/menu/components/ButtonManager.vue.js +2 -2
  338. package/dist/views/system/menu/components/ButtonManager2.vue.js +206 -190
  339. package/dist/views/system/menu/components/ButtonManager2.vue.js.map +1 -1
  340. package/dist/views/system/menu/components/MenuFormModal.vue.js +2 -2
  341. package/dist/views/system/menu/components/MenuFormModal2.vue.js +127 -118
  342. package/dist/views/system/menu/components/MenuFormModal2.vue.js.map +1 -1
  343. package/dist/views/system/menu/index.vue.js +1 -1
  344. package/dist/views/system/menu/index2.vue.js +216 -183
  345. package/dist/views/system/menu/index2.vue.js.map +1 -1
  346. package/dist/views/system/module/index.vue.js +1 -1
  347. package/dist/views/system/module/index2.vue.js +177 -144
  348. package/dist/views/system/module/index2.vue.js.map +1 -1
  349. package/dist/views/system/monitor/index.vue.js +2 -2
  350. package/dist/views/system/monitor/index2.vue.js +134 -149
  351. package/dist/views/system/monitor/index2.vue.js.map +1 -1
  352. package/dist/views/system/notice/index.vue.js +1 -1
  353. package/dist/views/system/notice/index2.vue.js +209 -181
  354. package/dist/views/system/notice/index2.vue.js.map +1 -1
  355. package/dist/views/system/org/index.vue.js +1 -1
  356. package/dist/views/system/org/index2.vue.js +278 -248
  357. package/dist/views/system/org/index2.vue.js.map +1 -1
  358. package/dist/views/system/position/index.vue.js +5 -2
  359. package/dist/views/system/position/index.vue.js.map +1 -1
  360. package/dist/views/system/position/index2.vue.js +128 -92
  361. package/dist/views/system/position/index2.vue.js.map +1 -1
  362. package/dist/views/system/recycle/index.vue.js +2 -2
  363. package/dist/views/system/recycle/index2.vue.js +90 -67
  364. package/dist/views/system/recycle/index2.vue.js.map +1 -1
  365. package/dist/views/system/role/components/GrantMenuSheet.vue.d.ts +20 -0
  366. package/dist/views/system/role/components/GrantMenuSheet.vue.js +8 -0
  367. package/dist/views/system/role/components/GrantMenuSheet.vue.js.map +1 -0
  368. package/dist/views/system/role/components/GrantMenuSheet2.vue.js +117 -0
  369. package/dist/views/system/role/components/GrantMenuSheet2.vue.js.map +1 -0
  370. package/dist/views/system/role/components/GrantMenuTable.vue.d.ts +6 -4
  371. package/dist/views/system/role/components/GrantMenuTable.vue.js +2 -2
  372. package/dist/views/system/role/components/GrantMenuTable2.vue.js +279 -177
  373. package/dist/views/system/role/components/GrantMenuTable2.vue.js.map +1 -1
  374. package/dist/views/system/role/components/MatchText.vue.d.ts +7 -0
  375. package/dist/views/system/role/components/MatchText.vue.js +8 -0
  376. package/dist/views/system/role/components/MatchText.vue.js.map +1 -0
  377. package/dist/views/system/role/components/MatchText2.vue.js +29 -0
  378. package/dist/views/system/role/components/MatchText2.vue.js.map +1 -0
  379. package/dist/views/system/role/components/grantMenuGroups.d.ts +36 -0
  380. package/dist/views/system/role/components/grantMenuGroups.js +110 -48
  381. package/dist/views/system/role/components/grantMenuGroups.js.map +1 -1
  382. package/dist/views/system/role/index.vue.js +5 -2
  383. package/dist/views/system/role/index.vue.js.map +1 -1
  384. package/dist/views/system/role/index2.vue.js +181 -165
  385. package/dist/views/system/role/index2.vue.js.map +1 -1
  386. package/dist/views/system/session/index2.vue.js +75 -49
  387. package/dist/views/system/session/index2.vue.js.map +1 -1
  388. package/dist/views/system/user/components/ResetPasswordModal.vue.js +2 -2
  389. package/dist/views/system/user/components/ResetPasswordModal2.vue.js +2 -0
  390. package/dist/views/system/user/components/ResetPasswordModal2.vue.js.map +1 -1
  391. package/dist/views/system/user/components/UserFormModal.vue.js +2 -2
  392. package/dist/views/system/user/components/UserFormModal2.vue.js +77 -76
  393. package/dist/views/system/user/components/UserFormModal2.vue.js.map +1 -1
  394. package/dist/views/system/user/index.vue.js +2 -2
  395. package/dist/views/system/user/index2.vue.js +362 -275
  396. package/dist/views/system/user/index2.vue.js.map +1 -1
  397. package/package.json +3 -5
  398. package/dist/components/SelectTable/index.vue.d.ts +0 -76
  399. package/dist/components/SelectTable/index2.vue.js +0 -256
  400. package/dist/components/SelectTable/index2.vue.js.map +0 -1
  401. package/dist/composables/useTableRowSort.d.ts +0 -20
  402. package/dist/composables/useTableRowSort.js +0 -59
  403. package/dist/composables/useTableRowSort.js.map +0 -1
  404. package/dist/layouts/LayoutModeCards.vue.js +0 -8
  405. package/dist/layouts/LayoutModeCards.vue.js.map +0 -1
  406. package/dist/layouts/LayoutModeCards2.vue.js +0 -67
  407. package/dist/layouts/LayoutModeCards2.vue.js.map +0 -1
  408. package/dist/layouts/SettingRow.vue.d.ts +0 -16
  409. package/dist/layouts/SettingRow.vue.js +0 -8
  410. package/dist/layouts/SettingRow.vue.js.map +0 -1
  411. package/dist/layouts/SettingRow2.vue.js +0 -23
  412. package/dist/layouts/SettingRow2.vue.js.map +0 -1
  413. package/dist/views/login/skins/AuroraGlass.vue.js +0 -8
  414. package/dist/views/login/skins/AuroraGlass.vue.js.map +0 -1
  415. package/dist/views/login/skins/AuroraGlass2.vue.js +0 -80
  416. package/dist/views/login/skins/AuroraGlass2.vue.js.map +0 -1
  417. package/dist/views/login/skins/SplitPanel.vue.d.ts +0 -3
  418. package/dist/views/login/skins/SplitPanel.vue.js +0 -8
  419. package/dist/views/login/skins/SplitPanel.vue.js.map +0 -1
  420. package/dist/views/login/skins/SplitPanel2.vue.js +0 -65
  421. package/dist/views/login/skins/SplitPanel2.vue.js.map +0 -1
  422. package/dist/views/login/skins/Spotlight.vue.d.ts +0 -3
  423. package/dist/views/login/skins/Spotlight.vue.js +0 -8
  424. package/dist/views/login/skins/Spotlight.vue.js.map +0 -1
  425. package/dist/views/login/skins/Spotlight2.vue.js +0 -36
  426. package/dist/views/login/skins/Spotlight2.vue.js.map +0 -1
  427. package/dist/views/login/skins.d.ts +0 -8
  428. package/dist/views/login/skins.js +0 -13
  429. package/dist/views/login/skins.js.map +0 -1
  430. /package/dist/components/{SelectTable → TableTotal}/index.vue.js.map +0 -0
  431. /package/dist/layouts/{LayoutModeCards.vue.d.ts → AccentPicker.vue.d.ts} +0 -0
  432. /package/dist/views/{login/skins/AuroraGlass.vue.d.ts → system/config/components/WatermarkSection.vue.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index2.vue.js","sources":["../../../../src/views/system/ai-usage/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// AI 用量统计 = 顶部统一筛选(日期/厂商/模型/场景)+ 四格指标 + 分组维度 Tab/表 + 趋势图 + 明细表。\n// 筛选只在 filterParams 这一处收口,四个区块都从它派生,避免各自拼参数导致竞态或口径不一致\n// (SmartTable 走 :params 自动联动,summary/trend 走 watch(filterParams, ...) 手动重拉 + 请求号防竞态)。\n// 本页只有一颗查询权限(GET:/api/v1/sys/ai/usage/summary),菜单可见性已由后端权限树控管,不需要 v-auth。\nimport { computed, h, onMounted, ref, watch } from 'vue'\nimport {\n NGrid,\n NGi,\n NCard,\n NSkeleton,\n NNumberAnimation,\n NDatePicker,\n NSelect,\n NInput,\n NButton,\n NTabs,\n NTabPane,\n NDataTable,\n NProgress,\n NTag,\n useMessage,\n type DataTableColumns,\n} from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { SmartTable, type SmartTableColumn } from 'smart-naive-table'\nimport LineChart from '#/components/Chart/LineChart.vue'\nimport { aiUsageApi, aiProviderApi } from '#/api'\nimport {\n AI_USAGE_GROUP_BY,\n AI_USAGE_SOURCE,\n type AiUsageGroupBy,\n type AiUsageGroupRow,\n type AiUsageSummary,\n type AiUsageTrendPoint,\n type SysAiUsageLog,\n} from '#/types/api'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\n\nconst { t } = useI18n()\nconst message = useMessage()\n\n// ── 日期范围:三个快捷按钮直接设值(shortcuts prop 类型较绕,按钮法更直白),默认近 7 天 ──\nfunction fmtDate(d: Date): string {\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, '0')\n const day = String(d.getDate()).padStart(2, '0')\n return `${y}-${m}-${day}`\n}\nfunction daysAgo(n: number): Date {\n const d = new Date()\n d.setDate(d.getDate() - n)\n return d\n}\nfunction quickRangeValue(days: number): [string, string] {\n return [fmtDate(daysAgo(days - 1)), fmtDate(daysAgo(0))]\n}\n\nconst dateRange = ref<[string, string]>(quickRangeValue(7))\nconst activeQuickRange = ref<number | null>(7)\n\nfunction setQuickRange(days: number) {\n dateRange.value = quickRangeValue(days)\n activeQuickRange.value = days\n}\n// 不加 clearable:没有清空按钮,formatted-value 就不会回传 null,ref 全程非空,少一层判空。\nfunction onDateRangeUpdate(v: [string, string] | null) {\n if (!v) return\n dateRange.value = v\n activeQuickRange.value = null // 手动挑日期后取消快捷按钮高亮\n}\n\n// ── 厂商 / 模型 / 场景筛选 ──\n// 厂商:只读消费 aiProviderApi 拉一页选项(不改厂商模块任何文件)。模型/场景后端无枚举接口,\n// 模型做成 filterable+tag 的自由输入 select(参考 menu/MenuFormModal 的 component 字段写法),\n// 场景干脆用文本框模糊过滤——两者都是自由字符串,不是字典。\nconst providerCode = ref<string | null>(null)\nconst model = ref<string | null>(null)\nconst scene = ref<string | null>(null)\n\nconst providerOptions = ref<{ label: string; value: string }[]>([])\nonMounted(async () => {\n try {\n const { items } = await aiProviderApi.page({ page: 1, pageSize: 100 })\n providerOptions.value = items.map(p => ({ label: p.name, value: p.code }))\n } catch {\n // 静默:厂商下拉是筛选辅助,拉取失败不打断本页其余区块\n }\n})\n\n/**\n * 统一收口的筛选参数——四格指标 / 分组表 / 趋势图 / 明细表都从这一份派生,不各自拼 from/to,\n * 避免四处逻辑不一致或漏改。结束日补到 23:59:59(同 job-log/操作日志页 daterange 的规矩),\n * 否则\"筛到今天\"会把今天已发生的调用漏掉(纯日期串等价于当天 00:00:00)。\n */\nconst filterParams = computed(() => {\n const p: {\n from: string\n to: string\n providerCode?: string\n model?: string\n scene?: string\n } = {\n from: `${dateRange.value[0]}T00:00:00`,\n to: `${dateRange.value[1]}T23:59:59`,\n }\n if (providerCode.value) p.providerCode = providerCode.value\n if (model.value) p.model = model.value\n if (scene.value) p.scene = scene.value\n return p\n})\n\n// ── 分组维度 Tab ──\nconst groupTabs: { value: AiUsageGroupBy; labelKey: 'provider' | 'model' | 'scene' | 'user' }[] = [\n { value: AI_USAGE_GROUP_BY.Provider, labelKey: 'provider' },\n { value: AI_USAGE_GROUP_BY.Model, labelKey: 'model' },\n { value: AI_USAGE_GROUP_BY.Scene, labelKey: 'scene' },\n { value: AI_USAGE_GROUP_BY.User, labelKey: 'user' },\n]\nconst activeGroupBy = ref<AiUsageGroupBy>(AI_USAGE_GROUP_BY.Provider)\n\n// ── summary(四格指标 totals + 当前维度 groups,同一次请求共用)──\nconst summary = ref<AiUsageSummary | null>(null)\nconst summaryLoading = ref(true)\nlet summaryReq = 0\nasync function fetchSummary() {\n const reqId = ++summaryReq\n summaryLoading.value = true\n try {\n const res = await aiUsageApi.summary({ ...filterParams.value, groupBy: activeGroupBy.value })\n if (reqId !== summaryReq) return // 旧请求的响应,丢弃(防竞态:快速切筛选/切 Tab 时先发的可能后回)\n summary.value = res\n } catch (e) {\n if (reqId !== summaryReq) return\n message.error(translateError(e))\n } finally {\n if (reqId === summaryReq) summaryLoading.value = false\n }\n}\nwatch([filterParams, activeGroupBy], fetchSummary, { immediate: true })\n\nconst totals = computed(() => summary.value?.totals ?? null)\nconst groups = computed(() => summary.value?.groups ?? [])\n\n/**\n * 平均耗时卡片的算法选择:后端 AiUsageTotals 没有整体的 avgLatencyMs 字段,只有当前 groupBy\n * 维度下每组的 avgLatencyMs。这里按各组 callCount 加权平均还原总体平均耗时——分组维度对区间内\n * 全部调用做了完整划分(每次调用恰好落在一个分组里,无重叠无遗漏),所以\n * sum(avgLatencyMs_i * callCount_i) / sum(callCount_i) 就精确等于对全部原始调用耗时取平均,\n * 不是近似值(除各组均值本身的取整/浮点误差外)。选它而不是\"失败率\"是因为卡片标题已经明确是\n * aiUsage.metric.avgLatency(平均耗时),不宜文不对题;比另开一个后端聚合字段/接口更省事,\n * 也顺带让这张卡片跟着 groupBy 切换、筛选变化实时更新,不需要额外请求。\n */\nconst avgLatencyMs = computed(() => {\n const totalCalls = groups.value.reduce((sum, g) => sum + g.callCount, 0)\n if (!totalCalls) return null\n const weighted = groups.value.reduce((sum, g) => sum + g.avgLatencyMs * g.callCount, 0)\n return weighted / totalCalls\n})\n\nconst metrics = computed(() => [\n { key: 'totalTokens', value: totals.value?.totalTokens ?? 0, empty: !totals.value },\n { key: 'totalCalls', value: totals.value?.callCount ?? 0, empty: !totals.value },\n { key: 'failureCount', value: totals.value?.failureCount ?? 0, empty: !totals.value },\n {\n key: 'avgLatency',\n value: avgLatencyMs.value != null ? Math.round(avgLatencyMs.value) : 0,\n suffix: 'ms',\n empty: avgLatencyMs.value == null,\n },\n])\n\n// ── 分组表(四个 Tab 共用同一张表,只是绑定的 groups/列标题随 activeGroupBy 变)──\nconst groupDimensionLabel = computed(() => {\n const tab = groupTabs.find(g => g.value === activeGroupBy.value)\n return t(`aiUsage.groupBy.${tab?.labelKey ?? 'provider'}`)\n})\n\nconst groupColumns = computed<DataTableColumns<AiUsageGroupRow>>(() => [\n { title: () => groupDimensionLabel.value, key: 'label', render: r => r.label ?? r.key },\n {\n title: () => t('aiUsage.trend.inputTokens'),\n key: 'inputTokens',\n render: r => r.inputTokens.toLocaleString(),\n },\n {\n title: () => t('aiUsage.trend.outputTokens'),\n key: 'outputTokens',\n render: r => r.outputTokens.toLocaleString(),\n },\n {\n title: () => t('aiUsage.metric.totalCalls'),\n key: 'callCount',\n render: r => r.callCount.toLocaleString(),\n },\n {\n title: () => t('aiUsage.table.latency'),\n key: 'avgLatencyMs',\n render: r => `${Math.round(r.avgLatencyMs)} ms`,\n },\n {\n title: () => t('aiUsage.share'),\n key: 'sharePercent',\n render: r =>\n h('div', { class: 'share-cell' }, [\n h('div', { class: 'share-bar' }, [\n h(NProgress, {\n type: 'line',\n percentage: Math.round(r.sharePercent),\n showIndicator: false,\n height: 6,\n }),\n ]),\n h('span', { class: 'share-text' }, `${r.sharePercent.toFixed(1)}%`),\n ]),\n },\n])\n\n// ── 趋势图 ──\nconst trendPoints = ref<AiUsageTrendPoint[]>([])\nconst trendLoading = ref(true)\nlet trendReq = 0\nasync function fetchTrend() {\n const reqId = ++trendReq\n trendLoading.value = true\n try {\n const res = await aiUsageApi.trend(filterParams.value)\n if (reqId !== trendReq) return\n trendPoints.value = res\n } catch (e) {\n if (reqId !== trendReq) return\n message.error(translateError(e))\n } finally {\n if (reqId === trendReq) trendLoading.value = false\n }\n}\nwatch(filterParams, fetchTrend, { immediate: true })\n\nconst trendCategories = computed(() => trendPoints.value.map(p => p.date))\nconst trendSeries = computed(() => [\n { name: t('aiUsage.trend.inputTokens'), data: trendPoints.value.map(p => p.inputTokens) },\n { name: t('aiUsage.trend.outputTokens'), data: trendPoints.value.map(p => p.outputTokens) },\n])\n\n// ── 明细表(SmartTable;筛选已在页面顶部统一做,这里不开列搜索,:params 联动顶部筛选)──\nconst detailColumns: SmartTableColumn<SysAiUsageLog>[] = [\n {\n key: 'createTime',\n title: () => t('aiUsage.table.createTime'),\n width: 170,\n render: r => fmtDateTime(r.createTime),\n },\n { key: 'providerCode', title: () => t('aiUsage.table.provider'), width: 120 },\n { key: 'model', title: () => t('aiUsage.table.model'), width: 140, ellipsis: { tooltip: true } },\n { key: 'scene', title: () => t('aiUsage.table.scene'), width: 120, render: r => r.scene || '—' },\n {\n key: 'userId',\n title: () => t('aiUsage.table.user'),\n width: 90,\n render: r => (r.userId != null ? String(r.userId) : '—'),\n },\n {\n key: 'inputTokens',\n title: () => t('aiUsage.table.inputTokens'),\n width: 110,\n render: r => r.inputTokens.toLocaleString(),\n },\n {\n key: 'outputTokens',\n title: () => t('aiUsage.table.outputTokens'),\n width: 110,\n render: r => r.outputTokens.toLocaleString(),\n },\n {\n key: 'totalTokens',\n title: () => t('aiUsage.table.totalTokens'),\n width: 110,\n render: r => r.totalTokens.toLocaleString(),\n },\n {\n key: 'latencyMs',\n title: () => t('aiUsage.table.latency'),\n width: 90,\n render: r => `${r.latencyMs} ms`,\n },\n {\n key: 'success',\n title: () => t('aiUsage.table.status'),\n width: 90,\n // 失败行用原生 title 兜底展示 errorMessage,不必为一个只读明细表再引入 NTooltip\n render: r =>\n h('span', { title: !r.success && r.errorMessage ? r.errorMessage : undefined }, [\n h(NTag, { size: 'small', bordered: false, type: r.success ? 'success' : 'error' }, () =>\n r.success ? t('aiUsage.table.success') : t('aiUsage.table.failed'),\n ),\n ]),\n },\n {\n key: 'streamed',\n title: () => t('aiUsage.table.streamed'),\n width: 80,\n render: r =>\n h(NTag, { size: 'small', bordered: false }, () =>\n r.streamed ? t('common.yes') : t('common.no'),\n ),\n },\n {\n key: 'usageSource',\n title: () => t('aiUsage.table.usageSource'),\n width: 110,\n render: r =>\n r.usageSource === AI_USAGE_SOURCE.Reported\n ? t('aiUsage.table.usageSourceReported')\n : t('aiUsage.table.usageSourceMissing'),\n },\n]\n</script>\n\n<template>\n <div class=\"view\">\n <!-- 筛选区:日期范围 + 快捷按钮 + 厂商/模型/场景,变化后经 filterParams 联动下面四块 -->\n <n-card :bordered=\"true\">\n <div class=\"filter-bar\">\n <div class=\"filter-item\">\n <span class=\"filter-label\">{{ t('aiUsage.filter.dateRange') }}</span>\n <div class=\"date-filter-row\">\n <n-date-picker\n :formatted-value=\"dateRange\"\n type=\"daterange\"\n value-format=\"yyyy-MM-dd\"\n style=\"width: 240px\"\n @update:formatted-value=\"onDateRangeUpdate\"\n />\n <div class=\"quick-range\">\n <n-button\n size=\"small\"\n quaternary\n :type=\"activeQuickRange === 1 ? 'primary' : 'default'\"\n @click=\"setQuickRange(1)\"\n >\n {{ t('aiUsage.filter.today') }}\n </n-button>\n <n-button\n size=\"small\"\n quaternary\n :type=\"activeQuickRange === 7 ? 'primary' : 'default'\"\n @click=\"setQuickRange(7)\"\n >\n {{ t('aiUsage.filter.last7Days') }}\n </n-button>\n <n-button\n size=\"small\"\n quaternary\n :type=\"activeQuickRange === 30 ? 'primary' : 'default'\"\n @click=\"setQuickRange(30)\"\n >\n {{ t('aiUsage.filter.last30Days') }}\n </n-button>\n </div>\n </div>\n </div>\n <div class=\"filter-item\">\n <span class=\"filter-label\">{{ t('aiUsage.filter.provider') }}</span>\n <n-select\n v-model:value=\"providerCode\"\n :options=\"providerOptions\"\n clearable\n filterable\n style=\"width: 180px\"\n :placeholder=\"t('aiUsage.filter.providerAll')\"\n />\n </div>\n <div class=\"filter-item\">\n <span class=\"filter-label\">{{ t('aiUsage.filter.model') }}</span>\n <n-select\n v-model:value=\"model\"\n :options=\"[]\"\n filterable\n tag\n clearable\n style=\"width: 180px\"\n :placeholder=\"t('aiUsage.filter.modelAll')\"\n />\n </div>\n <div class=\"filter-item\">\n <span class=\"filter-label\">{{ t('aiUsage.filter.scene') }}</span>\n <n-input\n v-model:value=\"scene\"\n clearable\n style=\"width: 180px\"\n :placeholder=\"t('aiUsage.filter.scenePlaceholder')\"\n />\n </div>\n </div>\n </n-card>\n\n <!-- 四格指标:totals 与分组表共用同一次 summary 请求,不重复请求 -->\n <n-grid :cols=\"'1 s:2 l:4'\" responsive=\"screen\" :x-gap=\"16\" :y-gap=\"16\">\n <n-gi v-for=\"m in metrics\" :key=\"m.key\">\n <n-card :bordered=\"true\">\n <div class=\"metric-body\">\n <n-skeleton v-if=\"summaryLoading\" text width=\"72px\" height=\"34px\" />\n <div v-else class=\"metric-val tabular\">\n <template v-if=\"m.empty\">—</template>\n <template v-else>\n <n-number-animation :from=\"0\" :to=\"m.value\" show-separator />\n <span v-if=\"m.suffix\" class=\"metric-suffix\">{{ ' ' + m.suffix }}</span>\n </template>\n </div>\n <div class=\"metric-label\">{{ t(`aiUsage.metric.${m.key}`) }}</div>\n </div>\n </n-card>\n </n-gi>\n </n-grid>\n\n <!-- 分组维度 Tab + 分组表:切 Tab 换 groupBy 重新拉 summary -->\n <n-card :bordered=\"true\">\n <n-tabs v-model:value=\"activeGroupBy\" type=\"line\" animated>\n <n-tab-pane\n v-for=\"tab in groupTabs\"\n :key=\"tab.value\"\n :name=\"tab.value\"\n :tab=\"t(`aiUsage.groupBy.${tab.labelKey}`)\"\n display-directive=\"show:lazy\"\n >\n <n-data-table\n :columns=\"groupColumns\"\n :data=\"groups\"\n :loading=\"summaryLoading\"\n :row-key=\"(r: AiUsageGroupRow) => r.key\"\n :bordered=\"false\"\n size=\"small\"\n />\n </n-tab-pane>\n </n-tabs>\n </n-card>\n\n <!-- 趋势图:区间内无数据的日期后端已补 0,直接画连续折线 -->\n <n-card :title=\"t('aiUsage.trend.title')\" :bordered=\"true\">\n <n-skeleton v-if=\"trendLoading\" height=\"320px\" :sharp=\"false\" />\n <LineChart v-else :categories=\"trendCategories\" :series=\"trendSeries\" />\n </n-card>\n\n <!-- 明细表::search=\"false\" 关掉 SmartTable 自带搜索区,筛选统一走顶部 :params -->\n <SmartTable\n :columns=\"detailColumns\"\n :fetcher=\"aiUsageApi.page\"\n :params=\"filterParams\"\n :search=\"false\"\n :default-page-size=\"20\"\n storage-key=\"sys-ai-usage\"\n @error=\"(e: unknown) => message.error(translateError(e))\"\n />\n </div>\n</template>\n\n<style scoped>\n.view {\n display: flex;\n flex-direction: column;\n gap: var(--gap-card);\n}\n.filter-bar {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-end;\n gap: 16px 24px;\n}\n.filter-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.filter-label {\n font-size: var(--font-size-sm, 13px);\n color: var(--color-text-secondary);\n}\n.date-filter-row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.quick-range {\n display: flex;\n gap: 4px;\n}\n.metric-body {\n min-width: 0;\n}\n.metric-val {\n font-size: 28px;\n font-weight: 700;\n color: var(--color-text-primary);\n line-height: 1.1;\n}\n.metric-suffix {\n font-size: 14px;\n font-weight: 400;\n color: var(--color-text-secondary);\n}\n.metric-label {\n color: var(--color-text-secondary);\n margin-top: 4px;\n}\n.share-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.share-bar {\n flex: 1;\n min-width: 60px;\n}\n.share-text {\n flex: 0 0 auto;\n color: var(--color-text-secondary);\n font-size: 12px;\n}\n</style>\n"],"names":["useI18n","message","useMessage","fmtDate","d","y","m","day","daysAgo","n","quickRangeValue","days","dateRange","ref","activeQuickRange","setQuickRange","onDateRangeUpdate","v","providerCode","model","scene","providerOptions","onMounted","items","aiProviderApi","p","filterParams","computed","groupTabs","AI_USAGE_GROUP_BY","activeGroupBy","summary","summaryLoading","summaryReq","fetchSummary","reqId","res","aiUsageApi","e","translateError","watch","totals","_a","groups","avgLatencyMs","totalCalls","sum","g","metrics","_b","_c","groupDimensionLabel","tab","groupColumns","r","h","NProgress","trendPoints","trendLoading","trendReq","fetchTrend","trendCategories","trendSeries","detailColumns","fmtDateTime","NTag","AI_USAGE_SOURCE","_openBlock","_createElementBlock","_hoisted_1","_createVNode","_unref","NCard","_createElementVNode","_hoisted_2","_hoisted_3","_hoisted_4","_toDisplayString","_hoisted_5","NDatePicker","_hoisted_6","NButton","_hoisted_7","_hoisted_8","NSelect","$event","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","NInput","NGrid","_Fragment","_renderList","_createBlock","NGi","_hoisted_13","NSkeleton","_hoisted_14","NNumberAnimation","_hoisted_15","_hoisted_16","NTabs","NTabPane","NDataTable","LineChart","SmartTable","_cache"],"mappings":"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"}
1
+ {"version":3,"file":"index2.vue.js","sources":["../../../../src/views/system/ai-usage/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// AI 用量统计 = 顶部统一筛选(日期/厂商/模型/场景)+ 四格指标 + 分组维度 Tab/表 + 趋势图 + 明细表。\n// 筛选只在 filterParams 这一处收口,四个区块都从它派生,避免各自拼参数导致竞态或口径不一致\n// (SmartTable 走 :params 自动联动,summary/trend 走 watch(filterParams, ...) 手动重拉 + 请求号防竞态)。\n// 本页只有一颗查询权限(GET:/api/v1/sys/ai/usage/summary),菜单可见性已由后端权限树控管,不需要 v-auth。\n// 版式:块顺序为 筛选 → 指标 → 趋势 → 分组 Tab → 明细;块间距 8px、指标格带图标底块、四格列数按内容区宽度分档(容器查询,窄 1 / 中 2 / 宽 4),\n// 分组表与明细表都是 SmartTable(分组表走静态数据模式),窄档都用内置的 card-on-narrow 卡片列表。图表用 ECharts(LineChart)。\nimport { computed, h, onMounted, ref, watch } from 'vue'\nimport {\n NCard,\n NSkeleton,\n NNumberAnimation,\n NDatePicker,\n NSelect,\n NInput,\n NButton,\n NTabs,\n NTabPane,\n NProgress,\n NTag,\n useMessage,\n} from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { SmartTable, type SmartTableColumn } from 'smart-naive-table'\nimport AppIcon from '#/components/AppIcon.vue'\nimport LineChart from '#/components/Chart/LineChart.vue'\nimport { aiUsageApi, aiProviderApi } from '#/api'\nimport {\n AI_USAGE_GROUP_BY,\n AI_USAGE_SOURCE,\n type AiUsageGroupBy,\n type AiUsageGroupRow,\n type AiUsageSummary,\n type AiUsageTrendPoint,\n type SysAiUsageLog,\n} from '#/types/api'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\nimport { SEARCH_ACTIONS, deriveHeaderFilters } from '#/utils/tableFilter'\nimport { TABLE_TOOLBAR } from '#/utils/tableToolbar'\nimport TableTotal from '#/components/TableTotal/index.vue'\n\nconst { t } = useI18n()\nconst message = useMessage()\n\n// ── 日期范围:三个快捷按钮直接设值(shortcuts prop 类型较绕,按钮法更直白),默认近 7 天 ──\nfunction fmtDate(d: Date): string {\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, '0')\n const day = String(d.getDate()).padStart(2, '0')\n return `${y}-${m}-${day}`\n}\nfunction daysAgo(n: number): Date {\n const d = new Date()\n d.setDate(d.getDate() - n)\n return d\n}\nfunction quickRangeValue(days: number): [string, string] {\n return [fmtDate(daysAgo(days - 1)), fmtDate(daysAgo(0))]\n}\n\nconst dateRange = ref<[string, string]>(quickRangeValue(7))\nconst activeQuickRange = ref<number | null>(7)\n\nfunction setQuickRange(days: number) {\n dateRange.value = quickRangeValue(days)\n activeQuickRange.value = days\n}\n// 不加 clearable:没有清空按钮,formatted-value 就不会回传 null,ref 全程非空,少一层判空。\nfunction onDateRangeUpdate(v: [string, string] | null) {\n if (!v) return\n dateRange.value = v\n activeQuickRange.value = null // 手动挑日期后取消快捷按钮高亮\n}\n\n// ── 厂商 / 模型 / 场景筛选 ──\n// 厂商:只读消费 aiProviderApi 拉一页选项(不改厂商模块任何文件)。模型/场景后端无枚举接口,\n// 模型做成 filterable+tag 的自由输入 select(参考 menu/MenuFormModal 的 component 字段写法),\n// 场景干脆用文本框模糊过滤——两者都是自由字符串,不是字典。\nconst providerCode = ref<string | null>(null)\nconst model = ref<string | null>(null)\nconst scene = ref<string | null>(null)\n\nconst providerOptions = ref<{ label: string; value: string }[]>([])\nonMounted(async () => {\n try {\n const { items } = await aiProviderApi.page({ page: 1, pageSize: 100 })\n providerOptions.value = items.map(p => ({ label: p.name, value: p.code }))\n } catch {\n // 静默:厂商下拉是筛选辅助,拉取失败不打断本页其余区块\n }\n})\n\n/**\n * 统一收口的筛选参数——四格指标 / 分组表 / 趋势图 / 明细表都从这一份派生,不各自拼 from/to,\n * 避免四处逻辑不一致或漏改。结束日补到 23:59:59(同 job-log/操作日志页 daterange 的规矩),\n * 否则\"筛到今天\"会把今天已发生的调用漏掉(纯日期串等价于当天 00:00:00)。\n */\nconst filterParams = computed(() => {\n const p: {\n from: string\n to: string\n providerCode?: string\n model?: string\n scene?: string\n } = {\n from: `${dateRange.value[0]}T00:00:00`,\n to: `${dateRange.value[1]}T23:59:59`,\n }\n if (providerCode.value) p.providerCode = providerCode.value\n if (model.value) p.model = model.value\n if (scene.value) p.scene = scene.value\n return p\n})\n\n// ── 分组维度 Tab ──\nconst groupTabs: { value: AiUsageGroupBy; labelKey: 'provider' | 'model' | 'scene' | 'user' }[] = [\n { value: AI_USAGE_GROUP_BY.Provider, labelKey: 'provider' },\n { value: AI_USAGE_GROUP_BY.Model, labelKey: 'model' },\n { value: AI_USAGE_GROUP_BY.Scene, labelKey: 'scene' },\n { value: AI_USAGE_GROUP_BY.User, labelKey: 'user' },\n]\nconst activeGroupBy = ref<AiUsageGroupBy>(AI_USAGE_GROUP_BY.Provider)\n\n// ── summary(四格指标 totals + 当前维度 groups,同一次请求共用)──\nconst summary = ref<AiUsageSummary | null>(null)\nconst summaryLoading = ref(true)\nlet summaryReq = 0\nasync function fetchSummary() {\n const reqId = ++summaryReq\n summaryLoading.value = true\n try {\n const res = await aiUsageApi.summary({ ...filterParams.value, groupBy: activeGroupBy.value })\n if (reqId !== summaryReq) return // 旧请求的响应,丢弃(防竞态:快速切筛选/切 Tab 时先发的可能后回)\n summary.value = res\n } catch (e) {\n if (reqId !== summaryReq) return\n message.error(translateError(e))\n } finally {\n if (reqId === summaryReq) summaryLoading.value = false\n }\n}\nwatch([filterParams, activeGroupBy], fetchSummary, { immediate: true })\n\nconst totals = computed(() => summary.value?.totals ?? null)\nconst groups = computed(() => summary.value?.groups ?? [])\n\n/**\n * 平均耗时卡片的算法选择:后端 AiUsageTotals 没有整体的 avgLatencyMs 字段,只有当前 groupBy\n * 维度下每组的 avgLatencyMs。这里按各组 callCount 加权平均还原总体平均耗时——分组维度对区间内\n * 全部调用做了完整划分(每次调用恰好落在一个分组里,无重叠无遗漏),所以\n * sum(avgLatencyMs_i * callCount_i) / sum(callCount_i) 就精确等于对全部原始调用耗时取平均,\n * 不是近似值(除各组均值本身的取整/浮点误差外)。选它而不是\"失败率\"是因为卡片标题已经明确是\n * aiUsage.metric.avgLatency(平均耗时),不宜文不对题;比另开一个后端聚合字段/接口更省事,\n * 也顺带让这张卡片跟着 groupBy 切换、筛选变化实时更新,不需要额外请求。\n */\nconst avgLatencyMs = computed(() => {\n const totalCalls = groups.value.reduce((sum, g) => sum + g.callCount, 0)\n if (!totalCalls) return null\n const weighted = groups.value.reduce((sum, g) => sum + g.avgLatencyMs * g.callCount, 0)\n return weighted / totalCalls\n})\n\nconst metrics = computed(() => [\n {\n key: 'totalTokens',\n icon: 'ph:coins',\n value: totals.value?.totalTokens ?? 0,\n empty: !totals.value,\n },\n {\n key: 'totalCalls',\n icon: 'ph:lightning',\n value: totals.value?.callCount ?? 0,\n empty: !totals.value,\n },\n {\n key: 'failureCount',\n icon: 'ph:warning-circle',\n value: totals.value?.failureCount ?? 0,\n empty: !totals.value,\n },\n {\n key: 'avgLatency',\n icon: 'ph:timer',\n value: avgLatencyMs.value != null ? Math.round(avgLatencyMs.value) : 0,\n suffix: 'ms',\n empty: avgLatencyMs.value == null,\n },\n])\n\n// ── 分组表(四个 Tab 共用同一张表,只是绑定的 groups/列标题随 activeGroupBy 变)──\nconst groupDimensionLabel = computed(() => {\n const tab = groupTabs.find(g => g.value === activeGroupBy.value)\n return t(`aiUsage.groupBy.${tab?.labelKey ?? 'provider'}`)\n})\n\nconst numCell = (n: number) => h('span', { class: 'num' }, n.toLocaleString())\n\nconst groupColumns = computed<SmartTableColumn<AiUsageGroupRow>[]>(() => [\n {\n title: () => groupDimensionLabel.value,\n key: 'label',\n minWidth: 160,\n search: {}, // 静态数据:条件由 SmartTable 前端求值\n // 厂商 / 模型 / 场景是编码类文本,等宽;用户维度是姓名,保持正文\n render: r =>\n h(\n 'span',\n { class: activeGroupBy.value === AI_USAGE_GROUP_BY.User ? '' : 'mono' },\n r.label ?? r.key,\n ),\n },\n {\n title: () => t('aiUsage.trend.inputTokens'),\n key: 'inputTokens',\n width: 120,\n align: 'right',\n render: r => numCell(r.inputTokens),\n },\n {\n title: () => t('aiUsage.trend.outputTokens'),\n key: 'outputTokens',\n width: 120,\n align: 'right',\n render: r => numCell(r.outputTokens),\n },\n {\n title: () => t('aiUsage.metric.totalCalls'),\n key: 'callCount',\n width: 110,\n align: 'right',\n render: r => numCell(r.callCount),\n },\n {\n title: () => t('aiUsage.table.latency'),\n key: 'avgLatencyMs',\n width: 100,\n align: 'right',\n render: r => h('span', { class: 'num' }, `${Math.round(r.avgLatencyMs)} ms`),\n },\n {\n title: () => t('aiUsage.share'),\n key: 'sharePercent',\n minWidth: 200,\n render: r =>\n h('div', { class: 'share-cell' }, [\n h('div', { class: 'share-bar' }, [\n h(NProgress, {\n type: 'line',\n percentage: Math.round(r.sharePercent),\n showIndicator: false,\n height: 6,\n }),\n ]),\n h('span', { class: 'share-text num muted' }, `${r.sharePercent.toFixed(1)}%`),\n ]),\n },\n])\n\n// ── 趋势图 ──\nconst trendPoints = ref<AiUsageTrendPoint[]>([])\nconst trendLoading = ref(true)\nlet trendReq = 0\nasync function fetchTrend() {\n const reqId = ++trendReq\n trendLoading.value = true\n try {\n const res = await aiUsageApi.trend(filterParams.value)\n if (reqId !== trendReq) return\n trendPoints.value = res\n } catch (e) {\n if (reqId !== trendReq) return\n message.error(translateError(e))\n } finally {\n if (reqId === trendReq) trendLoading.value = false\n }\n}\nwatch(filterParams, fetchTrend, { immediate: true })\n\nconst trendCategories = computed(() => trendPoints.value.map(p => p.date))\nconst trendSeries = computed(() => [\n { name: t('aiUsage.trend.inputTokens'), data: trendPoints.value.map(p => p.inputTokens) },\n { name: t('aiUsage.trend.outputTokens'), data: trendPoints.value.map(p => p.outputTokens) },\n])\n\n// ── 明细表(SmartTable;日期/厂商/模型/场景已在页面顶部统一做并经 :params 联动,\n// 内置条件搜索只放顶部没有的「结果」,避免同一个条件两处入口)──\nconst detailColumns: SmartTableColumn<SysAiUsageLog>[] = [\n {\n key: 'createTime',\n title: () => t('aiUsage.table.createTime'),\n width: 170,\n render: r =>\n h('span', { class: 'num muted', style: 'white-space: nowrap' }, fmtDateTime(r.createTime)),\n },\n {\n key: 'providerCode',\n title: () => t('aiUsage.table.provider'),\n width: 120,\n render: r => h('span', { class: 'mono' }, r.providerCode),\n },\n {\n key: 'model',\n title: () => t('aiUsage.table.model'),\n width: 140,\n ellipsis: { tooltip: true },\n render: r => h('span', { class: 'mono' }, r.model),\n },\n {\n key: 'scene',\n title: () => t('aiUsage.table.scene'),\n width: 120,\n render: r => h('span', { class: 'mono muted' }, r.scene || '—'),\n },\n {\n key: 'userId',\n title: () => t('aiUsage.table.user'),\n width: 90,\n render: r => h('span', { class: 'num' }, r.userId != null ? String(r.userId) : '—'),\n },\n {\n key: 'inputTokens',\n title: () => t('aiUsage.table.inputTokens'),\n width: 110,\n align: 'right',\n render: r => numCell(r.inputTokens),\n },\n {\n key: 'outputTokens',\n title: () => t('aiUsage.table.outputTokens'),\n width: 110,\n align: 'right',\n render: r => numCell(r.outputTokens),\n },\n {\n key: 'totalTokens',\n title: () => t('aiUsage.table.totalTokens'),\n width: 110,\n align: 'right',\n render: r => numCell(r.totalTokens),\n },\n {\n key: 'latencyMs',\n title: () => t('aiUsage.table.latency'),\n width: 100,\n align: 'right',\n render: r => h('span', { class: 'num' }, `${r.latencyMs.toLocaleString()} ms`),\n },\n {\n key: 'success',\n title: () => t('aiUsage.table.status'),\n width: 90,\n // options 只给搜索控件当下拉选项(单元格仍走下面的 render);后端 Success == 精确匹配,所以只开「等于」\n options: [\n { label: () => t('aiUsage.table.success'), value: true },\n { label: () => t('aiUsage.table.failed'), value: false },\n ],\n search: { actions: SEARCH_ACTIONS.exact },\n // 失败行用原生 title 兜底展示 errorMessage,不必为一个只读明细表再引入 NTooltip\n render: r =>\n h('span', { title: !r.success && r.errorMessage ? r.errorMessage : undefined }, [\n h(NTag, { size: 'small', bordered: false, type: r.success ? 'success' : 'error' }, () =>\n r.success ? t('aiUsage.table.success') : t('aiUsage.table.failed'),\n ),\n ]),\n },\n {\n key: 'streamed',\n title: () => t('aiUsage.table.streamed'),\n width: 80,\n render: r =>\n h(NTag, { size: 'small', bordered: false }, () =>\n r.streamed ? t('common.yes') : t('common.no'),\n ),\n },\n {\n key: 'usageSource',\n title: () => t('aiUsage.table.usageSource'),\n width: 110,\n render: r =>\n r.usageSource === AI_USAGE_SOURCE.Reported\n ? t('aiUsage.table.usageSourceReported')\n : t('aiUsage.table.usageSourceMissing'),\n },\n]\nderiveHeaderFilters(detailColumns)\n</script>\n\n<template>\n <div class=\"view\">\n <!-- 筛选区:日期范围 + 快捷按钮 + 厂商/模型/场景,变化后经 filterParams 联动下面四块 -->\n <n-card class=\"a-card\" size=\"small\" :bordered=\"true\" content-style=\"padding: 12px 14px\">\n <div class=\"filter-bar\">\n <div class=\"filter-item filter-item--range\">\n <span class=\"filter-label faint\">{{ t('aiUsage.filter.dateRange') }}</span>\n <div class=\"date-filter-row\">\n <n-date-picker\n :formatted-value=\"dateRange\"\n type=\"daterange\"\n value-format=\"yyyy-MM-dd\"\n class=\"date-picker\"\n @update:formatted-value=\"onDateRangeUpdate\"\n />\n <div class=\"quick-range\">\n <n-button\n size=\"small\"\n quaternary\n :type=\"activeQuickRange === 1 ? 'primary' : 'default'\"\n @click=\"setQuickRange(1)\"\n >\n {{ t('aiUsage.filter.today') }}\n </n-button>\n <n-button\n size=\"small\"\n quaternary\n :type=\"activeQuickRange === 7 ? 'primary' : 'default'\"\n @click=\"setQuickRange(7)\"\n >\n {{ t('aiUsage.filter.last7Days') }}\n </n-button>\n <n-button\n size=\"small\"\n quaternary\n :type=\"activeQuickRange === 30 ? 'primary' : 'default'\"\n @click=\"setQuickRange(30)\"\n >\n {{ t('aiUsage.filter.last30Days') }}\n </n-button>\n </div>\n </div>\n </div>\n <div class=\"filter-item\">\n <span class=\"filter-label faint\">{{ t('aiUsage.filter.provider') }}</span>\n <n-select\n v-model:value=\"providerCode\"\n :options=\"providerOptions\"\n clearable\n filterable\n class=\"filter-ctl\"\n :placeholder=\"t('aiUsage.filter.providerAll')\"\n />\n </div>\n <div class=\"filter-item\">\n <span class=\"filter-label faint\">{{ t('aiUsage.filter.model') }}</span>\n <n-select\n v-model:value=\"model\"\n :options=\"[]\"\n filterable\n tag\n clearable\n class=\"filter-ctl\"\n :placeholder=\"t('aiUsage.filter.modelAll')\"\n />\n </div>\n <div class=\"filter-item\">\n <span class=\"filter-label faint\">{{ t('aiUsage.filter.scene') }}</span>\n <n-input\n v-model:value=\"scene\"\n clearable\n class=\"filter-ctl\"\n :placeholder=\"t('aiUsage.filter.scenePlaceholder')\"\n />\n </div>\n </div>\n </n-card>\n\n <!-- 四格指标:totals 与分组表共用同一次 summary 请求,不重复请求 -->\n <div class=\"metrics\">\n <n-card\n v-for=\"m in metrics\"\n :key=\"m.key\"\n class=\"a-card\"\n size=\"small\"\n :bordered=\"true\"\n content-style=\"padding: 12px 14px\"\n >\n <div class=\"metric-body\">\n <div class=\"metric-main\">\n <n-skeleton v-if=\"summaryLoading\" text width=\"72px\" height=\"34px\" />\n <div v-else class=\"metric-val tabular\">\n <template v-if=\"m.empty\">—</template>\n <template v-else>\n <n-number-animation :from=\"0\" :to=\"m.value\" show-separator />\n <small v-if=\"m.suffix\" class=\"metric-suffix\">{{ ' ' + m.suffix }}</small>\n </template>\n </div>\n <div class=\"metric-label muted\">{{ t(`aiUsage.metric.${m.key}`) }}</div>\n </div>\n <div class=\"metric-icon\" aria-hidden=\"true\"><AppIcon :icon=\"m.icon\" :size=\"15\" /></div>\n </div>\n </n-card>\n </div>\n\n <!-- 趋势图:区间内无数据的日期后端已补 0,直接画连续折线 -->\n <n-card\n :title=\"t('aiUsage.trend.title')\"\n class=\"a-card\"\n size=\"small\"\n :bordered=\"true\"\n content-style=\"padding: 8px 14px 12px\"\n >\n <n-skeleton v-if=\"trendLoading\" height=\"320px\" :sharp=\"false\" />\n <LineChart v-else :categories=\"trendCategories\" :series=\"trendSeries\" />\n </n-card>\n\n <!-- 分组维度 Tab + 分组表:切 Tab 换 groupBy 重新拉 summary;窄档换成卡片列表 -->\n <n-card class=\"a-card\" size=\"small\" :bordered=\"true\" content-style=\"padding: 4px 14px 12px\">\n <n-tabs v-model:value=\"activeGroupBy\" type=\"line\" animated>\n <n-tab-pane\n v-for=\"tab in groupTabs\"\n :key=\"tab.value\"\n :name=\"tab.value\"\n :tab=\"t(`aiUsage.groupBy.${tab.labelKey}`)\"\n display-directive=\"show:lazy\"\n >\n <SmartTable\n :columns=\"groupColumns\"\n :data=\"groups\"\n row-key=\"key\"\n :loading=\"summaryLoading\"\n :search=\"{ container: 'table' }\"\n :toolbar=\"TABLE_TOOLBAR\"\n :card-props=\"{ bordered: false }\"\n :scroll-x=\"720\"\n card-on-narrow\n storage-key=\"sys-ai-usage-group\"\n >\n <template #pagination-prefix=\"{ itemCount }\">\n <TableTotal :count=\"itemCount\" />\n </template>\n </SmartTable>\n </n-tab-pane>\n </n-tabs>\n </n-card>\n\n <!-- 明细表:顶部筛选走 :params(与条件构造器的 success 键不冲突),「结果」走内置条件搜索 -->\n <SmartTable\n :columns=\"detailColumns\"\n :fetcher=\"aiUsageApi.page\"\n :params=\"filterParams\"\n :search=\"{ container: 'table' }\"\n :toolbar=\"TABLE_TOOLBAR\"\n :default-page-size=\"20\"\n card-on-narrow\n storage-key=\"sys-ai-usage\"\n @error=\"(e: unknown) => message.error(translateError(e))\"\n >\n <template #pagination-prefix=\"{ itemCount }\">\n <TableTotal :count=\"itemCount\" />\n </template>\n </SmartTable>\n </div>\n</template>\n\n<style scoped>\n/* 容器查询的容器:四格指标的列数按内容区宽度分档(窄 1 / 中 2 / 宽 4),不看视口 */\n.view {\n display: flex;\n flex-direction: column;\n gap: var(--gap-card, 8px);\n container-type: inline-size;\n}\n.filter-bar {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-end;\n gap: 12px 20px;\n}\n.filter-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n.filter-label {\n font-size: 13px;\n}\n.date-filter-row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.date-picker {\n width: 290px;\n}\n.filter-ctl {\n width: 180px;\n}\n.quick-range {\n display: flex;\n gap: 4px;\n}\n/* 窄档:每个筛选项独占一行,控件撑满 */\n@container (max-width: 603px) {\n .filter-item {\n flex: 1 1 100%;\n }\n .date-picker,\n .filter-ctl {\n width: 100%;\n }\n .date-picker {\n flex: 1 1 100%;\n }\n}\n.metrics {\n display: grid;\n gap: 8px;\n grid-template-columns: minmax(0, 1fr);\n}\n@container (min-width: 480px) {\n .metrics {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n}\n@container (min-width: 1000px) {\n .metrics {\n grid-template-columns: repeat(4, minmax(0, 1fr));\n }\n}\n.metric-body {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 8px;\n}\n.metric-main {\n min-width: 0;\n}\n.metric-val {\n font-size: 28px;\n font-weight: 600;\n letter-spacing: -0.04em;\n line-height: 1;\n color: var(--text-1);\n white-space: nowrap;\n}\n.metric-suffix {\n margin-left: 4px;\n font-size: 15px;\n letter-spacing: 0;\n color: var(--text-3);\n}\n.metric-label {\n margin-top: 6px;\n font-size: 14px;\n}\n/* 指标图标底块:中性玻璃小方块 */\n.metric-icon {\n flex: none;\n display: grid;\n place-items: center;\n width: 28px;\n height: 28px;\n border-radius: var(--radius-md);\n color: var(--text-1);\n background: var(--glass-strong);\n box-shadow: inset 0 0 0 1px var(--hairline);\n}\n.share-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.share-bar {\n flex: 1;\n min-width: 60px;\n}\n.share-text {\n flex: none;\n width: 58px;\n text-align: right;\n font-size: 13px;\n white-space: nowrap;\n}\n</style>\n"],"names":["t","useI18n","message","useMessage","fmtDate","d","y","m","day","daysAgo","n","quickRangeValue","days","dateRange","ref","activeQuickRange","setQuickRange","onDateRangeUpdate","v","providerCode","model","scene","providerOptions","onMounted","items","aiProviderApi","p","filterParams","computed","groupTabs","AI_USAGE_GROUP_BY","activeGroupBy","summary","summaryLoading","summaryReq","fetchSummary","reqId","res","aiUsageApi","e","translateError","watch","totals","_a","groups","avgLatencyMs","totalCalls","sum","g","metrics","_b","_c","groupDimensionLabel","tab","numCell","h","groupColumns","r","NProgress","trendPoints","trendLoading","trendReq","fetchTrend","trendCategories","trendSeries","detailColumns","fmtDateTime","SEARCH_ACTIONS","NTag","AI_USAGE_SOURCE","deriveHeaderFilters","_openBlock","_createElementBlock","_hoisted_1","_createVNode","_unref","NCard","_createElementVNode","_hoisted_2","_hoisted_3","_hoisted_4","_toDisplayString","_hoisted_5","NDatePicker","_hoisted_6","NButton","_hoisted_7","_hoisted_8","NSelect","$event","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","NInput","_hoisted_13","_Fragment","_renderList","_createBlock","_hoisted_14","_hoisted_15","NSkeleton","_hoisted_16","NNumberAnimation","_hoisted_17","_hoisted_18","_hoisted_19","AppIcon","LineChart","NTabs","NTabPane","SmartTable","TABLE_TOOLBAR","_withCtx","itemCount","TableTotal","_cache"],"mappings":"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"}
@@ -1,5 +1,8 @@
1
- import f from "./index2.vue.js";
1
+ import o from "./index2.vue.js";
2
+ /* empty css */
3
+ import t from "../../../_virtual/_plugin-vue_export-helper.js";
4
+ const p = /* @__PURE__ */ t(o, [["__scopeId", "data-v-7803e913"]]);
2
5
  export {
3
- f as default
6
+ p as default
4
7
  };
5
8
  //# sourceMappingURL=index.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -1,64 +1,114 @@
1
- import { defineComponent as D, onMounted as C, onActivated as N, openBlock as l, createBlock as y, unref as e, withCtx as o, createVNode as a, createElementVNode as p, toDisplayString as n, createTextVNode as s, createElementBlock as g, createCommentVNode as h } from "vue";
2
- import { NCard as x, NSpace as u, NButton as d } from "naive-ui";
3
- import { useClipboard as B } from "@vueuse/core";
4
- import { useI18n as T } from "vue-i18n";
5
- import { runtime as b } from "../../../lib/runtime.js";
6
- import { useUserStore as v } from "../../../stores/user.js";
7
- const S = { key: 0 }, L = /* @__PURE__ */ D({
1
+ import { defineComponent as v, onMounted as y, onActivated as w, openBlock as _, createBlock as z, unref as e, normalizeClass as D, withCtx as i, createVNode as s, createElementVNode as o, toDisplayString as t, createTextVNode as d, createElementBlock as C, createCommentVNode as N } from "vue";
2
+ import { NCard as g, NSpace as x, NButton as m, NDivider as B } from "naive-ui";
3
+ import { useClipboard as b } from "@vueuse/core";
4
+ import { useI18n as S } from "vue-i18n";
5
+ import { useShellBreakpoint as T } from "../../../composables/useShellBreakpoint.js";
6
+ import n from "../../../components/AppIcon.vue.js";
7
+ import { runtime as V } from "../../../lib/runtime.js";
8
+ import { useUserStore as A } from "../../../stores/user.js";
9
+ const E = { class: "lead" }, H = { class: "sym" }, U = { class: "lead-text" }, $ = { class: "lead-title" }, q = { class: "actions" }, G = { class: "actions copy-row" }, I = {
10
+ key: 0,
11
+ class: "copied"
12
+ }, L = { class: "hint" }, M = { class: "warn" }, Z = /* @__PURE__ */ v({
8
13
  __name: "index",
9
- setup(V) {
10
- const { t } = T(), f = v(), { copy: m, copied: _ } = B(), c = `${b.apiBase}/scalar`;
14
+ setup(P) {
15
+ const { t: c } = S(), { bp: a } = T(), u = A(), { copy: f, copied: h } = b(), r = `${V.apiBase}/scalar`;
11
16
  function k() {
12
- m(f.accessToken);
17
+ f(u.accessToken);
13
18
  }
14
- let r = !1;
15
- function i() {
16
- r || (r = !0, window.open(c, "_blank"), Promise.resolve().then(() => {
17
- r = !1;
19
+ let l = !1;
20
+ function p() {
21
+ l || (l = !0, window.open(r, "_blank"), Promise.resolve().then(() => {
22
+ l = !1;
18
23
  }));
19
24
  }
20
- return C(i), N(i), (w, A) => (l(), y(e(x), {
21
- title: e(t)("apiDocs.title")
25
+ return y(p), w(p), (W, j) => (_(), z(e(g), {
26
+ class: D(["a-card docs-card", { "docs-card--narrow": e(a) === "narrow" }]),
27
+ "content-style": "padding: 24px"
22
28
  }, {
23
- default: o(() => [
24
- a(e(u), {
29
+ default: i(() => [
30
+ s(e(x), {
25
31
  vertical: "",
26
- size: "large"
32
+ size: 22
27
33
  }, {
28
- default: o(() => [
29
- p("p", null, n(e(t)("apiDocs.openedHint")), 1),
30
- a(e(d), {
31
- tag: "a",
32
- href: c,
33
- target: "_blank"
34
- }, {
35
- default: o(() => [
36
- s(n(e(t)("apiDocs.fallbackLink")), 1)
34
+ default: i(() => [
35
+ o("div", E, [
36
+ o("span", H, [
37
+ s(n, {
38
+ icon: "ph:file-code",
39
+ size: 20
40
+ })
37
41
  ]),
38
- _: 1
39
- }),
40
- a(e(u), { align: "center" }, {
41
- default: o(() => [
42
- a(e(d), { onClick: k }, {
43
- default: o(() => [
44
- s(n(e(t)("apiDocs.copyToken")), 1)
42
+ o("div", U, [
43
+ o("div", $, t(e(c)("apiDocs.openedHint")), 1),
44
+ o("div", { class: "lead-url" }, t(r))
45
+ ])
46
+ ]),
47
+ o("div", q, [
48
+ s(e(m), {
49
+ tag: "a",
50
+ href: r,
51
+ target: "_blank",
52
+ secondary: "",
53
+ size: e(a) === "narrow" ? "large" : "medium"
54
+ }, {
55
+ icon: i(() => [
56
+ s(n, {
57
+ icon: "ph:arrow-square-out",
58
+ size: 16
59
+ })
60
+ ]),
61
+ default: i(() => [
62
+ d(" " + t(e(c)("apiDocs.fallbackLink")), 1)
63
+ ]),
64
+ _: 1
65
+ }, 8, ["size"])
66
+ ]),
67
+ s(e(B), { class: "split" }),
68
+ o("div", null, [
69
+ o("div", G, [
70
+ s(e(m), {
71
+ secondary: "",
72
+ size: e(a) === "narrow" ? "large" : "medium",
73
+ onClick: k
74
+ }, {
75
+ icon: i(() => [
76
+ s(n, {
77
+ icon: "ph:copy",
78
+ size: 16
79
+ })
80
+ ]),
81
+ default: i(() => [
82
+ d(" " + t(e(c)("apiDocs.copyToken")), 1)
45
83
  ]),
46
84
  _: 1
47
- }),
48
- e(_) ? (l(), g("span", S, n(e(t)("apiDocs.tokenCopied")), 1)) : h("", !0)
85
+ }, 8, ["size"]),
86
+ e(h) ? (_(), C("span", I, [
87
+ s(n, {
88
+ icon: "ph:check-circle",
89
+ size: 16
90
+ }),
91
+ d(" " + t(e(c)("apiDocs.tokenCopied")), 1)
92
+ ])) : N("", !0)
49
93
  ]),
50
- _: 1
51
- }),
52
- p("p", null, n(e(t)("apiDocs.copyTokenHint")), 1)
94
+ o("div", L, t(e(c)("apiDocs.copyTokenHint")), 1),
95
+ o("div", M, [
96
+ s(n, {
97
+ icon: "ph:shield-warning",
98
+ size: 15
99
+ }),
100
+ o("span", null, t(e(c)("apiDocs.tokenWarn")), 1)
101
+ ])
102
+ ])
53
103
  ]),
54
104
  _: 1
55
105
  })
56
106
  ]),
57
107
  _: 1
58
- }, 8, ["title"]));
108
+ }, 8, ["class"]));
59
109
  }
60
110
  });
61
111
  export {
62
- L as default
112
+ Z as default
63
113
  };
64
114
  //# sourceMappingURL=index2.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index2.vue.js","sources":["../../../../src/views/system/api-docs/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onActivated, onMounted } from 'vue'\nimport { NButton, NCard, NSpace } from 'naive-ui'\nimport { useClipboard } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { runtime } from '#/lib/runtime'\nimport { useUserStore } from '#/stores/user'\n\nconst { t } = useI18n()\nconst userStore = useUserStore()\nconst { copy, copied } = useClipboard()\n\nconst scalarUrl = `${runtime.apiBase}/scalar`\n\nfunction copyToken() {\n copy(userStore.accessToken)\n}\n\n// 门闩要保的不变量:不管这是本次会话里第几次挂载,一次全新挂载只应该开一个标签页。页面经\n// defineAsyncComponent 包装挂进 <keep-alive> 时,onMounted 和 onActivated 有可能在同一个 tick\n// 里各调用一次 openDocs(不是只有\"某一次特定的挂载\"才会撞;不能假设第一次挂载就天然安全)。\n// 用一个同步置位、下一个微任务清除的门闩吸收这种\"同 tick 双触发\":两次同步调用只开一次;\n// 而真正的重新激活(用户切走再切回)发生在别的 tick,门闩早已清空,照样正常重开——这正是\n// I7 修复本身要保的行为,不能被这里的去重顺带拿掉。\nlet openGuardActive = false\n\nfunction openDocs() {\n if (openGuardActive) return\n openGuardActive = true\n window.open(scalarUrl, '_blank')\n Promise.resolve().then(() => {\n openGuardActive = false\n })\n}\n\nonMounted(openDocs)\nonActivated(openDocs)\n</script>\n\n<template>\n <NCard :title=\"t('apiDocs.title')\">\n <NSpace vertical size=\"large\">\n <p>{{ t('apiDocs.openedHint') }}</p>\n <NButton tag=\"a\" :href=\"scalarUrl\" target=\"_blank\">{{ t('apiDocs.fallbackLink') }}</NButton>\n <NSpace align=\"center\">\n <NButton @click=\"copyToken\">{{ t('apiDocs.copyToken') }}</NButton>\n <span v-if=\"copied\">{{ t('apiDocs.tokenCopied') }}</span>\n </NSpace>\n <p>{{ t('apiDocs.copyTokenHint') }}</p>\n </NSpace>\n </NCard>\n</template>\n"],"names":["useI18n","userStore","useUserStore","copy","copied","useClipboard","scalarUrl","runtime","copyToken","openGuardActive","openDocs","onMounted","onActivated","_createBlock","_unref","NCard","_createVNode","NSpace","_createElementVNode","NButton","_openBlock","_createElementBlock"],"mappings":";;;;;;;;;AAQA,UAAM,EAAE,EAAA,IAAMA,EAAA,GACRC,IAAYC,EAAA,GACZ,EAAE,MAAAC,GAAM,QAAAC,EAAA,IAAWC,EAAA,GAEnBC,IAAY,GAAGC,EAAQ,OAAO;AAEpC,aAASC,IAAY;AACnB,MAAAL,EAAKF,EAAU,WAAW;AAAA,IAC5B;AAQA,QAAIQ,IAAkB;AAEtB,aAASC,IAAW;AAClB,MAAID,MACJA,IAAkB,IAClB,OAAO,KAAKH,GAAW,QAAQ,GAC/B,QAAQ,UAAU,KAAK,MAAM;AAC3B,QAAAG,IAAkB;AAAA,MACpB,CAAC;AAAA,IACH;AAEA,WAAAE,EAAUD,CAAQ,GAClBE,EAAYF,CAAQ,mBAIlBG,EAUQC,EAAAC,CAAA,GAAA;AAAA,MAVA,OAAOD,EAAA,CAAA,EAAC,eAAA;AAAA,IAAA;iBACd,MAQS;AAAA,QARTE,EAQSF,EAAAG,CAAA,GAAA;AAAA,UARD,UAAA;AAAA,UAAS,MAAK;AAAA,QAAA;qBACpB,MAAoC;AAAA,YAApCC,EAAoC,aAA9BJ,EAAA,CAAA,EAAC,oBAAA,CAAA,GAAA,CAAA;AAAA,YACPE,EAA4FF,EAAAK,CAAA,GAAA;AAAA,cAAnF,KAAI;AAAA,cAAK,MAAMb;AAAA,cAAW,QAAO;AAAA,YAAA;yBAAS,MAA+B;AAAA,oBAA5BQ,EAAA,CAAA,EAAC,sBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;YACvDE,EAGSF,EAAAG,CAAA,GAAA,EAHD,OAAM,YAAQ;AAAA,yBACpB,MAAkE;AAAA,gBAAlED,EAAkEF,EAAAK,CAAA,GAAA,EAAxD,SAAOX,KAAS;AAAA,6BAAE,MAA4B;AAAA,wBAAzBM,EAAA,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,kBAAA;;;gBACpBA,EAAAV,CAAA,KAAZgB,KAAAC,EAAyD,aAAlCP,EAAA,CAAA,EAAC,qBAAA,CAAA,GAAA,CAAA;;;;YAE1BI,EAAuC,aAAjCJ,EAAA,CAAA,EAAC,uBAAA,CAAA,GAAA,CAAA;AAAA,UAAA;;;;;;;;"}
1
+ {"version":3,"file":"index2.vue.js","sources":["../../../../src/views/system/api-docs/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onActivated, onMounted } from 'vue'\nimport { NButton, NCard, NDivider, NSpace } from 'naive-ui'\nimport { useClipboard } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { useShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { runtime } from '#/lib/runtime'\nimport { useUserStore } from '#/stores/user'\n\nconst { t } = useI18n()\nconst { bp } = useShellBreakpoint()\nconst userStore = useUserStore()\nconst { copy, copied } = useClipboard()\n\nconst scalarUrl = `${runtime.apiBase}/scalar`\n\nfunction copyToken() {\n copy(userStore.accessToken)\n}\n\n// 门闩要保的不变量:不管这是本次会话里第几次挂载,一次全新挂载只应该开一个标签页。页面经\n// defineAsyncComponent 包装挂进 <keep-alive> 时,onMounted 和 onActivated 有可能在同一个 tick\n// 里各调用一次 openDocs(不是只有\"某一次特定的挂载\"才会撞;不能假设第一次挂载就天然安全)。\n// 用一个同步置位、下一个微任务清除的门闩吸收这种\"同 tick 双触发\":两次同步调用只开一次;\n// 而真正的重新激活(用户切走再切回)发生在别的 tick,门闩早已清空,照样正常重开——这正是\n// 重新激活必须保留的行为,不能被这里的去重顺带吞掉。\nlet openGuardActive = false\n\nfunction openDocs() {\n if (openGuardActive) return\n openGuardActive = true\n window.open(scalarUrl, '_blank')\n Promise.resolve().then(() => {\n openGuardActive = false\n })\n}\n\nonMounted(openDocs)\nonActivated(openDocs)\n</script>\n\n<template>\n <!-- 外壳卡片:页面不放菜单名标题;进入页面即自动新开 Scalar,这里只做提示 + 兜底入口 + 复制令牌 -->\n <NCard\n class=\"a-card docs-card\"\n :class=\"{ 'docs-card--narrow': bp === 'narrow' }\"\n content-style=\"padding: 24px\"\n >\n <NSpace vertical :size=\"22\">\n <div class=\"lead\">\n <span class=\"sym\"><AppIcon icon=\"ph:file-code\" :size=\"20\" /></span>\n <div class=\"lead-text\">\n <div class=\"lead-title\">{{ t('apiDocs.openedHint') }}</div>\n <div class=\"lead-url\">{{ scalarUrl }}</div>\n </div>\n </div>\n <div class=\"actions\">\n <NButton\n tag=\"a\"\n :href=\"scalarUrl\"\n target=\"_blank\"\n secondary\n :size=\"bp === 'narrow' ? 'large' : 'medium'\"\n >\n <template #icon><AppIcon icon=\"ph:arrow-square-out\" :size=\"16\" /></template>\n {{ t('apiDocs.fallbackLink') }}\n </NButton>\n </div>\n <NDivider class=\"split\" />\n <div>\n <div class=\"actions copy-row\">\n <NButton secondary :size=\"bp === 'narrow' ? 'large' : 'medium'\" @click=\"copyToken\">\n <template #icon><AppIcon icon=\"ph:copy\" :size=\"16\" /></template>\n {{ t('apiDocs.copyToken') }}\n </NButton>\n <span v-if=\"copied\" class=\"copied\">\n <AppIcon icon=\"ph:check-circle\" :size=\"16\" />\n {{ t('apiDocs.tokenCopied') }}\n </span>\n </div>\n <div class=\"hint\">{{ t('apiDocs.copyTokenHint') }}</div>\n <div class=\"warn\">\n <AppIcon icon=\"ph:shield-warning\" :size=\"15\" />\n <span>{{ t('apiDocs.tokenWarn') }}</span>\n </div>\n </div>\n </NSpace>\n </NCard>\n</template>\n\n<style scoped>\n.docs-card {\n width: 100%;\n max-width: 760px;\n margin: 0 auto;\n}\n.lead {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n/* 图标底块:中性玻璃 */\n.sym {\n display: grid;\n place-items: center;\n flex-shrink: 0;\n width: 28px;\n height: 28px;\n border-radius: var(--radius-md);\n color: var(--text-1);\n background: var(--glass-strong);\n box-shadow:\n inset 0 0 0 1px var(--hairline),\n inset 0 1px 0 var(--edge-light);\n}\n.lead-text {\n min-width: 0;\n}\n.lead-title {\n font-size: 16px;\n font-weight: 600;\n}\n.lead-url {\n margin-top: 2px;\n font-family: var(--font-mono, ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace);\n font-size: 13.5px;\n color: var(--text-3);\n overflow-wrap: anywhere;\n}\n.split {\n margin: 0;\n}\n.copy-row {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n.copied {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 14px;\n color: var(--ok);\n}\n.hint {\n margin-top: 12px;\n font-size: 14px;\n line-height: 1.7;\n color: var(--text-2);\n}\n.warn {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n margin-top: 6px;\n font-size: 13px;\n line-height: 1.6;\n color: var(--text-3);\n}\n.warn > :first-child {\n flex: none;\n margin-top: 3px;\n}\n/* 窄档(内容区 < 600):按钮铺满一行,好点 */\n.docs-card--narrow .actions :deep(.n-button) {\n width: 100%;\n}\n.docs-card--narrow .copy-row {\n flex-direction: column;\n align-items: stretch;\n}\n</style>\n"],"names":["t","useI18n","bp","useShellBreakpoint","userStore","useUserStore","copy","copied","useClipboard","scalarUrl","runtime","copyToken","openGuardActive","openDocs","onMounted","onActivated","_createBlock","_unref","NCard","_normalizeClass","_createVNode","NSpace","_createElementVNode","_hoisted_1","_hoisted_2","AppIcon","_hoisted_3","_hoisted_4","_toDisplayString","_hoisted_5","NButton","_createTextVNode","NDivider","_hoisted_6","_openBlock","_createElementBlock","_hoisted_7","_hoisted_8","_hoisted_9"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import o from "./index2.vue.js";
2
2
  /* empty css */
3
3
  import t from "../../../_virtual/_plugin-vue_export-helper.js";
4
- const p = /* @__PURE__ */ t(o, [["__scopeId", "data-v-21abb77a"]]);
4
+ const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-a699819f"]]);
5
5
  export {
6
- p as default
6
+ m as default
7
7
  };
8
8
  //# sourceMappingURL=index.vue.js.map
@@ -1,113 +1,107 @@
1
- import { defineComponent as v, ref as g, resolveDirective as x, openBlock as h, createElementBlock as d, createVNode as s, unref as e, withCtx as n, Fragment as C, renderList as N, withDirectives as D, createBlock as T, createElementVNode as i, toDisplayString as a, createTextVNode as b } from "vue";
2
- import { useMessage as w, NGrid as P, NGi as S, NCard as $, NButton as z } from "naive-ui";
3
- import { useI18n as B } from "vue-i18n";
1
+ import { defineComponent as x, computed as C, ref as w, resolveDirective as b, openBlock as l, createElementBlock as m, createElementVNode as c, normalizeClass as z, Fragment as D, renderList as S, withDirectives as T, createBlock as B, unref as o, withCtx as u, createVNode as p, toDisplayString as n, createTextVNode as N } from "vue";
2
+ import { useMessage as P, NCard as $, NButton as O } from "naive-ui";
3
+ import { useI18n as E } from "vue-i18n";
4
4
  import f from "../../../components/AppIcon.vue.js";
5
- import { useConfirm as O } from "../../../composables/useConfirm.js";
6
- import { cacheApi as l } from "../../../api/index.js";
7
- import { translateError as E } from "../../../utils/error.js";
8
- const V = { class: "cache" }, A = { class: "head" }, G = { class: "title" }, q = { class: "desc" }, F = { class: "note" }, U = /* @__PURE__ */ v({
5
+ import { useShellBreakpoint as V } from "../../../composables/useShellBreakpoint.js";
6
+ import { useConfirm as A } from "../../../composables/useConfirm.js";
7
+ import { cacheApi as a } from "../../../api/index.js";
8
+ import { translateError as q } from "../../../utils/error.js";
9
+ const F = { class: "cache" }, I = { class: "head" }, L = { class: "sym" }, M = { class: "title" }, j = { class: "desc" }, G = { class: "act" }, H = { class: "note" }, te = /* @__PURE__ */ x({
9
10
  __name: "index",
10
- setup(I) {
11
- const { t } = B(), p = w(), { ask: m } = O(), y = [
11
+ setup(J) {
12
+ const { t: e } = E(), h = P(), { ask: _ } = A(), { bp: y } = V(), d = C(() => y.value === "narrow"), k = [
12
13
  {
13
14
  key: "auth",
14
- icon: "ph:shield-check-duotone",
15
+ icon: "ph:shield-check",
15
16
  perm: "POST:/api/v1/sys/cache/flush-auth",
16
- run: l.flushAuth
17
+ run: a.flushAuth
17
18
  },
18
19
  {
19
20
  key: "dict",
20
- icon: "ph:book-open-text-duotone",
21
+ icon: "ph:book-open-text",
21
22
  perm: "POST:/api/v1/sys/cache/flush-dict",
22
- run: l.flushDict
23
+ run: a.flushDict
23
24
  },
24
25
  {
25
26
  key: "config",
26
- icon: "ph:sliders-horizontal-duotone",
27
+ icon: "ph:sliders-horizontal",
27
28
  perm: "POST:/api/v1/sys/cache/flush-config",
28
- run: l.flushConfig
29
+ run: a.flushConfig
29
30
  },
30
31
  {
31
32
  key: "portal",
32
- icon: "ph:squares-four-duotone",
33
+ icon: "ph:squares-four",
33
34
  perm: "POST:/api/v1/sys/cache/rebuild-portal",
34
- run: l.rebuildPortal
35
+ run: a.rebuildPortal
35
36
  }
36
- ], u = g(null);
37
- async function _(c) {
38
- if (await m({ type: "warning", content: t(`cache.${c.key}Confirm`) })) {
39
- u.value = c.key;
37
+ ], i = w(null);
38
+ async function v(s) {
39
+ if (await _({ type: "warning", content: e(`cache.${s.key}Confirm`) })) {
40
+ i.value = s.key;
40
41
  try {
41
- const r = await c.run();
42
- p.success(c.key === "portal" ? t("cache.portalDone") : t("cache.flushed", { n: r }));
42
+ const r = await s.run();
43
+ h.success(s.key === "portal" ? e("cache.portalDone") : e("cache.flushed", { n: r }));
43
44
  } catch (r) {
44
- p.error(E(r));
45
+ h.error(q(r));
45
46
  } finally {
46
- u.value = null;
47
+ i.value = null;
47
48
  }
48
49
  }
49
50
  }
50
- return (c, r) => {
51
- const k = x("auth");
52
- return h(), d("div", V, [
53
- s(e(P), {
54
- cols: "1 s:2 l:2",
55
- responsive: "screen",
56
- "x-gap": 12,
57
- "y-gap": 12
58
- }, {
59
- default: n(() => [
60
- (h(), d(C, null, N(y, (o) => D((h(), T(e(S), {
61
- key: o.key
62
- }, {
63
- default: n(() => [
64
- s(e($), {
65
- size: "small",
66
- class: "action-card"
51
+ return (s, r) => {
52
+ const g = b("auth");
53
+ return l(), m("div", F, [
54
+ c("div", {
55
+ class: z(["cards", { "cards--narrow": d.value }])
56
+ }, [
57
+ (l(), m(D, null, S(k, (t) => T((l(), B(o($), {
58
+ key: t.key,
59
+ class: "a-card action-card",
60
+ "content-style": "padding: 16px 18px"
61
+ }, {
62
+ default: u(() => [
63
+ c("div", I, [
64
+ c("span", L, [
65
+ p(f, {
66
+ icon: t.icon,
67
+ size: 16
68
+ }, null, 8, ["icon"])
69
+ ]),
70
+ c("b", M, n(o(e)(`cache.${t.key}Title`)), 1)
71
+ ]),
72
+ c("p", j, n(o(e)(`cache.${t.key}Desc`)), 1),
73
+ c("div", G, [
74
+ p(o(O), {
75
+ type: "primary",
76
+ secondary: "",
77
+ size: d.value ? "large" : "medium",
78
+ loading: i.value === t.key,
79
+ onClick: (K) => v(t)
67
80
  }, {
68
- default: n(() => [
69
- i("div", A, [
70
- s(f, {
71
- icon: o.icon,
72
- size: 22
73
- }, null, 8, ["icon"]),
74
- i("span", G, a(e(t)(`cache.${o.key}Title`)), 1)
75
- ]),
76
- i("p", q, a(e(t)(`cache.${o.key}Desc`)), 1),
77
- s(e(z), {
78
- type: "primary",
79
- secondary: "",
80
- loading: u.value === o.key,
81
- onClick: (L) => _(o)
82
- }, {
83
- icon: n(() => [
84
- s(f, {
85
- icon: "ph:broom",
86
- size: 16
87
- })
88
- ]),
89
- default: n(() => [
90
- b(" " + a(e(t)("cache.execute")), 1)
91
- ]),
92
- _: 1
93
- }, 8, ["loading", "onClick"])
81
+ icon: u(() => [
82
+ p(f, {
83
+ icon: "ph:broom",
84
+ size: 16
85
+ })
94
86
  ]),
95
- _: 2
96
- }, 1024)
97
- ]),
98
- _: 2
99
- }, 1024)), [
100
- [k, o.perm]
101
- ])), 64))
102
- ]),
103
- _: 1
104
- }),
105
- i("p", F, a(e(t)("cache.note")), 1)
87
+ default: u(() => [
88
+ N(" " + n(o(e)("cache.execute")), 1)
89
+ ]),
90
+ _: 1
91
+ }, 8, ["size", "loading", "onClick"])
92
+ ])
93
+ ]),
94
+ _: 2
95
+ }, 1024)), [
96
+ [g, t.perm]
97
+ ])), 64))
98
+ ], 2),
99
+ c("p", H, n(o(e)("cache.note")), 1)
106
100
  ]);
107
101
  };
108
102
  }
109
103
  });
110
104
  export {
111
- U as default
105
+ te as default
112
106
  };
113
107
  //# sourceMappingURL=index2.vue.js.map