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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WatermarkSection2.vue.js","sources":["../../../../../src/views/system/config/components/WatermarkSection.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 水印设置:左边「内容」「样式」两组设置,右边预览(缩小版后台,水印层直接叠在上面,改一项即时变)。\n// 水印只印在登录后的页面,所以预览只有后台一种,不像「品牌与登录页」要切登录页。\nimport { computed } from 'vue'\nimport { NCheckbox, NCheckboxGroup, NInput, NSelect, NSlider, NSwitch } from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport {\n DEFAULT_WATERMARK,\n formatWatermarkTime,\n normalizeWatermarkFields,\n watermarkFromValues,\n watermarkParts,\n WATERMARK_FIELDS,\n WATERMARK_KEY,\n WATERMARK_LIMITS,\n WATERMARK_TIME_FORMATS,\n type WatermarkDensity,\n type WatermarkLayout,\n type WatermarkTimeFormat,\n} from '#/lib/watermark'\nimport { useConfigDraft, useDraftFields } from '../draft'\nimport { useConfigLayout } from '../layoutMode'\nimport SectionLayout from './SectionLayout.vue'\nimport CfgGroup from './CfgGroup.vue'\nimport CfgRow from './CfgRow.vue'\nimport CfgSegment from './CfgSegment.vue'\nimport ScaleToFit from './ScaleToFit.vue'\nimport AdminMock from './AdminMock.vue'\n\nconst { t } = useI18n()\nconst { values } = useConfigDraft()\nconst { str, num, bool } = useDraftFields()\nconst { ctl } = useConfigLayout()\n\n// 内容项勾选顺序不算数,存的时候按固定顺序排,线上和预览才印得一样;键不存在(老库没种子)按默认内容项。\nconst wmOn = bool(WATERMARK_KEY.enabled)\nconst wmFields = computed<string[]>({\n get: () =>\n values[WATERMARK_KEY.fields] === undefined\n ? [...DEFAULT_WATERMARK.fields]\n : normalizeWatermarkFields(values[WATERMARK_KEY.fields]),\n set: v => {\n values[WATERMARK_KEY.fields] = normalizeWatermarkFields(v).join(',')\n },\n})\nconst wmText = str(WATERMARK_KEY.text)\nconst wmEnum = <T extends string>(key: string, fallback: T) =>\n computed<T>({\n get: () => (values[key] || fallback) as T,\n set: v => {\n values[key] = v\n },\n })\nconst wmTimeFormat = wmEnum<WatermarkTimeFormat>(\n WATERMARK_KEY.timeFormat,\n DEFAULT_WATERMARK.timeFormat,\n)\nconst wmLayout = wmEnum<WatermarkLayout>(WATERMARK_KEY.layout, DEFAULT_WATERMARK.layout)\nconst wmDensity = wmEnum<WatermarkDensity>(WATERMARK_KEY.density, DEFAULT_WATERMARK.density)\nconst wmSize = num(WATERMARK_KEY.fontSize, DEFAULT_WATERMARK.fontSize)\nconst wmOpacity = num(WATERMARK_KEY.opacity, DEFAULT_WATERMARK.opacity)\nconst wmRotate = num(WATERMARK_KEY.rotate, DEFAULT_WATERMARK.rotate)\nconst wmCross = computed({\n get: () => values[WATERMARK_KEY.cross] !== 'false',\n set: v => {\n values[WATERMARK_KEY.cross] = v ? 'true' : 'false'\n },\n})\nconst wmHasField = (f: string) => wmFields.value.includes(f)\nconst wmFieldOptions = computed(() =>\n WATERMARK_FIELDS.map(f => ({ value: f, label: t(`config.watermark.field.${f}`) })),\n)\n// 时间格式的选项文字就是「现在这一刻按该格式印出来」的样子,不用背格式串\nconst wmTimeOptions = computed(() =>\n WATERMARK_TIME_FORMATS.map(f => ({ value: f, label: formatWatermarkTime(f, new Date()) })),\n)\nconst wmLayoutOptions = computed(() => [\n { value: 'single' as const, label: t('config.watermark.layoutSingle') },\n { value: 'multi' as const, label: t('config.watermark.layoutMulti') },\n])\nconst wmDensityOptions = computed(() => [\n { value: 'sparse' as const, label: t('config.watermark.sparse') },\n { value: 'normal' as const, label: t('config.watermark.normal') },\n { value: 'dense' as const, label: t('config.watermark.dense') },\n])\n// 启用了但没有任何可印的东西(一项没勾,或只勾了自定义文字却没填):警告,照常允许保存\nconst wmEmpty = computed(\n () =>\n wmOn.value &&\n watermarkParts(\n watermarkFromValues(values),\n { name: 'x', account: 'x', org: 'x', phoneTail: 'x' },\n new Date(),\n ).length === 0,\n)\n</script>\n\n<template>\n <SectionLayout\n :title=\"t('config.tab.watermark')\"\n :desc=\"t('config.watermark.desc')\"\n :preview-title=\"t('config.brand.preview')\"\n >\n <CfgGroup :title=\"t('config.watermark.groupContent')\">\n <CfgRow\n :label=\"t('config.watermark.enable')\"\n :hint=\"t('config.watermark.enableHint')\"\n :keys=\"[WATERMARK_KEY.enabled]\"\n >\n <n-switch v-model:value=\"wmOn\" :aria-label=\"t('config.watermark.enable')\" />\n </CfgRow>\n <CfgRow\n :label=\"t('config.watermark.content')\"\n :keys=\"[WATERMARK_KEY.fields]\"\n :disabled=\"!wmOn\"\n tall\n class=\"wm-content\"\n >\n <template #hint>\n <span :class=\"{ warn: wmEmpty }\">\n {{ wmEmpty ? t('config.watermark.contentEmpty') : t('config.watermark.contentHint') }}\n </span>\n </template>\n <n-checkbox-group v-model:value=\"wmFields\" :disabled=\"!wmOn\">\n <div class=\"wm-fields\">\n <n-checkbox\n v-for=\"o in wmFieldOptions\"\n :key=\"o.value\"\n :value=\"o.value\"\n :label=\"o.label\"\n />\n </div>\n </n-checkbox-group>\n </CfgRow>\n <CfgRow\n :label=\"t('config.watermark.text')\"\n :hint=\"t('config.watermark.textHint')\"\n :keys=\"[WATERMARK_KEY.text]\"\n :disabled=\"!wmOn || !wmHasField('text')\"\n sub\n >\n <n-input\n v-model:value=\"wmText\"\n :size=\"ctl\"\n :maxlength=\"WATERMARK_LIMITS.text\"\n show-count\n :disabled=\"!wmOn || !wmHasField('text')\"\n :placeholder=\"t('config.watermark.textPlaceholder', { max: WATERMARK_LIMITS.text })\"\n :input-props=\"{ 'aria-label': t('config.watermark.text') }\"\n />\n </CfgRow>\n <CfgRow\n :label=\"t('config.watermark.timeFormat')\"\n :keys=\"[WATERMARK_KEY.timeFormat]\"\n :disabled=\"!wmOn || !wmHasField('time')\"\n sub\n >\n <n-select\n v-model:value=\"wmTimeFormat\"\n :size=\"ctl\"\n :options=\"wmTimeOptions\"\n :disabled=\"!wmOn || !wmHasField('time')\"\n :aria-label=\"t('config.watermark.timeFormat')\"\n />\n </CfgRow>\n </CfgGroup>\n\n <CfgGroup :title=\"t('config.watermark.groupStyle')\">\n <CfgRow\n :label=\"t('config.watermark.layout')\"\n :keys=\"[WATERMARK_KEY.layout]\"\n :disabled=\"!wmOn\"\n >\n <CfgSegment\n v-model=\"wmLayout\"\n :options=\"wmLayoutOptions\"\n :label=\"t('config.watermark.layout')\"\n />\n </CfgRow>\n <CfgRow\n :label=\"t('config.watermark.fontSize')\"\n :keys=\"[WATERMARK_KEY.fontSize]\"\n :disabled=\"!wmOn\"\n >\n <n-slider\n v-model:value=\"wmSize\"\n class=\"slider\"\n :min=\"WATERMARK_LIMITS.fontSize.min\"\n :max=\"WATERMARK_LIMITS.fontSize.max\"\n :tooltip=\"false\"\n :disabled=\"!wmOn\"\n :aria-label=\"t('config.watermark.fontSize')\"\n />\n <span class=\"unit\">{{ wmSize }} px</span>\n </CfgRow>\n <CfgRow\n :label=\"t('config.watermark.opacity')\"\n :hint=\"t('config.watermark.opacityHint')\"\n :keys=\"[WATERMARK_KEY.opacity]\"\n :disabled=\"!wmOn\"\n >\n <n-slider\n v-model:value=\"wmOpacity\"\n class=\"slider\"\n :min=\"WATERMARK_LIMITS.opacity.min\"\n :max=\"WATERMARK_LIMITS.opacity.max\"\n :tooltip=\"false\"\n :disabled=\"!wmOn\"\n :aria-label=\"t('config.watermark.opacity')\"\n />\n <span class=\"unit\">{{ wmOpacity }}%</span>\n </CfgRow>\n <CfgRow\n :label=\"t('config.watermark.rotate')\"\n :keys=\"[WATERMARK_KEY.rotate]\"\n :disabled=\"!wmOn\"\n >\n <n-slider\n v-model:value=\"wmRotate\"\n class=\"slider\"\n :min=\"WATERMARK_LIMITS.rotate.min\"\n :max=\"WATERMARK_LIMITS.rotate.max\"\n :step=\"5\"\n :tooltip=\"false\"\n :disabled=\"!wmOn\"\n :aria-label=\"t('config.watermark.rotate')\"\n />\n <span class=\"unit\">{{ wmRotate }}°</span>\n </CfgRow>\n <CfgRow\n :label=\"t('config.watermark.density')\"\n :keys=\"[WATERMARK_KEY.density]\"\n :disabled=\"!wmOn\"\n >\n <CfgSegment\n v-model=\"wmDensity\"\n :options=\"wmDensityOptions\"\n :label=\"t('config.watermark.density')\"\n />\n </CfgRow>\n <CfgRow\n :label=\"t('config.watermark.cross')\"\n :hint=\"t('config.watermark.crossHint')\"\n :keys=\"[WATERMARK_KEY.cross]\"\n :disabled=\"!wmOn\"\n >\n <n-switch\n v-model:value=\"wmCross\"\n :disabled=\"!wmOn\"\n :aria-label=\"t('config.watermark.cross')\"\n />\n </CfgRow>\n </CfgGroup>\n\n <template #preview>\n <ScaleToFit :width=\"880\" :height=\"540\">\n <AdminMock />\n </ScaleToFit>\n </template>\n </SectionLayout>\n</template>\n\n<style scoped>\n.warn {\n color: var(--warn);\n}\n.wm-content :deep(.ctl) {\n flex: 1.8 1 0;\n}\n.wm-content :deep(.n-checkbox-group) {\n width: 100%;\n}\n.wm-fields {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: 8px 16px;\n}\n.slider {\n width: 160px;\n}\n.unit {\n flex: none;\n min-width: 44px;\n font-size: 13px;\n color: var(--text-2);\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n</style>\n"],"names":["t","useI18n","values","useConfigDraft","str","num","bool","useDraftFields","ctl","useConfigLayout","wmOn","WATERMARK_KEY","wmFields","computed","DEFAULT_WATERMARK","normalizeWatermarkFields","v","wmText","wmEnum","key","fallback","wmTimeFormat","wmLayout","wmDensity","wmSize","wmOpacity","wmRotate","wmCross","wmHasField","f","wmFieldOptions","WATERMARK_FIELDS","wmTimeOptions","WATERMARK_TIME_FORMATS","formatWatermarkTime","wmLayoutOptions","wmDensityOptions","wmEmpty","watermarkParts","watermarkFromValues","_createBlock","SectionLayout","_unref","_createVNode","ScaleToFit","AdminMock","CfgGroup","CfgRow","NSwitch","$event","_createElementVNode","NCheckboxGroup","_hoisted_1","_createElementBlock","_Fragment","_renderList","o","NCheckbox","NInput","WATERMARK_LIMITS","NSelect","CfgSegment","NSlider","_hoisted_2","_toDisplayString","_hoisted_3","_hoisted_4"],"mappings":"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"}
@@ -17,7 +17,7 @@ export interface DraftCheck {
17
17
  message: string;
18
18
  }[];
19
19
  }
20
- /** 登录页 Hero 的规则:卖点最多 5 条(阻止);强调词不在主标题里(提示,照常保存)。 */
20
+ /** 登录页 Hero 的规则:亮点最多 5 条(阻止);强调词不在主标题里(提示,照常保存)。 */
21
21
  export declare function checkDraft(values: Record<string, string>): DraftCheck;
22
22
  export declare function createConfigDraft(): {
23
23
  original: Record<string, string>;
@@ -129,7 +129,7 @@ export declare function createConfigDraft(): {
129
129
  text: () => Promise<string>;
130
130
  } | null>;
131
131
  dirtyKeys: import('vue').ComputedRef<string[]>;
132
- dirtyTabs: import('vue').ComputedRef<Set<"security" | "brand" | "advanced" | "job" | "sensitive" | "upload" | "signin">>;
132
+ dirtyTabs: import('vue').ComputedRef<Set<"security" | "brand" | "watermark" | "advanced" | "job" | "sensitive" | "upload" | "signin">>;
133
133
  claimedKeys: import('vue').ComputedRef<string[]>;
134
134
  load: () => Promise<void>;
135
135
  refreshProviders: () => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"draft.js","sources":["../../../../src/views/system/config/draft.ts"],"sourcesContent":["// 配置中心的页面级草稿:进页面一次载入所有结构化表单的值,各分类只读写这份草稿,\n// 底部保存条统一保存。切换顶部导航不会丢改动;离开页面草稿随组件销毁。\nimport { computed, inject, provide, reactive, ref, type InjectionKey } from 'vue'\nimport {\n configApi,\n externalAuthApi,\n type ExternalAuthCatalog,\n type ExternalProviderAdmin,\n} from '#/api'\nimport { loadSite } from '#/composables/useSite'\nimport { splitLoginHeroFeatures } from '#/lib/loginHero'\nimport { buildConfigProviderRows, LINK_BY_ACCOUNT_CODES } from '#/utils/oauthBrand'\nimport {\n bumpConfigRevision,\n heroKeys,\n LOGIN_LOCALES,\n LOGO_KEY,\n STATIC_CLAIMED_KEYS,\n STRUCTURED_GROUPS,\n tabOfKey,\n type ConfigTab,\n type LoginLocale,\n} from './groups'\n\nexport const enabledKey = (code: string) => `sys.externalauth.${code}.enabled`\nexport const linkKey = (code: string) => `sys.externalauth.${code}.linkByAccount`\nexport const hasLinkSwitch = (code: string) => LINK_BY_ACCOUNT_CODES.includes(code)\n\n/** 与原值不同的键(按字符串比较;配置值一律以字符串落库)。 */\nexport function diffKeys(original: Record<string, string>, values: Record<string, string>) {\n return Object.keys(values).filter(key => values[key] !== original[key])\n}\n\n/** 保存前的校验结论:error 阻止保存并跳到对应分类,warnings 只提示。 */\nexport interface DraftCheck {\n error?: { tab: ConfigTab; message: string; locale?: LoginLocale }\n warnings: { locale: LoginLocale; message: string }[]\n}\n\n/** 登录页 Hero 的规则:卖点最多 5 条(阻止);强调词不在主标题里(提示,照常保存)。 */\nexport function checkDraft(values: Record<string, string>): DraftCheck {\n const warnings: DraftCheck['warnings'] = []\n for (const locale of LOGIN_LOCALES) {\n const keys = heroKeys(locale)\n if (splitLoginHeroFeatures(values[keys.features], Number.MAX_SAFE_INTEGER).length > 5)\n return { error: { tab: 'brand', locale, message: 'config.login.tooManyFeatures' }, warnings }\n const headline = values[keys.headline]?.trim() ?? ''\n const highlight = values[keys.highlight]?.trim() ?? ''\n if (highlight && headline && !headline.includes(highlight))\n warnings.push({ locale, message: 'config.login.highlightMissing' })\n }\n return { warnings }\n}\n\nexport function createConfigDraft() {\n const original = reactive<Record<string, string>>({})\n const values = reactive<Record<string, string>>({})\n const providers = ref<ExternalProviderAdmin[]>([])\n const catalog = ref<ExternalAuthCatalog>({\n dataProtectionEphemeral: false,\n callbackBaseUrlMissing: false,\n callbackUriTemplate: '',\n types: [],\n providers: [],\n })\n const loading = ref(true)\n const saving = ref(false)\n /** 裁剪好、还没上传的 Logo;预览期间 values[LOGO_KEY] 是它的 blob: 地址,保存时才上传 */\n const pendingLogo = ref<Blob | null>(null)\n\n const providerRows = computed(() => buildConfigProviderRows(catalog.value, providers.value))\n const dirtyKeys = computed(() => diffKeys(original, values))\n const dirtyTabs = computed(() => new Set(dirtyKeys.value.map(tabOfKey)))\n /** 结构化表单认领的全部键:「高级」页排除它们。未注册的第三方登录方式也算,它们的开关在卡片上。 */\n const claimedKeys = computed(() => [\n ...STATIC_CLAIMED_KEYS,\n ...providerRows.value.flatMap(p =>\n hasLinkSwitch(p.code) ? [enabledKey(p.code), linkKey(p.code)] : [enabledKey(p.code)],\n ),\n ])\n\n function reset(next: Record<string, string>) {\n for (const key of Object.keys(original)) delete original[key]\n for (const key of Object.keys(values)) delete values[key]\n Object.assign(original, next)\n Object.assign(values, next)\n }\n\n async function load() {\n loading.value = true\n try {\n const [groups, list, cat] = await Promise.all([\n Promise.all(STRUCTURED_GROUPS.map(g => configApi.listByGroup(g))),\n externalAuthApi.providersAll(),\n externalAuthApi.catalog(),\n ])\n providers.value = list\n catalog.value = cat\n const claimed = new Set(STATIC_CLAIMED_KEYS)\n const next: Record<string, string> = {}\n // 库里没有的键按空串起步:表单显示默认值,不动它就不算改动,也不会被写回\n for (const key of STATIC_CLAIMED_KEYS) next[key] = ''\n for (const row of groups.flat())\n if (claimed.has(row.configKey)) next[row.configKey] = row.configValue ?? ''\n // 第三方登录只收已配置的方式:没配好的开关不可打开,永远不写\n Object.assign(next, providerSwitchValues())\n reset(next)\n } finally {\n loading.value = false\n }\n }\n\n /** 已配置的第三方各自的开关值(enabled / linkByAccount)。 */\n function providerSwitchValues() {\n const out: Record<string, string> = {}\n for (const p of providerRows.value.filter(row => row.registered)) {\n out[enabledKey(p.code)] = String(p.enabled)\n if (hasLinkSwitch(p.code)) out[linkKey(p.code)] = String(p.linkByAccount)\n }\n return out\n }\n\n /**\n * 设置面板保存或清除之后重读第三方目录。已在草稿里的开关不动(可能有未保存的改动),\n * 新配好的补进来,被清掉的移出——没有配置的方式,开关没有意义。\n */\n async function refreshProviders() {\n const [list, cat] = await Promise.all([\n externalAuthApi.providersAll(),\n externalAuthApi.catalog(),\n ])\n providers.value = list\n catalog.value = cat\n const fresh = providerSwitchValues()\n for (const [key, value] of Object.entries(fresh)) {\n if (key in original) continue\n original[key] = value\n values[key] = value\n }\n for (const row of providerRows.value.filter(r => !r.registered)) {\n for (const key of [enabledKey(row.code), linkKey(row.code)]) {\n delete original[key]\n delete values[key]\n }\n }\n }\n\n function setPendingLogo(blob: Blob | null, previewUrl: string) {\n revokePreview()\n pendingLogo.value = blob\n values[LOGO_KEY] = previewUrl\n }\n\n function revokePreview() {\n if (values[LOGO_KEY]?.startsWith('blob:')) URL.revokeObjectURL(values[LOGO_KEY])\n }\n\n function discard() {\n revokePreview()\n pendingLogo.value = null\n Object.assign(values, original)\n }\n\n /** 保存全部改动;有待传的 Logo 先上传换成签名直链,再一次批量写库。 */\n async function save() {\n saving.value = true\n try {\n if (pendingLogo.value) {\n const file = new File([pendingLogo.value], 'logo.png', { type: 'image/png' })\n const uploaded = await configApi.uploadLogo(file)\n revokePreview()\n values[LOGO_KEY] = uploaded.viewUrl ?? ''\n // 传完就清掉:后面批量保存失败时重试不会再传一遍\n pendingLogo.value = null\n }\n for (const key of dirtyKeys.value) values[key] = values[key].trim()\n const items = diffKeys(original, values).map(configKey => ({\n configKey,\n configValue: values[configKey],\n }))\n if (items.length) await configApi.saveBatch(items)\n Object.assign(original, values)\n bumpConfigRevision()\n // 即时生效:侧栏、顶栏、登录页、浏览器标签页的品牌随之刷新\n await loadSite(true)\n } finally {\n saving.value = false\n }\n }\n\n return {\n original,\n values,\n providers,\n catalog,\n providerRows,\n loading,\n saving,\n pendingLogo,\n dirtyKeys,\n dirtyTabs,\n claimedKeys,\n load,\n refreshProviders,\n discard,\n save,\n setPendingLogo,\n }\n}\n\nexport type ConfigDraft = ReturnType<typeof createConfigDraft>\n\nconst DRAFT_KEY: InjectionKey<ConfigDraft> = Symbol('config-draft')\n\nexport function provideConfigDraft(draft: ConfigDraft) {\n provide(DRAFT_KEY, draft)\n}\n\nexport function useConfigDraft(): ConfigDraft {\n const draft = inject(DRAFT_KEY)\n if (!draft) throw new Error('useConfigDraft() 只能在配置中心页面内使用')\n return draft\n}\n\n/** 字符串 / 数值 / 开关三种双向绑定,模板里直接 v-model。 */\nexport function useDraftFields() {\n const { values } = useConfigDraft()\n return {\n str: (key: string) =>\n computed({\n get: () => values[key] ?? '',\n set: v => {\n values[key] = v ?? ''\n },\n }),\n num: (key: string, fallback: number) =>\n computed<number>({\n get: () => {\n const n = Number(values[key])\n return values[key] === '' || values[key] === undefined || Number.isNaN(n) ? fallback : n\n },\n set: v => {\n values[key] = String(v ?? fallback)\n },\n }),\n bool: (key: string) =>\n computed<boolean>({\n get: () => values[key] === 'true',\n set: v => {\n values[key] = v ? 'true' : 'false'\n },\n }),\n }\n}\n"],"names":["enabledKey","code","linkKey","hasLinkSwitch","LINK_BY_ACCOUNT_CODES","diffKeys","original","values","key","checkDraft","warnings","locale","LOGIN_LOCALES","keys","heroKeys","splitLoginHeroFeatures","headline","_a","highlight","_b","createConfigDraft","reactive","providers","ref","catalog","loading","saving","pendingLogo","providerRows","computed","buildConfigProviderRows","dirtyKeys","dirtyTabs","tabOfKey","claimedKeys","STATIC_CLAIMED_KEYS","p","reset","next","load","groups","list","cat","STRUCTURED_GROUPS","configApi","g","externalAuthApi","claimed","row","providerSwitchValues","out","refreshProviders","fresh","value","r","setPendingLogo","blob","previewUrl","revokePreview","LOGO_KEY","discard","save","file","uploaded","items","configKey","bumpConfigRevision","loadSite","DRAFT_KEY","provideConfigDraft","draft","provide","useConfigDraft","inject","useDraftFields","v","fallback","n"],"mappings":"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"}
1
+ {"version":3,"file":"draft.js","sources":["../../../../src/views/system/config/draft.ts"],"sourcesContent":["// 配置中心的页面级草稿:进页面一次载入所有结构化表单的值,各分类只读写这份草稿,\n// 底部保存条统一保存。切换顶部导航不会丢改动;离开页面草稿随组件销毁。\nimport { computed, inject, provide, reactive, ref, type InjectionKey } from 'vue'\nimport {\n configApi,\n externalAuthApi,\n type ExternalAuthCatalog,\n type ExternalProviderAdmin,\n} from '#/api'\nimport { loadSite } from '#/composables/useSite'\nimport { splitLoginHeroFeatures } from '#/lib/loginHero'\nimport { buildConfigProviderRows, LINK_BY_ACCOUNT_CODES } from '#/utils/oauthBrand'\nimport {\n bumpConfigRevision,\n heroKeys,\n LOGIN_LOCALES,\n LOGO_KEY,\n STATIC_CLAIMED_KEYS,\n STRUCTURED_GROUPS,\n tabOfKey,\n type ConfigTab,\n type LoginLocale,\n} from './groups'\n\nexport const enabledKey = (code: string) => `sys.externalauth.${code}.enabled`\nexport const linkKey = (code: string) => `sys.externalauth.${code}.linkByAccount`\nexport const hasLinkSwitch = (code: string) => LINK_BY_ACCOUNT_CODES.includes(code)\n\n/** 与原值不同的键(按字符串比较;配置值一律以字符串落库)。 */\nexport function diffKeys(original: Record<string, string>, values: Record<string, string>) {\n return Object.keys(values).filter(key => values[key] !== original[key])\n}\n\n/** 保存前的校验结论:error 阻止保存并跳到对应分类,warnings 只提示。 */\nexport interface DraftCheck {\n error?: { tab: ConfigTab; message: string; locale?: LoginLocale }\n warnings: { locale: LoginLocale; message: string }[]\n}\n\n/** 登录页 Hero 的规则:亮点最多 5 条(阻止);强调词不在主标题里(提示,照常保存)。 */\nexport function checkDraft(values: Record<string, string>): DraftCheck {\n const warnings: DraftCheck['warnings'] = []\n for (const locale of LOGIN_LOCALES) {\n const keys = heroKeys(locale)\n if (splitLoginHeroFeatures(values[keys.features], Number.MAX_SAFE_INTEGER).length > 5)\n return { error: { tab: 'brand', locale, message: 'config.login.tooManyFeatures' }, warnings }\n const headline = values[keys.headline]?.trim() ?? ''\n const highlight = values[keys.highlight]?.trim() ?? ''\n if (highlight && headline && !headline.includes(highlight))\n warnings.push({ locale, message: 'config.login.highlightMissing' })\n }\n return { warnings }\n}\n\nexport function createConfigDraft() {\n const original = reactive<Record<string, string>>({})\n const values = reactive<Record<string, string>>({})\n const providers = ref<ExternalProviderAdmin[]>([])\n const catalog = ref<ExternalAuthCatalog>({\n dataProtectionEphemeral: false,\n callbackBaseUrlMissing: false,\n callbackUriTemplate: '',\n types: [],\n providers: [],\n })\n const loading = ref(true)\n const saving = ref(false)\n /** 裁剪好、还没上传的 Logo;预览期间 values[LOGO_KEY] 是它的 blob: 地址,保存时才上传 */\n const pendingLogo = ref<Blob | null>(null)\n\n const providerRows = computed(() => buildConfigProviderRows(catalog.value, providers.value))\n const dirtyKeys = computed(() => diffKeys(original, values))\n const dirtyTabs = computed(() => new Set(dirtyKeys.value.map(tabOfKey)))\n /** 结构化表单认领的全部键:「高级」页排除它们。未注册的第三方登录方式也算,它们的开关在卡片上。 */\n const claimedKeys = computed(() => [\n ...STATIC_CLAIMED_KEYS,\n ...providerRows.value.flatMap(p =>\n hasLinkSwitch(p.code) ? [enabledKey(p.code), linkKey(p.code)] : [enabledKey(p.code)],\n ),\n ])\n\n function reset(next: Record<string, string>) {\n for (const key of Object.keys(original)) delete original[key]\n for (const key of Object.keys(values)) delete values[key]\n Object.assign(original, next)\n Object.assign(values, next)\n }\n\n async function load() {\n loading.value = true\n try {\n const [groups, list, cat] = await Promise.all([\n Promise.all(STRUCTURED_GROUPS.map(g => configApi.listByGroup(g))),\n externalAuthApi.providersAll(),\n externalAuthApi.catalog(),\n ])\n providers.value = list\n catalog.value = cat\n const claimed = new Set(STATIC_CLAIMED_KEYS)\n const next: Record<string, string> = {}\n // 库里没有的键按空串起步:表单显示默认值,不动它就不算改动,也不会被写回\n for (const key of STATIC_CLAIMED_KEYS) next[key] = ''\n for (const row of groups.flat())\n if (claimed.has(row.configKey)) next[row.configKey] = row.configValue ?? ''\n // 第三方登录只收已配置的方式:没配好的开关不可打开,永远不写\n Object.assign(next, providerSwitchValues())\n reset(next)\n } finally {\n loading.value = false\n }\n }\n\n /** 已配置的第三方各自的开关值(enabled / linkByAccount)。 */\n function providerSwitchValues() {\n const out: Record<string, string> = {}\n for (const p of providerRows.value.filter(row => row.registered)) {\n out[enabledKey(p.code)] = String(p.enabled)\n if (hasLinkSwitch(p.code)) out[linkKey(p.code)] = String(p.linkByAccount)\n }\n return out\n }\n\n /**\n * 设置面板保存或清除之后重读第三方目录。已在草稿里的开关不动(可能有未保存的改动),\n * 新配好的补进来,被清掉的移出——没有配置的方式,开关没有意义。\n */\n async function refreshProviders() {\n const [list, cat] = await Promise.all([\n externalAuthApi.providersAll(),\n externalAuthApi.catalog(),\n ])\n providers.value = list\n catalog.value = cat\n const fresh = providerSwitchValues()\n for (const [key, value] of Object.entries(fresh)) {\n if (key in original) continue\n original[key] = value\n values[key] = value\n }\n for (const row of providerRows.value.filter(r => !r.registered)) {\n for (const key of [enabledKey(row.code), linkKey(row.code)]) {\n delete original[key]\n delete values[key]\n }\n }\n }\n\n function setPendingLogo(blob: Blob | null, previewUrl: string) {\n revokePreview()\n pendingLogo.value = blob\n values[LOGO_KEY] = previewUrl\n }\n\n function revokePreview() {\n if (values[LOGO_KEY]?.startsWith('blob:')) URL.revokeObjectURL(values[LOGO_KEY])\n }\n\n function discard() {\n revokePreview()\n pendingLogo.value = null\n Object.assign(values, original)\n }\n\n /** 保存全部改动;有待传的 Logo 先上传换成签名直链,再一次批量写库。 */\n async function save() {\n saving.value = true\n try {\n if (pendingLogo.value) {\n const file = new File([pendingLogo.value], 'logo.png', { type: 'image/png' })\n const uploaded = await configApi.uploadLogo(file)\n revokePreview()\n values[LOGO_KEY] = uploaded.viewUrl ?? ''\n // 传完就清掉:后面批量保存失败时重试不会再传一遍\n pendingLogo.value = null\n }\n for (const key of dirtyKeys.value) values[key] = values[key].trim()\n const items = diffKeys(original, values).map(configKey => ({\n configKey,\n configValue: values[configKey],\n }))\n if (items.length) await configApi.saveBatch(items)\n Object.assign(original, values)\n bumpConfigRevision()\n // 即时生效:侧栏、顶栏、登录页、浏览器标签页的品牌随之刷新\n await loadSite(true)\n } finally {\n saving.value = false\n }\n }\n\n return {\n original,\n values,\n providers,\n catalog,\n providerRows,\n loading,\n saving,\n pendingLogo,\n dirtyKeys,\n dirtyTabs,\n claimedKeys,\n load,\n refreshProviders,\n discard,\n save,\n setPendingLogo,\n }\n}\n\nexport type ConfigDraft = ReturnType<typeof createConfigDraft>\n\nconst DRAFT_KEY: InjectionKey<ConfigDraft> = Symbol('config-draft')\n\nexport function provideConfigDraft(draft: ConfigDraft) {\n provide(DRAFT_KEY, draft)\n}\n\nexport function useConfigDraft(): ConfigDraft {\n const draft = inject(DRAFT_KEY)\n if (!draft) throw new Error('useConfigDraft() 只能在配置中心页面内使用')\n return draft\n}\n\n/** 字符串 / 数值 / 开关三种双向绑定,模板里直接 v-model。 */\nexport function useDraftFields() {\n const { values } = useConfigDraft()\n return {\n str: (key: string) =>\n computed({\n get: () => values[key] ?? '',\n set: v => {\n values[key] = v ?? ''\n },\n }),\n num: (key: string, fallback: number) =>\n computed<number>({\n get: () => {\n const n = Number(values[key])\n return values[key] === '' || values[key] === undefined || Number.isNaN(n) ? fallback : n\n },\n set: v => {\n values[key] = String(v ?? fallback)\n },\n }),\n bool: (key: string) =>\n computed<boolean>({\n get: () => values[key] === 'true',\n set: v => {\n values[key] = v ? 'true' : 'false'\n },\n }),\n }\n}\n"],"names":["enabledKey","code","linkKey","hasLinkSwitch","LINK_BY_ACCOUNT_CODES","diffKeys","original","values","key","checkDraft","warnings","locale","LOGIN_LOCALES","keys","heroKeys","splitLoginHeroFeatures","headline","_a","highlight","_b","createConfigDraft","reactive","providers","ref","catalog","loading","saving","pendingLogo","providerRows","computed","buildConfigProviderRows","dirtyKeys","dirtyTabs","tabOfKey","claimedKeys","STATIC_CLAIMED_KEYS","p","reset","next","load","groups","list","cat","STRUCTURED_GROUPS","configApi","g","externalAuthApi","claimed","row","providerSwitchValues","out","refreshProviders","fresh","value","r","setPendingLogo","blob","previewUrl","revokePreview","LOGO_KEY","discard","save","file","uploaded","items","configKey","bumpConfigRevision","loadSite","DRAFT_KEY","provideConfigDraft","draft","provide","useConfigDraft","inject","useDraftFields","v","fallback","n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- export declare const CONFIG_TABS: readonly ["brand", "security", "signin", "sensitive", "upload", "job", "advanced"];
1
+ import { WATERMARK_KEYS } from '../../../lib/watermark';
2
+ export declare const CONFIG_TABS: readonly ["brand", "signin", "security", "watermark", "sensitive", "upload", "job", "advanced"];
2
3
  export type ConfigTab = (typeof CONFIG_TABS)[number];
3
4
  /** 顶部导航分组:站点与安全 | 系统,组间留空。 */
4
5
  export declare const TAB_GROUPS: readonly (readonly ConfigTab[])[];
@@ -6,6 +7,8 @@ export declare const TAB_GROUPS: readonly (readonly ConfigTab[])[];
6
7
  export declare const TAB_ICONS: Record<ConfigTab, string>;
7
8
  export declare const LOGO_KEY = "sys.site.logo";
8
9
  export declare const BRAND_KEYS: readonly ["sys.site.title", "sys.site.logo", "sys.site.copyright", "sys.site.copyrightUrl"];
10
+ /** 水印的 10 个键(`sys.watermark.*`),在「水印设置」页编辑 */
11
+ export { WATERMARK_KEYS };
9
12
  export declare const LOGIN_LOCALES: readonly ["zh-CN", "en-US"];
10
13
  export type LoginLocale = (typeof LOGIN_LOCALES)[number];
11
14
  export declare const heroKeys: (locale: LoginLocale) => {
@@ -1,37 +1,40 @@
1
1
  import { ref as e } from "vue";
2
+ import { WATERMARK_KEYS as i } from "../../../lib/watermark.js";
2
3
  const L = [
3
4
  "brand",
4
- "security",
5
5
  "signin",
6
+ "security",
7
+ "watermark",
6
8
  "sensitive",
7
9
  "upload",
8
10
  "job",
9
11
  "advanced"
10
- ], O = [
11
- ["brand", "security", "signin", "sensitive"],
12
+ ], T = [
13
+ ["brand", "signin", "security", "watermark", "sensitive"],
12
14
  ["upload", "job", "advanced"]
13
- ], T = {
15
+ ], f = {
14
16
  brand: "ph:browser",
15
- security: "ph:shield-check",
16
17
  signin: "ph:sign-in",
18
+ security: "ph:shield-check",
19
+ watermark: "ph:drop",
17
20
  sensitive: "ph:lock-key",
18
21
  upload: "ph:cloud-arrow-up",
19
22
  job: "ph:clock",
20
23
  advanced: "ph:sliders-horizontal"
21
- }, i = "sys.site.logo", r = [
24
+ }, r = "sys.site.logo", o = [
22
25
  "sys.site.title",
23
- i,
26
+ r,
24
27
  "sys.site.copyright",
25
28
  "sys.site.copyrightUrl"
26
- ], o = ["zh-CN", "en-US"], n = (s) => ({
29
+ ], n = ["zh-CN", "en-US"], a = (s) => ({
27
30
  headline: `sys.login.hero.headline.${s}`,
28
31
  highlight: `sys.login.hero.highlight.${s}`,
29
32
  features: `sys.login.hero.features.${s}`
30
- }), c = "sys.site.subtitle", y = "sys.login.hero.showFeatures", a = [
33
+ }), c = "sys.site.subtitle", y = "sys.login.hero.showFeatures", u = [
31
34
  c,
32
35
  y,
33
- ...o.flatMap((s) => Object.values(n(s)))
34
- ], u = {
36
+ ...n.flatMap((s) => Object.values(a(s)))
37
+ ], d = {
35
38
  "sys.security.loginLock.maxFailCount": 0,
36
39
  "sys.security.loginLock.lockMinutes": 1,
37
40
  "sys.security.password.minLength": 1,
@@ -42,7 +45,7 @@ const L = [
42
45
  "sys.security.rateLimit.windowSeconds": 1,
43
46
  "sys.security.rateLimit.permitPerWindow": 0,
44
47
  "sys.security.rateLimit.authPermitPerWindow": 0
45
- }, t = "sys.security.smsLogin.enabled", d = [
48
+ }, t = "sys.security.smsLogin.enabled", p = [
46
49
  "sys.security.password.requireUpper",
47
50
  "sys.security.password.requireLower",
48
51
  "sys.security.password.requireDigit",
@@ -53,51 +56,53 @@ const L = [
53
56
  "sys.security.totp.requireForSuperAdmin",
54
57
  "sys.security.mfa.enabled",
55
58
  "sys.security.rateLimit.enabled"
56
- ], l = "sys.security.captcha.type", h = [
57
- ...Object.keys(u),
58
- ...d,
59
- l,
59
+ ], h = "sys.security.captcha.type", l = [
60
+ ...Object.keys(d),
61
+ ...p,
62
+ h,
60
63
  t
61
- ], p = "sys.upload.maxSizeMb", E = "sys.upload.allowedExtensions", g = "sys.job.logRetentionDays", S = "sys.job.alertEmails", f = [
62
- ...r,
63
- ...a,
64
- ...h,
65
- p,
64
+ ], E = "sys.upload.maxSizeMb", S = "sys.upload.allowedExtensions", _ = "sys.job.logRetentionDays", g = "sys.job.alertEmails", O = [
65
+ ...o,
66
+ ...u,
67
+ ...i,
68
+ ...l,
66
69
  E,
67
- g,
68
- S
69
- ], w = ["sys", "login", "security", "upload", "job"];
70
- function C(s) {
71
- return s.startsWith("sys.site.") || s.startsWith("sys.login.") ? "brand" : s === t || s.startsWith("sys.externalauth.") ? "signin" : s.startsWith("sys.security.") ? "security" : s.startsWith("sys.upload.") ? "upload" : s.startsWith("sys.job.") ? "job" : "advanced";
70
+ S,
71
+ _,
72
+ g
73
+ ], Y = ["sys", "login", "security", "upload", "job"];
74
+ function A(s) {
75
+ return s.startsWith("sys.site.") || s.startsWith("sys.login.") ? "brand" : s.startsWith("sys.watermark.") ? "watermark" : s === t || s.startsWith("sys.externalauth.") ? "signin" : s.startsWith("sys.security.") ? "security" : s.startsWith("sys.upload.") ? "upload" : s.startsWith("sys.job.") ? "job" : "advanced";
72
76
  }
73
- const _ = e(0);
74
- function Y() {
75
- _.value++;
77
+ const b = e(0);
78
+ function C() {
79
+ b.value++;
76
80
  }
77
81
  export {
78
- r as BRAND_KEYS,
79
- l as CAPTCHA_TYPE_KEY,
82
+ o as BRAND_KEYS,
83
+ h as CAPTCHA_TYPE_KEY,
80
84
  L as CONFIG_TABS,
81
- S as JOB_ALERT_KEY,
82
- g as JOB_RETENTION_KEY,
83
- a as LOGIN_KEYS,
84
- o as LOGIN_LOCALES,
85
- i as LOGO_KEY,
86
- h as SECURITY_KEYS,
87
- u as SECURITY_NUMBERS,
88
- d as SECURITY_SWITCHES,
85
+ g as JOB_ALERT_KEY,
86
+ _ as JOB_RETENTION_KEY,
87
+ u as LOGIN_KEYS,
88
+ n as LOGIN_LOCALES,
89
+ r as LOGO_KEY,
90
+ l as SECURITY_KEYS,
91
+ d as SECURITY_NUMBERS,
92
+ p as SECURITY_SWITCHES,
89
93
  y as SHOW_FEATURES_KEY,
90
94
  t as SMS_LOGIN_KEY,
91
- f as STATIC_CLAIMED_KEYS,
92
- w as STRUCTURED_GROUPS,
95
+ O as STATIC_CLAIMED_KEYS,
96
+ Y as STRUCTURED_GROUPS,
93
97
  c as SUBTITLE_KEY,
94
- O as TAB_GROUPS,
95
- T as TAB_ICONS,
96
- E as UPLOAD_EXTS_KEY,
97
- p as UPLOAD_MAX_KEY,
98
- Y as bumpConfigRevision,
99
- _ as configRevision,
100
- n as heroKeys,
101
- C as tabOfKey
98
+ T as TAB_GROUPS,
99
+ f as TAB_ICONS,
100
+ S as UPLOAD_EXTS_KEY,
101
+ E as UPLOAD_MAX_KEY,
102
+ i as WATERMARK_KEYS,
103
+ C as bumpConfigRevision,
104
+ b as configRevision,
105
+ a as heroKeys,
106
+ A as tabOfKey
102
107
  };
103
108
  //# sourceMappingURL=groups.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"groups.js","sources":["../../../../src/views/system/config/groups.ts"],"sourcesContent":["// 配置中心的分类与键归属。顶部导航每一项是一个分类,分类名就是它管的那一类东西;\n// 结构化表单认领的键由这里集中声明,\n// 草稿只装这些键,「高级」页据此排除它们(同一个键不会在两处都能改)。\nimport { ref } from 'vue'\n\nexport const CONFIG_TABS = [\n 'brand',\n 'security',\n 'signin',\n 'sensitive',\n 'upload',\n 'job',\n 'advanced',\n] as const\nexport type ConfigTab = (typeof CONFIG_TABS)[number]\n\n/** 顶部导航分组:站点与安全 | 系统,组间留空。 */\nexport const TAB_GROUPS: readonly (readonly ConfigTab[])[] = [\n ['brand', 'security', 'signin', 'sensitive'],\n ['upload', 'job', 'advanced'],\n]\n\n/** 导航图标 */\nexport const TAB_ICONS: Record<ConfigTab, string> = {\n brand: 'ph:browser',\n security: 'ph:shield-check',\n signin: 'ph:sign-in',\n sensitive: 'ph:lock-key',\n upload: 'ph:cloud-arrow-up',\n job: 'ph:clock',\n advanced: 'ph:sliders-horizontal',\n}\n\nexport const LOGO_KEY = 'sys.site.logo'\nexport const BRAND_KEYS = [\n 'sys.site.title',\n LOGO_KEY,\n 'sys.site.copyright',\n 'sys.site.copyrightUrl',\n] as const\n\nexport const LOGIN_LOCALES = ['zh-CN', 'en-US'] as const\nexport type LoginLocale = (typeof LOGIN_LOCALES)[number]\nexport const heroKeys = (locale: LoginLocale) => ({\n headline: `sys.login.hero.headline.${locale}`,\n highlight: `sys.login.hero.highlight.${locale}`,\n features: `sys.login.hero.features.${locale}`,\n})\nexport const SUBTITLE_KEY = 'sys.site.subtitle'\nexport const SHOW_FEATURES_KEY = 'sys.login.hero.showFeatures'\nexport const LOGIN_KEYS = [\n SUBTITLE_KEY,\n SHOW_FEATURES_KEY,\n ...LOGIN_LOCALES.flatMap(l => Object.values(heroKeys(l))),\n]\n\n// 数值项的下限:锁定阈值不为负、时长至少 1 分钟,避免存 0 变成永不过期/永久锁定。\n// 0 在少数项上是合法的\"关闭\"语义(永不过期、不防重用、不限流)。\nexport const SECURITY_NUMBERS: Readonly<Record<string, number>> = {\n 'sys.security.loginLock.maxFailCount': 0,\n 'sys.security.loginLock.lockMinutes': 1,\n 'sys.security.password.minLength': 1,\n 'sys.security.password.expireDays': 0,\n 'sys.security.password.historyCount': 0,\n 'sys.security.session.accessMinutes': 1,\n 'sys.security.session.refreshMinutes': 1,\n 'sys.security.rateLimit.windowSeconds': 1,\n 'sys.security.rateLimit.permitPerWindow': 0,\n 'sys.security.rateLimit.authPermitPerWindow': 0,\n}\n/** 短信验证码登录是一种登录方式,在「登录方式」页,不在安全策略 */\nexport const SMS_LOGIN_KEY = 'sys.security.smsLogin.enabled'\nexport const SECURITY_SWITCHES = [\n 'sys.security.password.requireUpper',\n 'sys.security.password.requireLower',\n 'sys.security.password.requireDigit',\n 'sys.security.password.requireSpecial',\n 'sys.security.password.forceChangeOnFirstLogin',\n 'sys.security.captcha.enabled',\n 'sys.security.totp.enabled',\n 'sys.security.totp.requireForSuperAdmin',\n 'sys.security.mfa.enabled',\n 'sys.security.rateLimit.enabled',\n] as const\nexport const CAPTCHA_TYPE_KEY = 'sys.security.captcha.type'\nexport const SECURITY_KEYS = [\n ...Object.keys(SECURITY_NUMBERS),\n ...SECURITY_SWITCHES,\n CAPTCHA_TYPE_KEY,\n SMS_LOGIN_KEY,\n]\n\nexport const UPLOAD_MAX_KEY = 'sys.upload.maxSizeMb'\nexport const UPLOAD_EXTS_KEY = 'sys.upload.allowedExtensions'\nexport const JOB_RETENTION_KEY = 'sys.job.logRetentionDays'\nexport const JOB_ALERT_KEY = 'sys.job.alertEmails'\n\n/** 固定认领的键(第三方登录的键按已注册的方式动态认领,见 draft.ts)。 */\nexport const STATIC_CLAIMED_KEYS: readonly string[] = [\n ...BRAND_KEYS,\n ...LOGIN_KEYS,\n ...SECURITY_KEYS,\n UPLOAD_MAX_KEY,\n UPLOAD_EXTS_KEY,\n JOB_RETENTION_KEY,\n JOB_ALERT_KEY,\n]\n\n/** 结构化表单从这些分组取值。 */\nexport const STRUCTURED_GROUPS = ['sys', 'login', 'security', 'upload', 'job'] as const\n\n/** 键 → 所属分类,用于导航上的\"有未保存改动\"标记。 */\nexport function tabOfKey(key: string): ConfigTab {\n if (key.startsWith('sys.site.') || key.startsWith('sys.login.')) return 'brand'\n if (key === SMS_LOGIN_KEY || key.startsWith('sys.externalauth.')) return 'signin'\n if (key.startsWith('sys.security.')) return 'security'\n if (key.startsWith('sys.upload.')) return 'upload'\n if (key.startsWith('sys.job.')) return 'job'\n return 'advanced'\n}\n\n/** 配置行增删改的版本号:保存或在「高级」页改了行之后 bump,「高级」表据此重拉。 */\nexport const configRevision = ref(0)\n\nexport function bumpConfigRevision() {\n configRevision.value++\n}\n"],"names":["CONFIG_TABS","TAB_GROUPS","TAB_ICONS","LOGO_KEY","BRAND_KEYS","LOGIN_LOCALES","heroKeys","locale","SUBTITLE_KEY","SHOW_FEATURES_KEY","LOGIN_KEYS","l","SECURITY_NUMBERS","SMS_LOGIN_KEY","SECURITY_SWITCHES","CAPTCHA_TYPE_KEY","SECURITY_KEYS","UPLOAD_MAX_KEY","UPLOAD_EXTS_KEY","JOB_RETENTION_KEY","JOB_ALERT_KEY","STATIC_CLAIMED_KEYS","STRUCTURED_GROUPS","tabOfKey","key","configRevision","ref","bumpConfigRevision"],"mappings":";AAKO,MAAMA,IAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAIaC,IAAgD;AAAA,EAC3D,CAAC,SAAS,YAAY,UAAU,WAAW;AAAA,EAC3C,CAAC,UAAU,OAAO,UAAU;AAC9B,GAGaC,IAAuC;AAAA,EAClD,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,UAAU;AACZ,GAEaC,IAAW,iBACXC,IAAa;AAAA,EACxB;AAAA,EACAD;AAAA,EACA;AAAA,EACA;AACF,GAEaE,IAAgB,CAAC,SAAS,OAAO,GAEjCC,IAAW,CAACC,OAAyB;AAAA,EAChD,UAAU,2BAA2BA,CAAM;AAAA,EAC3C,WAAW,4BAA4BA,CAAM;AAAA,EAC7C,UAAU,2BAA2BA,CAAM;AAC7C,IACaC,IAAe,qBACfC,IAAoB,+BACpBC,IAAa;AAAA,EACxBF;AAAA,EACAC;AAAA,EACA,GAAGJ,EAAc,QAAQ,CAAAM,MAAK,OAAO,OAAOL,EAASK,CAAC,CAAC,CAAC;AAC1D,GAIaC,IAAqD;AAAA,EAChE,uCAAuC;AAAA,EACvC,sCAAsC;AAAA,EACtC,mCAAmC;AAAA,EACnC,oCAAoC;AAAA,EACpC,sCAAsC;AAAA,EACtC,sCAAsC;AAAA,EACtC,uCAAuC;AAAA,EACvC,wCAAwC;AAAA,EACxC,0CAA0C;AAAA,EAC1C,8CAA8C;AAChD,GAEaC,IAAgB,iCAChBC,IAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GACaC,IAAmB,6BACnBC,IAAgB;AAAA,EAC3B,GAAG,OAAO,KAAKJ,CAAgB;AAAA,EAC/B,GAAGE;AAAA,EACHC;AAAA,EACAF;AACF,GAEaI,IAAiB,wBACjBC,IAAkB,gCAClBC,IAAoB,4BACpBC,IAAgB,uBAGhBC,IAAyC;AAAA,EACpD,GAAGjB;AAAA,EACH,GAAGM;AAAA,EACH,GAAGM;AAAA,EACHC;AAAA,EACAC;AAAA,EACAC;AAAA,EACAC;AACF,GAGaE,IAAoB,CAAC,OAAO,SAAS,YAAY,UAAU,KAAK;AAGtE,SAASC,EAASC,GAAwB;AAC/C,SAAIA,EAAI,WAAW,WAAW,KAAKA,EAAI,WAAW,YAAY,IAAU,UACpEA,MAAQX,KAAiBW,EAAI,WAAW,mBAAmB,IAAU,WACrEA,EAAI,WAAW,eAAe,IAAU,aACxCA,EAAI,WAAW,aAAa,IAAU,WACtCA,EAAI,WAAW,UAAU,IAAU,QAChC;AACT;AAGO,MAAMC,IAAiBC,EAAI,CAAC;AAE5B,SAASC,IAAqB;AACnC,EAAAF,EAAe;AACjB;"}
1
+ {"version":3,"file":"groups.js","sources":["../../../../src/views/system/config/groups.ts"],"sourcesContent":["// 配置中心的分类与键归属。顶部导航每一项是一个分类,分类名就是它管的那一类东西;\n// 结构化表单认领的键由这里集中声明,\n// 草稿只装这些键,「高级」页据此排除它们(同一个键不会在两处都能改)。\nimport { ref } from 'vue'\nimport { WATERMARK_KEYS } from '#/lib/watermark'\n\nexport const CONFIG_TABS = [\n 'brand',\n 'signin',\n 'security',\n 'watermark',\n 'sensitive',\n 'upload',\n 'job',\n 'advanced',\n] as const\nexport type ConfigTab = (typeof CONFIG_TABS)[number]\n\n/** 顶部导航分组:站点与安全 | 系统,组间留空。 */\nexport const TAB_GROUPS: readonly (readonly ConfigTab[])[] = [\n ['brand', 'signin', 'security', 'watermark', 'sensitive'],\n ['upload', 'job', 'advanced'],\n]\n\n/** 导航图标 */\nexport const TAB_ICONS: Record<ConfigTab, string> = {\n brand: 'ph:browser',\n signin: 'ph:sign-in',\n security: 'ph:shield-check',\n watermark: 'ph:drop',\n sensitive: 'ph:lock-key',\n upload: 'ph:cloud-arrow-up',\n job: 'ph:clock',\n advanced: 'ph:sliders-horizontal',\n}\n\nexport const LOGO_KEY = 'sys.site.logo'\nexport const BRAND_KEYS = [\n 'sys.site.title',\n LOGO_KEY,\n 'sys.site.copyright',\n 'sys.site.copyrightUrl',\n] as const\n\n/** 水印的 10 个键(`sys.watermark.*`),在「水印设置」页编辑 */\nexport { WATERMARK_KEYS }\n\nexport const LOGIN_LOCALES = ['zh-CN', 'en-US'] as const\nexport type LoginLocale = (typeof LOGIN_LOCALES)[number]\nexport const heroKeys = (locale: LoginLocale) => ({\n headline: `sys.login.hero.headline.${locale}`,\n highlight: `sys.login.hero.highlight.${locale}`,\n features: `sys.login.hero.features.${locale}`,\n})\nexport const SUBTITLE_KEY = 'sys.site.subtitle'\nexport const SHOW_FEATURES_KEY = 'sys.login.hero.showFeatures'\nexport const LOGIN_KEYS = [\n SUBTITLE_KEY,\n SHOW_FEATURES_KEY,\n ...LOGIN_LOCALES.flatMap(l => Object.values(heroKeys(l))),\n]\n\n// 数值项的下限:锁定阈值不为负、时长至少 1 分钟,避免存 0 变成永不过期/永久锁定。\n// 0 在少数项上是合法的\"关闭\"语义(永不过期、不防重用、不限流)。\nexport const SECURITY_NUMBERS: Readonly<Record<string, number>> = {\n 'sys.security.loginLock.maxFailCount': 0,\n 'sys.security.loginLock.lockMinutes': 1,\n 'sys.security.password.minLength': 1,\n 'sys.security.password.expireDays': 0,\n 'sys.security.password.historyCount': 0,\n 'sys.security.session.accessMinutes': 1,\n 'sys.security.session.refreshMinutes': 1,\n 'sys.security.rateLimit.windowSeconds': 1,\n 'sys.security.rateLimit.permitPerWindow': 0,\n 'sys.security.rateLimit.authPermitPerWindow': 0,\n}\n/** 短信验证码登录是一种登录方式,在「登录方式」页,不在安全策略 */\nexport const SMS_LOGIN_KEY = 'sys.security.smsLogin.enabled'\nexport const SECURITY_SWITCHES = [\n 'sys.security.password.requireUpper',\n 'sys.security.password.requireLower',\n 'sys.security.password.requireDigit',\n 'sys.security.password.requireSpecial',\n 'sys.security.password.forceChangeOnFirstLogin',\n 'sys.security.captcha.enabled',\n 'sys.security.totp.enabled',\n 'sys.security.totp.requireForSuperAdmin',\n 'sys.security.mfa.enabled',\n 'sys.security.rateLimit.enabled',\n] as const\nexport const CAPTCHA_TYPE_KEY = 'sys.security.captcha.type'\nexport const SECURITY_KEYS = [\n ...Object.keys(SECURITY_NUMBERS),\n ...SECURITY_SWITCHES,\n CAPTCHA_TYPE_KEY,\n SMS_LOGIN_KEY,\n]\n\nexport const UPLOAD_MAX_KEY = 'sys.upload.maxSizeMb'\nexport const UPLOAD_EXTS_KEY = 'sys.upload.allowedExtensions'\nexport const JOB_RETENTION_KEY = 'sys.job.logRetentionDays'\nexport const JOB_ALERT_KEY = 'sys.job.alertEmails'\n\n/** 固定认领的键(第三方登录的键按已注册的方式动态认领,见 draft.ts)。 */\nexport const STATIC_CLAIMED_KEYS: readonly string[] = [\n ...BRAND_KEYS,\n ...LOGIN_KEYS,\n ...WATERMARK_KEYS,\n ...SECURITY_KEYS,\n UPLOAD_MAX_KEY,\n UPLOAD_EXTS_KEY,\n JOB_RETENTION_KEY,\n JOB_ALERT_KEY,\n]\n\n/** 结构化表单从这些分组取值。 */\nexport const STRUCTURED_GROUPS = ['sys', 'login', 'security', 'upload', 'job'] as const\n\n/** 键 → 所属分类,用于导航上的\"有未保存改动\"标记。 */\nexport function tabOfKey(key: string): ConfigTab {\n if (key.startsWith('sys.site.') || key.startsWith('sys.login.')) return 'brand'\n if (key.startsWith('sys.watermark.')) return 'watermark'\n if (key === SMS_LOGIN_KEY || key.startsWith('sys.externalauth.')) return 'signin'\n if (key.startsWith('sys.security.')) return 'security'\n if (key.startsWith('sys.upload.')) return 'upload'\n if (key.startsWith('sys.job.')) return 'job'\n return 'advanced'\n}\n\n/** 配置行增删改的版本号:保存或在「高级」页改了行之后 bump,「高级」表据此重拉。 */\nexport const configRevision = ref(0)\n\nexport function bumpConfigRevision() {\n configRevision.value++\n}\n"],"names":["CONFIG_TABS","TAB_GROUPS","TAB_ICONS","LOGO_KEY","BRAND_KEYS","LOGIN_LOCALES","heroKeys","locale","SUBTITLE_KEY","SHOW_FEATURES_KEY","LOGIN_KEYS","l","SECURITY_NUMBERS","SMS_LOGIN_KEY","SECURITY_SWITCHES","CAPTCHA_TYPE_KEY","SECURITY_KEYS","UPLOAD_MAX_KEY","UPLOAD_EXTS_KEY","JOB_RETENTION_KEY","JOB_ALERT_KEY","STATIC_CLAIMED_KEYS","WATERMARK_KEYS","STRUCTURED_GROUPS","tabOfKey","key","configRevision","ref","bumpConfigRevision"],"mappings":";;AAMO,MAAMA,IAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAIaC,IAAgD;AAAA,EAC3D,CAAC,SAAS,UAAU,YAAY,aAAa,WAAW;AAAA,EACxD,CAAC,UAAU,OAAO,UAAU;AAC9B,GAGaC,IAAuC;AAAA,EAClD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,WAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,UAAU;AACZ,GAEaC,IAAW,iBACXC,IAAa;AAAA,EACxB;AAAA,EACAD;AAAA,EACA;AAAA,EACA;AACF,GAKaE,IAAgB,CAAC,SAAS,OAAO,GAEjCC,IAAW,CAACC,OAAyB;AAAA,EAChD,UAAU,2BAA2BA,CAAM;AAAA,EAC3C,WAAW,4BAA4BA,CAAM;AAAA,EAC7C,UAAU,2BAA2BA,CAAM;AAC7C,IACaC,IAAe,qBACfC,IAAoB,+BACpBC,IAAa;AAAA,EACxBF;AAAA,EACAC;AAAA,EACA,GAAGJ,EAAc,QAAQ,CAAAM,MAAK,OAAO,OAAOL,EAASK,CAAC,CAAC,CAAC;AAC1D,GAIaC,IAAqD;AAAA,EAChE,uCAAuC;AAAA,EACvC,sCAAsC;AAAA,EACtC,mCAAmC;AAAA,EACnC,oCAAoC;AAAA,EACpC,sCAAsC;AAAA,EACtC,sCAAsC;AAAA,EACtC,uCAAuC;AAAA,EACvC,wCAAwC;AAAA,EACxC,0CAA0C;AAAA,EAC1C,8CAA8C;AAChD,GAEaC,IAAgB,iCAChBC,IAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GACaC,IAAmB,6BACnBC,IAAgB;AAAA,EAC3B,GAAG,OAAO,KAAKJ,CAAgB;AAAA,EAC/B,GAAGE;AAAA,EACHC;AAAA,EACAF;AACF,GAEaI,IAAiB,wBACjBC,IAAkB,gCAClBC,IAAoB,4BACpBC,IAAgB,uBAGhBC,IAAyC;AAAA,EACpD,GAAGjB;AAAA,EACH,GAAGM;AAAA,EACH,GAAGY;AAAA,EACH,GAAGN;AAAA,EACHC;AAAA,EACAC;AAAA,EACAC;AAAA,EACAC;AACF,GAGaG,IAAoB,CAAC,OAAO,SAAS,YAAY,UAAU,KAAK;AAGtE,SAASC,EAASC,GAAwB;AAC/C,SAAIA,EAAI,WAAW,WAAW,KAAKA,EAAI,WAAW,YAAY,IAAU,UACpEA,EAAI,WAAW,gBAAgB,IAAU,cACzCA,MAAQZ,KAAiBY,EAAI,WAAW,mBAAmB,IAAU,WACrEA,EAAI,WAAW,eAAe,IAAU,aACxCA,EAAI,WAAW,aAAa,IAAU,WACtCA,EAAI,WAAW,UAAU,IAAU,QAChC;AACT;AAGO,MAAMC,IAAiBC,EAAI,CAAC;AAE5B,SAASC,IAAqB;AACnC,EAAAF,EAAe;AACjB;"}
@@ -1,8 +1,9 @@
1
1
  import o from "./index2.vue.js";
2
2
  /* empty css */
3
+ /* empty css */
3
4
  import t from "../../../_virtual/_plugin-vue_export-helper.js";
4
- const f = /* @__PURE__ */ t(o, [["__scopeId", "data-v-8ea68f7d"]]);
5
+ const i = /* @__PURE__ */ t(o, [["__scopeId", "data-v-c57600e7"]]);
5
6
  export {
6
- f as default
7
+ i as default
7
8
  };
8
9
  //# 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":";;;;;"}