vome-core 0.3.64 → 0.3.66

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 (345) hide show
  1. package/dist/admin/api/client.js +7 -2
  2. package/dist/admin/components/ui/avatar/Avatar.vue +18 -18
  3. package/dist/admin/components/ui/avatar/AvatarFallback.vue +21 -21
  4. package/dist/admin/components/ui/avatar/AvatarImage.vue +16 -16
  5. package/dist/admin/components/ui/avatar/index.js +1 -1
  6. package/dist/admin/components/ui/badge/Badge.vue +26 -26
  7. package/dist/admin/components/ui/button/Button.vue +31 -31
  8. package/dist/admin/components/ui/checkbox/Checkbox.vue +35 -35
  9. package/dist/admin/components/ui/checkbox/index.js +1 -1
  10. package/dist/admin/components/ui/dialog/Dialog.vue +19 -19
  11. package/dist/admin/components/ui/dialog/DialogClose.vue +15 -15
  12. package/dist/admin/components/ui/dialog/DialogContent.vue +267 -267
  13. package/dist/admin/components/ui/dialog/DialogDescription.vue +23 -23
  14. package/dist/admin/components/ui/dialog/DialogFooter.vue +27 -27
  15. package/dist/admin/components/ui/dialog/DialogHeader.vue +17 -17
  16. package/dist/admin/components/ui/dialog/DialogOverlay.vue +21 -21
  17. package/dist/admin/components/ui/dialog/DialogScrollContent.vue +60 -60
  18. package/dist/admin/components/ui/dialog/DialogTitle.vue +23 -23
  19. package/dist/admin/components/ui/dialog/DialogTrigger.vue +15 -15
  20. package/dist/admin/components/ui/dialog/index.js +1 -1
  21. package/dist/admin/components/ui/dropdown-menu/DropdownMenu.vue +19 -19
  22. package/dist/admin/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +39 -39
  23. package/dist/admin/components/ui/dropdown-menu/DropdownMenuContent.vue +39 -39
  24. package/dist/admin/components/ui/dropdown-menu/DropdownMenuGroup.vue +15 -15
  25. package/dist/admin/components/ui/dropdown-menu/DropdownMenuItem.vue +31 -31
  26. package/dist/admin/components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -23
  27. package/dist/admin/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -21
  28. package/dist/admin/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +40 -40
  29. package/dist/admin/components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -23
  30. package/dist/admin/components/ui/dropdown-menu/DropdownMenuShortcut.vue +17 -17
  31. package/dist/admin/components/ui/dropdown-menu/DropdownMenuSub.vue +18 -18
  32. package/dist/admin/components/ui/dropdown-menu/DropdownMenuSubContent.vue +27 -27
  33. package/dist/admin/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +31 -31
  34. package/dist/admin/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -17
  35. package/dist/admin/components/ui/dropdown-menu/index.js +1 -1
  36. package/dist/admin/components/ui/input/Input.vue +183 -183
  37. package/dist/admin/components/ui/input/index.js +1 -1
  38. package/dist/admin/components/ui/label/Label.vue +26 -26
  39. package/dist/admin/components/ui/label/index.js +1 -1
  40. package/dist/admin/components/ui/scroll-area/ScrollArea.vue +33 -33
  41. package/dist/admin/components/ui/scroll-area/ScrollBar.vue +32 -32
  42. package/dist/admin/components/ui/scroll-area/index.js +1 -1
  43. package/dist/admin/components/ui/select/Select.vue +19 -19
  44. package/dist/admin/components/ui/select/SelectContent.vue +51 -51
  45. package/dist/admin/components/ui/select/SelectGroup.vue +15 -15
  46. package/dist/admin/components/ui/select/SelectItem.vue +53 -53
  47. package/dist/admin/components/ui/select/SelectItemText.vue +15 -15
  48. package/dist/admin/components/ui/select/SelectLabel.vue +17 -17
  49. package/dist/admin/components/ui/select/SelectScrollDownButton.vue +26 -26
  50. package/dist/admin/components/ui/select/SelectScrollUpButton.vue +26 -26
  51. package/dist/admin/components/ui/select/SelectSeparator.vue +19 -19
  52. package/dist/admin/components/ui/select/SelectTrigger.vue +44 -44
  53. package/dist/admin/components/ui/select/SelectValue.vue +15 -15
  54. package/dist/admin/components/ui/select/index.js +1 -1
  55. package/dist/admin/components/ui/separator/Separator.vue +29 -29
  56. package/dist/admin/components/ui/separator/index.js +1 -1
  57. package/dist/admin/components/ui/sheet/Sheet.vue +19 -19
  58. package/dist/admin/components/ui/sheet/SheetClose.vue +15 -15
  59. package/dist/admin/components/ui/sheet/SheetContent.vue +63 -63
  60. package/dist/admin/components/ui/sheet/SheetDescription.vue +21 -21
  61. package/dist/admin/components/ui/sheet/SheetFooter.vue +16 -16
  62. package/dist/admin/components/ui/sheet/SheetHeader.vue +15 -15
  63. package/dist/admin/components/ui/sheet/SheetOverlay.vue +21 -21
  64. package/dist/admin/components/ui/sheet/SheetTitle.vue +21 -21
  65. package/dist/admin/components/ui/sheet/SheetTrigger.vue +15 -15
  66. package/dist/admin/components/ui/sheet/index.js +1 -1
  67. package/dist/admin/components/ui/sonner/Toaster.vue +117 -117
  68. package/dist/admin/components/ui/sonner/index.js +1 -1
  69. package/dist/admin/components/ui/table/Table.vue +16 -16
  70. package/dist/admin/components/ui/table/TableBody.vue +17 -17
  71. package/dist/admin/components/ui/table/TableCaption.vue +17 -17
  72. package/dist/admin/components/ui/table/TableCell.vue +22 -22
  73. package/dist/admin/components/ui/table/TableEmpty.vue +34 -34
  74. package/dist/admin/components/ui/table/TableFooter.vue +17 -17
  75. package/dist/admin/components/ui/table/TableHead.vue +17 -17
  76. package/dist/admin/components/ui/table/TableHeader.vue +17 -17
  77. package/dist/admin/components/ui/table/TableRow.vue +17 -17
  78. package/dist/admin/components/ui/table/index.js +1 -1
  79. package/dist/admin/components/ui/tabs/Tabs.vue +24 -24
  80. package/dist/admin/components/ui/tabs/TabsContent.vue +21 -21
  81. package/dist/admin/components/ui/tabs/TabsList.vue +24 -24
  82. package/dist/admin/components/ui/tabs/TabsTrigger.vue +26 -26
  83. package/dist/admin/components/ui/tabs/index.js +1 -1
  84. package/dist/admin/components/ui/tooltip/Tooltip.vue +19 -19
  85. package/dist/admin/components/ui/tooltip/TooltipContent.vue +34 -34
  86. package/dist/admin/components/ui/tooltip/TooltipProvider.vue +14 -14
  87. package/dist/admin/components/ui/tooltip/TooltipTrigger.vue +15 -15
  88. package/dist/admin/components/ui/tooltip/index.js +1 -1
  89. package/dist/admin/components/vm-action-btn.vue +136 -136
  90. package/dist/admin/components/vm-aside-list-item.vue +136 -136
  91. package/dist/admin/components/vm-aside.vue +229 -229
  92. package/dist/admin/components/vm-auto-perm-dialog.vue +371 -371
  93. package/dist/admin/components/vm-card-grid.vue +37 -37
  94. package/dist/admin/components/vm-card-head.vue +45 -45
  95. package/dist/admin/components/vm-card-meta.vue +22 -22
  96. package/dist/admin/components/vm-card-title.vue +56 -56
  97. package/dist/admin/components/vm-card.vue +176 -176
  98. package/dist/admin/components/vm-check-tree.vue +340 -340
  99. package/dist/admin/components/vm-clamp-text.vue +39 -39
  100. package/dist/admin/components/vm-dept-tree.vue +497 -497
  101. package/dist/admin/components/vm-empty.vue +68 -68
  102. package/dist/admin/components/vm-eps-perm-picker.vue +123 -123
  103. package/dist/admin/components/vm-form-dialog.vue +632 -632
  104. package/dist/admin/components/vm-group-cascader.vue +560 -560
  105. package/dist/admin/components/vm-icon-btn.vue +88 -88
  106. package/dist/admin/components/vm-icon-picker.vue +647 -647
  107. package/dist/admin/components/vm-inline-search.vue +61 -61
  108. package/dist/admin/components/vm-loading.vue +114 -114
  109. package/dist/admin/components/vm-markdown.vue +405 -405
  110. package/dist/admin/components/vm-marquee.vue +265 -265
  111. package/dist/admin/components/vm-page-tabs.vue +94 -94
  112. package/dist/admin/components/vm-perm-section.vue +57 -57
  113. package/dist/admin/components/vm-ri-icon.vue +23 -23
  114. package/dist/admin/components/vm-role-picker.vue +314 -314
  115. package/dist/admin/components/vm-split-layout.vue +106 -106
  116. package/dist/admin/components/vm-thumb.vue +49 -49
  117. package/dist/admin/components/vm-view-path-picker.vue +59 -59
  118. package/dist/admin/crud/auto-fields.js +1 -1
  119. package/dist/admin/crud/components/vm-avatar.vue +104 -104
  120. package/dist/admin/crud/components/vm-color-picker.vue +1626 -1626
  121. package/dist/admin/crud/components/vm-column-custom.vue +193 -193
  122. package/dist/admin/crud/components/vm-context-menu.vue +105 -105
  123. package/dist/admin/crud/components/vm-copy-btn.vue +102 -102
  124. package/dist/admin/crud/components/vm-date-calendar-panel.vue +537 -537
  125. package/dist/admin/crud/components/vm-date-picker.vue +75 -75
  126. package/dist/admin/crud/components/vm-date-range.vue +88 -88
  127. package/dist/admin/crud/components/vm-date-text.vue +42 -42
  128. package/dist/admin/crud/components/vm-datetime-field.vue +215 -215
  129. package/dist/admin/crud/components/vm-datetime-picker.vue +9 -9
  130. package/dist/admin/crud/components/vm-dict-tag.vue +112 -112
  131. package/dist/admin/crud/components/vm-ellipsis-text.vue +34 -34
  132. package/dist/admin/crud/components/vm-form-hint.vue +81 -81
  133. package/dist/admin/crud/components/vm-json-code.vue +41 -41
  134. package/dist/admin/crud/components/vm-json-editor.vue +161 -161
  135. package/dist/admin/crud/components/vm-json-kv-editor.vue +318 -318
  136. package/dist/admin/crud/components/vm-kv-row.vue +51 -51
  137. package/dist/admin/crud/components/vm-multi-select.vue +279 -279
  138. package/dist/admin/crud/components/vm-number-range.vue +204 -204
  139. package/dist/admin/crud/components/vm-preview-viewer.vue +894 -894
  140. package/dist/admin/crud/components/vm-radio.vue +87 -87
  141. package/dist/admin/crud/components/vm-richtext.vue +313 -313
  142. package/dist/admin/crud/components/vm-select.vue +570 -570
  143. package/dist/admin/crud/components/vm-status-tag.vue +158 -158
  144. package/dist/admin/crud/components/vm-switch.vue +158 -158
  145. package/dist/admin/crud/components/vm-tag-list.vue +108 -108
  146. package/dist/admin/crud/components/vm-text-link.vue +52 -52
  147. package/dist/admin/crud/components/vm-toggle-switch.vue +84 -84
  148. package/dist/admin/crud/components/vm-tree-select.vue +450 -450
  149. package/dist/admin/crud/components/vm-upload-item.vue +298 -298
  150. package/dist/admin/crud/components/vm-upload.vue +436 -436
  151. package/dist/admin/crud/config.js +1 -1
  152. package/dist/admin/crud/confirm.js +1 -1
  153. package/dist/admin/crud/crud-page-request.js +1 -1
  154. package/dist/admin/crud/data-i18n.js +1 -1
  155. package/dist/admin/crud/dict.js +1 -1
  156. package/dist/admin/crud/export-fetch.js +1 -1
  157. package/dist/admin/crud/index.js +1 -0
  158. package/dist/admin/crud/key.js +1 -1
  159. package/dist/admin/crud/plugins.js +1 -1
  160. package/dist/admin/crud/span.js +1 -1
  161. package/dist/admin/crud/style.js +1 -1
  162. package/dist/admin/crud/useCrud.js +3 -0
  163. package/dist/admin/crud/validate.js +1 -1
  164. package/dist/admin/crud/vm-add-btn.vue +70 -70
  165. package/dist/admin/crud/vm-adv-search.vue +83 -83
  166. package/dist/admin/crud/vm-crud.vue +711 -711
  167. package/dist/admin/crud/vm-data-i18n-btn.vue +456 -456
  168. package/dist/admin/crud/vm-data-i18n-lang.vue +183 -183
  169. package/dist/admin/crud/vm-export-btn.vue +183 -183
  170. package/dist/admin/crud/vm-flex.vue +14 -14
  171. package/dist/admin/crud/vm-form.vue +33 -15
  172. package/dist/admin/crud/vm-import-btn.vue +747 -747
  173. package/dist/admin/crud/vm-multi-delete-btn.vue +49 -49
  174. package/dist/admin/crud/vm-pagination.vue +212 -212
  175. package/dist/admin/crud/vm-refresh-btn.vue +35 -35
  176. package/dist/admin/crud/vm-row.vue +55 -55
  177. package/dist/admin/crud/vm-search-key.vue +78 -78
  178. package/dist/admin/crud/vm-search.vue +466 -466
  179. package/dist/admin/crud/vm-table.vue +1390 -1390
  180. package/dist/admin/crud/vm-tabs.vue +94 -94
  181. package/dist/admin/crud/vm-toolbar.vue +357 -357
  182. package/dist/admin/crud/vm-upsert.vue +765 -765
  183. package/dist/admin/directives/perm.js +1 -1
  184. package/dist/admin/env.d.ts +1 -1
  185. package/dist/admin/hooks/useUpload.js +1 -1
  186. package/dist/admin/index.d.ts +1 -31
  187. package/dist/admin/lib/browser.js +1 -1
  188. package/dist/admin/lib/cn.js +1 -1
  189. package/dist/admin/lib/dialog-float.js +1 -1
  190. package/dist/admin/lib/export-excel.js +1 -1
  191. package/dist/admin/lib/import-excel.js +1 -1
  192. package/dist/admin/lib/json.js +1 -1
  193. package/dist/admin/lib/menu.js +1 -1
  194. package/dist/admin/lib/micro-locale.js +1 -1
  195. package/dist/admin/lib/micro-theme.js +1 -1
  196. package/dist/admin/lib/shell.js +1 -1
  197. package/dist/admin/lib/theme-color-options.js +1 -1
  198. package/dist/admin/lib/tree.js +1 -1
  199. package/dist/admin/lib/upload.js +1 -1
  200. package/dist/admin/lib/video-frame.js +1 -1
  201. package/dist/admin/router/create.js +1 -1
  202. package/dist/admin/router/guards.js +1 -1
  203. package/dist/admin/router/index.d.ts +1 -5
  204. package/dist/admin/service/index.d.ts +1 -11
  205. package/dist/admin/styles/base.css +121 -121
  206. package/dist/admin/vendor/browser-image-compression.js +1144 -1144
  207. package/dist/admin/vendor/decimal-js.js +12 -12
  208. package/dist/admin/vendor/xlsx.js +263 -263
  209. package/dist/ai/index.js +1 -1
  210. package/dist/client/admin-vendor.d.ts +1 -13
  211. package/dist/client/ai-model-registry.js +1 -1
  212. package/dist/client/base.js +1 -1
  213. package/dist/client/configure.js +1 -1
  214. package/dist/client/dict.js +1 -1
  215. package/dist/client/eps-payload.js +1 -1
  216. package/dist/client/eps.js +1 -1
  217. package/dist/client/index.d.ts +1 -7
  218. package/dist/client/index.js +1 -1
  219. package/dist/client/locale-change.js +1 -1
  220. package/dist/client/locale-store.js +1 -1
  221. package/dist/client/service.js +1 -1
  222. package/dist/client/vite-admin.d.ts +1 -40
  223. package/dist/client/vite-admin.js +1 -1
  224. package/dist/client/vite-auto-import.d.ts +1 -2
  225. package/dist/client/vite-auto-import.js +1 -1
  226. package/dist/client/vite-micro-proxy.d.ts +1 -20
  227. package/dist/client/vite-micro-proxy.js +1 -1
  228. package/dist/client/vite-plugin-eps.d.ts +1 -20
  229. package/dist/client/vite-plugin-eps.js +1 -1
  230. package/dist/client/vite-resolve.d.ts +1 -16
  231. package/dist/client/vite-resolve.js +1 -1
  232. package/dist/config/index.js +1 -1
  233. package/dist/core/index.d.ts +1 -1
  234. package/dist/index.js +1 -1
  235. package/dist/ioc/index.d.ts +1 -1
  236. package/dist/server/index.d.ts +1 -1
  237. package/dist/server/index.js +1 -1
  238. package/dist/shared/datetime-picker.js +1 -1
  239. package/dist/shared/decimal.js +1 -1
  240. package/dist/shared/excel.js +1 -1
  241. package/dist/shared/index.js +1 -1
  242. package/dist/shared/locale-json.js +1 -1
  243. package/dist/shared/tree.js +1 -1
  244. package/package.json +1 -1
  245. package/typings/admin/base/auth.ts +24 -24
  246. package/typings/admin/base/permission.ts +19 -19
  247. package/typings/admin/comm/cascader.ts +7 -7
  248. package/typings/admin/comm/check-tree.ts +7 -7
  249. package/typings/admin/comm/crud.ts +427 -427
  250. package/typings/admin/comm/eps.ts +86 -86
  251. package/typings/admin/comm/request.ts +16 -16
  252. package/typings/admin/comm/service.ts +43 -43
  253. package/typings/admin/comm/upload.ts +39 -39
  254. package/typings/admin/theme.ts +10 -10
  255. package/typings/admin/vome/browser.ts +11 -11
  256. package/typings/admin/vome/module.ts +13 -13
  257. package/typings/admin/vome/tags.ts +9 -9
  258. package/typings/comm/crud.ts +83 -83
  259. package/typings/comm/page.ts +18 -18
  260. package/typings/comm/scan.ts +6 -6
  261. package/typings/common.ts +4 -4
  262. package/typings/context/data.ts +10 -10
  263. package/typings/ext/market-seat.ts +42 -42
  264. package/typings/ext/market.ts +55 -55
  265. package/typings/ext/module.ts +64 -64
  266. package/typings/ext/plugin.ts +38 -38
  267. package/typings/ioc/metadata.ts +34 -34
  268. package/typings/logger/config.ts +6 -6
  269. package/typings/routing/crud.ts +199 -199
  270. package/typings/routing/eps.ts +88 -88
  271. package/typings/routing/meta.ts +63 -63
  272. package/typings/routing/register.ts +21 -21
  273. package/typings/routing/scan-context.ts +7 -7
  274. package/dist/admin/api/client.d.ts +0 -50
  275. package/dist/admin/components/ui/avatar/index.d.ts +0 -3
  276. package/dist/admin/components/ui/badge/index.d.ts +0 -6
  277. package/dist/admin/components/ui/button/index.d.ts +0 -7
  278. package/dist/admin/components/ui/checkbox/index.d.ts +0 -1
  279. package/dist/admin/components/ui/dialog/index.d.ts +0 -10
  280. package/dist/admin/components/ui/dropdown-menu/index.d.ts +0 -15
  281. package/dist/admin/components/ui/input/index.d.ts +0 -1
  282. package/dist/admin/components/ui/label/index.d.ts +0 -1
  283. package/dist/admin/components/ui/scroll-area/index.d.ts +0 -2
  284. package/dist/admin/components/ui/select/index.d.ts +0 -11
  285. package/dist/admin/components/ui/separator/index.d.ts +0 -1
  286. package/dist/admin/components/ui/sheet/index.d.ts +0 -8
  287. package/dist/admin/components/ui/sonner/index.d.ts +0 -1
  288. package/dist/admin/components/ui/table/index.d.ts +0 -9
  289. package/dist/admin/components/ui/tabs/index.d.ts +0 -4
  290. package/dist/admin/components/ui/tooltip/index.d.ts +0 -4
  291. package/dist/admin/crud/auto-fields.d.ts +0 -68
  292. package/dist/admin/crud/config.d.ts +0 -5
  293. package/dist/admin/crud/confirm.d.ts +0 -19
  294. package/dist/admin/crud/crud-page-request.d.ts +0 -21
  295. package/dist/admin/crud/data-i18n.d.ts +0 -62
  296. package/dist/admin/crud/dict.d.ts +0 -4
  297. package/dist/admin/crud/export-fetch.d.ts +0 -22
  298. package/dist/admin/crud/index.d.ts +0 -60
  299. package/dist/admin/crud/json-kv.d.ts +0 -9
  300. package/dist/admin/crud/key.d.ts +0 -22
  301. package/dist/admin/crud/paging.d.ts +0 -2
  302. package/dist/admin/crud/plugins.d.ts +0 -63
  303. package/dist/admin/crud/registry.d.ts +0 -3
  304. package/dist/admin/crud/span.d.ts +0 -17
  305. package/dist/admin/crud/style.d.ts +0 -82
  306. package/dist/admin/crud/useCrud.d.ts +0 -21
  307. package/dist/admin/crud/validate.d.ts +0 -7
  308. package/dist/admin/directives/perm.d.ts +0 -3
  309. package/dist/admin/hooks/useBrowser.d.ts +0 -6
  310. package/dist/admin/hooks/useUpload.d.ts +0 -8
  311. package/dist/admin/hooks/useVome.d.ts +0 -10
  312. package/dist/admin/lib/browser.d.ts +0 -3
  313. package/dist/admin/lib/cn.d.ts +0 -2
  314. package/dist/admin/lib/compress-image.d.ts +0 -12
  315. package/dist/admin/lib/dialog-float.d.ts +0 -8
  316. package/dist/admin/lib/eps.d.ts +0 -2
  317. package/dist/admin/lib/export-excel.d.ts +0 -9
  318. package/dist/admin/lib/file-preview.d.ts +0 -9
  319. package/dist/admin/lib/import-excel.d.ts +0 -21
  320. package/dist/admin/lib/json.d.ts +0 -11
  321. package/dist/admin/lib/menu.d.ts +0 -3
  322. package/dist/admin/lib/micro-locale.d.ts +0 -5
  323. package/dist/admin/lib/micro-theme.d.ts +0 -14
  324. package/dist/admin/lib/module.d.ts +0 -21
  325. package/dist/admin/lib/scarce-assets.d.ts +0 -5
  326. package/dist/admin/lib/shell.d.ts +0 -8
  327. package/dist/admin/lib/theme-color-options.d.ts +0 -15
  328. package/dist/admin/lib/tree.d.ts +0 -2
  329. package/dist/admin/lib/upload.d.ts +0 -17
  330. package/dist/admin/lib/video-frame.d.ts +0 -6
  331. package/dist/admin/router/create.d.ts +0 -16
  332. package/dist/admin/router/guards.d.ts +0 -6
  333. package/dist/admin/router/menu-routes.d.ts +0 -13
  334. package/dist/admin/stores/app.d.ts +0 -13
  335. package/dist/admin/stores/tags.d.ts +0 -14
  336. package/dist/admin/stores/user.d.ts +0 -48
  337. package/dist/client/ai-model-registry.d.ts +0 -16
  338. package/dist/client/base.d.ts +0 -28
  339. package/dist/client/configure.d.ts +0 -33
  340. package/dist/client/dict.d.ts +0 -31
  341. package/dist/client/eps-payload.d.ts +0 -3
  342. package/dist/client/eps.d.ts +0 -17
  343. package/dist/client/locale-change.d.ts +0 -16
  344. package/dist/client/locale-store.d.ts +0 -105
  345. package/dist/client/service.d.ts +0 -29
@@ -1,357 +1,357 @@
1
- <template>
2
- <div class="vm-crud-toolbar">
3
- <div class="vm-crud-toolbar__left">
4
- <template v-if="isDataI18nView">
5
- <vm-data-i18n-btn v-if="showDataI18n" :text="dataI18nText" />
6
- <vm-data-i18n-lang />
7
- <button
8
- type="button"
9
- class="vm-crud-toolbar__btn is-danger"
10
- :disabled="!crud.selection.value.length || dataI18nDeleting"
11
- @click="onDataI18nMultiDelete"
12
- >
13
- <i class="ri-delete-bin-line" />
14
- {{ deleteText ?? crudLabel('multiDelete', crud.dict.label) }}
15
- </button>
16
- </template>
17
- <template v-else>
18
- <button
19
- v-if="showAddBtn"
20
- type="button"
21
- class="vm-crud-toolbar__btn is-primary"
22
- @click="onAdd"
23
- >
24
- <i class="ri-add-line" />
25
- {{ addText ?? crudLabel('add', crud.dict.label) }}
26
- </button>
27
- <button
28
- v-if="showDeleteBtn"
29
- type="button"
30
- class="vm-crud-toolbar__btn is-danger"
31
- :disabled="!crud.selection.value.length"
32
- @click="crud.rowDelete()"
33
- >
34
- <i class="ri-delete-bin-line" />
35
- {{ deleteText ?? crudLabel('multiDelete', crud.dict.label) }}
36
- </button>
37
- <vm-export-btn
38
- v-if="showExport"
39
- :text="exportText || crudLabel('export', crud.dict.label)"
40
- :filename="exportFilename"
41
- :max-export-limit="maxExportLimit"
42
- :columns="exportColumns"
43
- :data="exportData"
44
- />
45
- <vm-import-btn
46
- v-if="showImport"
47
- :text="importText || crudLabel('import', crud.dict.label)"
48
- :tip="importTip"
49
- :template-filename="importTemplateFilename"
50
- :max-size-mb="importMaxSizeMb"
51
- />
52
- <slot />
53
- </template>
54
- </div>
55
- <div class="vm-crud-toolbar__right">
56
- <slot name="right" />
57
- <div v-if="showSearchActions" class="vm-crud-toolbar__search">
58
- <button type="button" class="vm-crud-toolbar__btn is-primary" @click="onSearch">
59
- {{ crudLabel('search', crud.dict.label) }}
60
- </button>
61
- <button type="button" class="vm-crud-toolbar__btn is-ghost" @click="onReset">
62
- {{ crudLabel('reset', crud.dict.label) }}
63
- </button>
64
- </div>
65
- <vm-tabs
66
- v-if="showViewTabs"
67
- :model-value="crud.trashMode.value"
68
- :items="viewTabs"
69
- @update:model-value="onViewTab"
70
- />
71
- </div>
72
- </div>
73
- </template>
74
-
75
- <script setup lang="ts">
76
- import { computed, ref } from 'vue'
77
- import { toast } from 'vue-sonner'
78
- import { useVome } from '../hooks/useVome'
79
- import { useCrud } from './useCrud'
80
- import VmExportBtn from './vm-export-btn.vue'
81
- import VmImportBtn from './vm-import-btn.vue'
82
- import VmDataI18nBtn from './vm-data-i18n-btn.vue'
83
- import VmDataI18nLang from './vm-data-i18n-lang.vue'
84
- import VmTabs from './vm-tabs.vue'
85
- import { canUseDataI18n, dataPackFromService } from './data-i18n'
86
- import { vmConfirm } from './confirm'
87
- import { crudFormat, crudLabel } from './style'
88
- import type {
89
- CrudColumn,
90
- CrudTrashMode,
91
- } from '../../../typings/admin/comm/crud'
92
- defineOptions({ name: 'vm-toolbar' })
93
-
94
- const props = withDefaults(
95
- defineProps<{
96
- /** 显示搜索/重置(默认开;放在列表/回收站左侧) */
97
- search?: boolean
98
- /** 显示导出(默认开;需 page/list 权限) */
99
- showExport?: boolean
100
- /** 显示导入(默认开;需 add 权限) */
101
- showImport?: boolean
102
- /** 显示业务数据翻译(默认开;EPS dataI18n 且在语言 Tab) */
103
- showDataI18n?: boolean
104
- dataI18nText?: string
105
- /**
106
- * 新增前置默认值(可选):对象直接带入表单;函数 await 后带入。
107
- * 未传 / 空对象 → 仍正常打开新增。仅函数显式返回 `null` 时中止(前置校验未通过)。
108
- */
109
- addData?:
110
- | Record<string, unknown>
111
- | (() => Record<string, unknown> | null | Promise<Record<string, unknown> | null>)
112
- /** 回收站中是否隐藏新增(默认 true) */
113
- hideAddInTrash?: boolean
114
- addText?: string
115
- deleteText?: string
116
- exportText?: string
117
- exportFilename?: string | (() => string)
118
- maxExportLimit?: number
119
- exportColumns?: CrudColumn[]
120
- exportData?:
121
- | Record<string, unknown>[]
122
- | ((params: Record<string, unknown>) => Promise<Record<string, unknown>[]>)
123
- importText?: string
124
- importTip?: string
125
- importTemplateFilename?: string | (() => string)
126
- importMaxSizeMb?: number
127
- }>(),
128
- {
129
- search: true,
130
- showExport: true,
131
- showImport: true,
132
- showDataI18n: true,
133
- hideAddInTrash: true,
134
- maxExportLimit: 5000,
135
- importMaxSizeMb: 10,
136
- },
137
- )
138
-
139
- const crud = useCrud()
140
- const { service } = useVome()
141
- const dataI18nDeleting = ref(false)
142
-
143
- const dataI18nEnabled = computed(() => canUseDataI18n(crud.service, service).ok)
144
-
145
- /** 有 restore 权限(Controller api + 权限码)才显示列表/回收站 */
146
- const showTrash = computed(() => Boolean(crud.getPermission('restore')))
147
-
148
- const showViewTabs = computed(() => showTrash.value || dataI18nEnabled.value)
149
-
150
- const viewTabs = computed(() => {
151
- const tabs: Array<{ label: string; value: CrudTrashMode }> = [
152
- { label: crudLabel('list', crud.dict.label), value: 'default' },
153
- ]
154
- if (showTrash.value) {
155
- tabs.push({
156
- label: crudLabel('trash', crud.dict.label),
157
- value: 'onlyTrashed',
158
- })
159
- }
160
- if (dataI18nEnabled.value) {
161
- tabs.push({ label: crudLabel('dataI18n', crud.dict.label), value: 'dataI18n' })
162
- }
163
- return tabs
164
- })
165
-
166
- const isDataI18nView = computed(() => crud.trashMode.value === 'dataI18n')
167
-
168
- /** 有 add 权限才显示;回收站内可再藏 */
169
- const showAddBtn = computed(() => {
170
- if (!crud.getPermission('add')) return false
171
- if (props.hideAddInTrash && crud.trashMode.value === 'onlyTrashed') return false
172
- return true
173
- })
174
-
175
- /** 有 delete 权限才显示 */
176
- const showDeleteBtn = computed(() => Boolean(crud.getPermission('delete')))
177
-
178
- const showSearchActions = computed(
179
- () =>
180
- props.search &&
181
- crud.hasSearchFilters.value &&
182
- crud.trashMode.value !== 'dataI18n',
183
- )
184
-
185
- async function onAdd() {
186
- const raw = props.addData
187
- if (typeof raw === 'function') {
188
- const defaults = await raw()
189
- // 仅函数显式返回 null 表示前置未满足;undefined / 空对象仍打开
190
- if (defaults === null) return
191
- crud.rowAdd(defaults ?? {})
192
- return
193
- }
194
- crud.rowAdd(raw ?? {})
195
- }
196
-
197
- async function onDataI18nMultiDelete() {
198
- if (dataI18nDeleting.value) return
199
- const rows = crud.selection.value
200
- if (!rows.length) return
201
- const meta = canUseDataI18n(crud.service, service)
202
- const dataPack = dataPackFromService(service)
203
- const lang = crud.dataI18nLangCode?.value
204
- if (!meta.ok || !dataPack?.deleteEntry || !lang) {
205
- toast.error(crudLabel('dataI18nNoService', crud.dict.label))
206
- return
207
- }
208
- const ids = [
209
- ...new Set(
210
- rows
211
- .map((r) => String(r.id ?? '').trim())
212
- .filter(Boolean),
213
- ),
214
- ]
215
- if (!ids.length) return
216
- const ok = await vmConfirm({
217
- title: crudLabel('tips', crud.dict.label),
218
- message: crudFormat(
219
- crudLabel('dataI18nMultiDeleteConfirm', crud.dict.label),
220
- ids.length,
221
- ),
222
- confirmText: crudLabel('confirm', crud.dict.label),
223
- cancelText: crudLabel('close', crud.dict.label),
224
- })
225
- if (!ok) return
226
- dataI18nDeleting.value = true
227
- try {
228
- for (const id of ids) {
229
- await dataPack.deleteEntry({
230
- tableName: meta.tableName,
231
- langCode: lang,
232
- id,
233
- })
234
- }
235
- toast.success(crudLabel('deleteSuccess', crud.dict.label))
236
- crud.setSelection([])
237
- await crud.refresh()
238
- } catch (e) {
239
- toast.error(e instanceof Error ? e.message : crudLabel('deleteFailed'))
240
- } finally {
241
- dataI18nDeleting.value = false
242
- }
243
- }
244
-
245
- function onSearch() {
246
- crud.searchActions.value?.search()
247
- }
248
-
249
- function onReset() {
250
- crud.searchActions.value?.reset()
251
- }
252
-
253
- function onViewTab(mode: string | number) {
254
- const next = String(mode) as CrudTrashMode
255
- if (next !== 'default' && next !== 'onlyTrashed' && next !== 'dataI18n') return
256
- if (next === 'onlyTrashed' && !showTrash.value) return
257
- if (next === 'dataI18n' && !dataI18nEnabled.value) return
258
- crud.trashMode.value = next
259
- crud.pagination.value = { ...crud.pagination.value, page: 1 }
260
- // 语言 Tab:先清空旧列表,避免 rowKey 已切到 __rowKey 而行数据仍是业务行 → key=undefined
261
- if (next === 'dataI18n') {
262
- crud.list.value = []
263
- crud.selection.value = []
264
- return
265
- }
266
- void crud.refresh()
267
- }
268
- </script>
269
-
270
- <style lang="scss" scoped>
271
- .vm-crud-toolbar {
272
- display: flex;
273
- flex: 1;
274
- min-width: 0;
275
- flex-wrap: wrap;
276
- align-items: center;
277
- gap: 10px;
278
- }
279
-
280
- .vm-crud-toolbar__left {
281
- display: flex;
282
- flex-wrap: wrap;
283
- align-items: center;
284
- gap: 8px;
285
- }
286
-
287
- .vm-crud-toolbar__right {
288
- display: flex;
289
- flex-wrap: wrap;
290
- align-items: center;
291
- margin-left: auto;
292
- gap: 10px;
293
- }
294
-
295
- .vm-crud-toolbar__search {
296
- display: flex;
297
- flex-wrap: wrap;
298
- align-items: center;
299
- gap: 8px;
300
- }
301
-
302
- .vm-crud-toolbar__btn {
303
- display: inline-flex;
304
- height: 36px;
305
- align-items: center;
306
- gap: 4px;
307
- padding: 0 14px;
308
- border: none;
309
- border-radius: 12px;
310
- font-size: 13px;
311
- font-weight: 600;
312
- cursor: pointer;
313
- transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease;
314
-
315
- &:disabled {
316
- cursor: not-allowed;
317
- opacity: 0.45;
318
- }
319
-
320
- &.is-primary {
321
- background: var(--brand);
322
- color: #fff;
323
-
324
- &:hover:not(:disabled) {
325
- background: var(--brand-deep);
326
- }
327
- }
328
-
329
- &.is-ghost {
330
- background: var(--muted);
331
- color: var(--foreground);
332
-
333
- &:hover:not(:disabled) {
334
- background: color-mix(in srgb, var(--muted) 70%, var(--foreground) 8%);
335
- }
336
- }
337
-
338
- &.is-danger {
339
- background: var(--danger-soft);
340
- color: var(--danger);
341
-
342
- &:hover:not(:disabled) {
343
- background: color-mix(in srgb, var(--danger-soft) 70%, var(--danger) 12%);
344
- }
345
- }
346
- }
347
-
348
- /* 中窄屏(含侧栏半宽):展平左右分区,统一流式换行;宽屏仍左右布局 */
349
- @media (max-width: 1280px) {
350
- .vm-crud-toolbar,
351
- .vm-crud-toolbar__left,
352
- .vm-crud-toolbar__right,
353
- .vm-crud-toolbar__search {
354
- display: contents;
355
- }
356
- }
357
- </style>
1
+ <template>
2
+ <div class="vm-crud-toolbar">
3
+ <div class="vm-crud-toolbar__left">
4
+ <template v-if="isDataI18nView">
5
+ <vm-data-i18n-btn v-if="showDataI18n" :text="dataI18nText" />
6
+ <vm-data-i18n-lang />
7
+ <button
8
+ type="button"
9
+ class="vm-crud-toolbar__btn is-danger"
10
+ :disabled="!crud.selection.value.length || dataI18nDeleting"
11
+ @click="onDataI18nMultiDelete"
12
+ >
13
+ <i class="ri-delete-bin-line" />
14
+ {{ deleteText ?? crudLabel('multiDelete', crud.dict.label) }}
15
+ </button>
16
+ </template>
17
+ <template v-else>
18
+ <button
19
+ v-if="showAddBtn"
20
+ type="button"
21
+ class="vm-crud-toolbar__btn is-primary"
22
+ @click="onAdd"
23
+ >
24
+ <i class="ri-add-line" />
25
+ {{ addText ?? crudLabel('add', crud.dict.label) }}
26
+ </button>
27
+ <button
28
+ v-if="showDeleteBtn"
29
+ type="button"
30
+ class="vm-crud-toolbar__btn is-danger"
31
+ :disabled="!crud.selection.value.length"
32
+ @click="crud.rowDelete()"
33
+ >
34
+ <i class="ri-delete-bin-line" />
35
+ {{ deleteText ?? crudLabel('multiDelete', crud.dict.label) }}
36
+ </button>
37
+ <vm-export-btn
38
+ v-if="showExport"
39
+ :text="exportText || crudLabel('export', crud.dict.label)"
40
+ :filename="exportFilename"
41
+ :max-export-limit="maxExportLimit"
42
+ :columns="exportColumns"
43
+ :data="exportData"
44
+ />
45
+ <vm-import-btn
46
+ v-if="showImport"
47
+ :text="importText || crudLabel('import', crud.dict.label)"
48
+ :tip="importTip"
49
+ :template-filename="importTemplateFilename"
50
+ :max-size-mb="importMaxSizeMb"
51
+ />
52
+ <slot />
53
+ </template>
54
+ </div>
55
+ <div class="vm-crud-toolbar__right">
56
+ <slot name="right" />
57
+ <div v-if="showSearchActions" class="vm-crud-toolbar__search">
58
+ <button type="button" class="vm-crud-toolbar__btn is-primary" @click="onSearch">
59
+ {{ crudLabel('search', crud.dict.label) }}
60
+ </button>
61
+ <button type="button" class="vm-crud-toolbar__btn is-ghost" @click="onReset">
62
+ {{ crudLabel('reset', crud.dict.label) }}
63
+ </button>
64
+ </div>
65
+ <vm-tabs
66
+ v-if="showViewTabs"
67
+ :model-value="crud.trashMode.value"
68
+ :items="viewTabs"
69
+ @update:model-value="onViewTab"
70
+ />
71
+ </div>
72
+ </div>
73
+ </template>
74
+
75
+ <script setup lang="ts">
76
+ import { computed, ref } from 'vue'
77
+ import { toast } from 'vue-sonner'
78
+ import { useVome } from '../hooks/useVome'
79
+ import { useCrud } from './useCrud'
80
+ import VmExportBtn from './vm-export-btn.vue'
81
+ import VmImportBtn from './vm-import-btn.vue'
82
+ import VmDataI18nBtn from './vm-data-i18n-btn.vue'
83
+ import VmDataI18nLang from './vm-data-i18n-lang.vue'
84
+ import VmTabs from './vm-tabs.vue'
85
+ import { canUseDataI18n, dataPackFromService } from './data-i18n'
86
+ import { vmConfirm } from './confirm'
87
+ import { crudFormat, crudLabel } from './style'
88
+ import type {
89
+ CrudColumn,
90
+ CrudTrashMode,
91
+ } from '../../../typings/admin/comm/crud'
92
+ defineOptions({ name: 'vm-toolbar' })
93
+
94
+ const props = withDefaults(
95
+ defineProps<{
96
+ /** 显示搜索/重置(默认开;放在列表/回收站左侧) */
97
+ search?: boolean
98
+ /** 显示导出(默认开;需 page/list 权限) */
99
+ showExport?: boolean
100
+ /** 显示导入(默认开;需 add 权限) */
101
+ showImport?: boolean
102
+ /** 显示业务数据翻译(默认开;EPS dataI18n 且在语言 Tab) */
103
+ showDataI18n?: boolean
104
+ dataI18nText?: string
105
+ /**
106
+ * 新增前置默认值(可选):对象直接带入表单;函数 await 后带入。
107
+ * 未传 / 空对象 → 仍正常打开新增。仅函数显式返回 `null` 时中止(前置校验未通过)。
108
+ */
109
+ addData?:
110
+ | Record<string, unknown>
111
+ | (() => Record<string, unknown> | null | Promise<Record<string, unknown> | null>)
112
+ /** 回收站中是否隐藏新增(默认 true) */
113
+ hideAddInTrash?: boolean
114
+ addText?: string
115
+ deleteText?: string
116
+ exportText?: string
117
+ exportFilename?: string | (() => string)
118
+ maxExportLimit?: number
119
+ exportColumns?: CrudColumn[]
120
+ exportData?:
121
+ | Record<string, unknown>[]
122
+ | ((params: Record<string, unknown>) => Promise<Record<string, unknown>[]>)
123
+ importText?: string
124
+ importTip?: string
125
+ importTemplateFilename?: string | (() => string)
126
+ importMaxSizeMb?: number
127
+ }>(),
128
+ {
129
+ search: true,
130
+ showExport: true,
131
+ showImport: true,
132
+ showDataI18n: true,
133
+ hideAddInTrash: true,
134
+ maxExportLimit: 5000,
135
+ importMaxSizeMb: 10,
136
+ },
137
+ )
138
+
139
+ const crud = useCrud()
140
+ const { service } = useVome()
141
+ const dataI18nDeleting = ref(false)
142
+
143
+ const dataI18nEnabled = computed(() => canUseDataI18n(crud.service, service).ok)
144
+
145
+ /** 有 restore 权限(Controller api + 权限码)才显示列表/回收站 */
146
+ const showTrash = computed(() => Boolean(crud.getPermission('restore')))
147
+
148
+ const showViewTabs = computed(() => showTrash.value || dataI18nEnabled.value)
149
+
150
+ const viewTabs = computed(() => {
151
+ const tabs: Array<{ label: string; value: CrudTrashMode }> = [
152
+ { label: crudLabel('list', crud.dict.label), value: 'default' },
153
+ ]
154
+ if (showTrash.value) {
155
+ tabs.push({
156
+ label: crudLabel('trash', crud.dict.label),
157
+ value: 'onlyTrashed',
158
+ })
159
+ }
160
+ if (dataI18nEnabled.value) {
161
+ tabs.push({ label: crudLabel('dataI18n', crud.dict.label), value: 'dataI18n' })
162
+ }
163
+ return tabs
164
+ })
165
+
166
+ const isDataI18nView = computed(() => crud.trashMode.value === 'dataI18n')
167
+
168
+ /** 有 add 权限才显示;回收站内可再藏 */
169
+ const showAddBtn = computed(() => {
170
+ if (!crud.getPermission('add')) return false
171
+ if (props.hideAddInTrash && crud.trashMode.value === 'onlyTrashed') return false
172
+ return true
173
+ })
174
+
175
+ /** 有 delete 权限才显示 */
176
+ const showDeleteBtn = computed(() => Boolean(crud.getPermission('delete')))
177
+
178
+ const showSearchActions = computed(
179
+ () =>
180
+ props.search &&
181
+ crud.hasSearchFilters.value &&
182
+ crud.trashMode.value !== 'dataI18n',
183
+ )
184
+
185
+ async function onAdd() {
186
+ const raw = props.addData
187
+ if (typeof raw === 'function') {
188
+ const defaults = await raw()
189
+ // 仅函数显式返回 null 表示前置未满足;undefined / 空对象仍打开
190
+ if (defaults === null) return
191
+ crud.rowAdd(defaults ?? {})
192
+ return
193
+ }
194
+ crud.rowAdd(raw ?? {})
195
+ }
196
+
197
+ async function onDataI18nMultiDelete() {
198
+ if (dataI18nDeleting.value) return
199
+ const rows = crud.selection.value
200
+ if (!rows.length) return
201
+ const meta = canUseDataI18n(crud.service, service)
202
+ const dataPack = dataPackFromService(service)
203
+ const lang = crud.dataI18nLangCode?.value
204
+ if (!meta.ok || !dataPack?.deleteEntry || !lang) {
205
+ toast.error(crudLabel('dataI18nNoService', crud.dict.label))
206
+ return
207
+ }
208
+ const ids = [
209
+ ...new Set(
210
+ rows
211
+ .map((r) => String(r.id ?? '').trim())
212
+ .filter(Boolean),
213
+ ),
214
+ ]
215
+ if (!ids.length) return
216
+ const ok = await vmConfirm({
217
+ title: crudLabel('tips', crud.dict.label),
218
+ message: crudFormat(
219
+ crudLabel('dataI18nMultiDeleteConfirm', crud.dict.label),
220
+ ids.length,
221
+ ),
222
+ confirmText: crudLabel('confirm', crud.dict.label),
223
+ cancelText: crudLabel('close', crud.dict.label),
224
+ })
225
+ if (!ok) return
226
+ dataI18nDeleting.value = true
227
+ try {
228
+ for (const id of ids) {
229
+ await dataPack.deleteEntry({
230
+ tableName: meta.tableName,
231
+ langCode: lang,
232
+ id,
233
+ })
234
+ }
235
+ toast.success(crudLabel('deleteSuccess', crud.dict.label))
236
+ crud.setSelection([])
237
+ await crud.refresh()
238
+ } catch (e) {
239
+ toast.error(e instanceof Error ? e.message : crudLabel('deleteFailed'))
240
+ } finally {
241
+ dataI18nDeleting.value = false
242
+ }
243
+ }
244
+
245
+ function onSearch() {
246
+ crud.searchActions.value?.search()
247
+ }
248
+
249
+ function onReset() {
250
+ crud.searchActions.value?.reset()
251
+ }
252
+
253
+ function onViewTab(mode: string | number) {
254
+ const next = String(mode) as CrudTrashMode
255
+ if (next !== 'default' && next !== 'onlyTrashed' && next !== 'dataI18n') return
256
+ if (next === 'onlyTrashed' && !showTrash.value) return
257
+ if (next === 'dataI18n' && !dataI18nEnabled.value) return
258
+ crud.trashMode.value = next
259
+ crud.pagination.value = { ...crud.pagination.value, page: 1 }
260
+ // 语言 Tab:先清空旧列表,避免 rowKey 已切到 __rowKey 而行数据仍是业务行 → key=undefined
261
+ if (next === 'dataI18n') {
262
+ crud.list.value = []
263
+ crud.selection.value = []
264
+ return
265
+ }
266
+ void crud.refresh()
267
+ }
268
+ </script>
269
+
270
+ <style lang="scss" scoped>
271
+ .vm-crud-toolbar {
272
+ display: flex;
273
+ flex: 1;
274
+ min-width: 0;
275
+ flex-wrap: wrap;
276
+ align-items: center;
277
+ gap: 10px;
278
+ }
279
+
280
+ .vm-crud-toolbar__left {
281
+ display: flex;
282
+ flex-wrap: wrap;
283
+ align-items: center;
284
+ gap: 8px;
285
+ }
286
+
287
+ .vm-crud-toolbar__right {
288
+ display: flex;
289
+ flex-wrap: wrap;
290
+ align-items: center;
291
+ margin-left: auto;
292
+ gap: 10px;
293
+ }
294
+
295
+ .vm-crud-toolbar__search {
296
+ display: flex;
297
+ flex-wrap: wrap;
298
+ align-items: center;
299
+ gap: 8px;
300
+ }
301
+
302
+ .vm-crud-toolbar__btn {
303
+ display: inline-flex;
304
+ height: 36px;
305
+ align-items: center;
306
+ gap: 4px;
307
+ padding: 0 14px;
308
+ border: none;
309
+ border-radius: 12px;
310
+ font-size: 13px;
311
+ font-weight: 600;
312
+ cursor: pointer;
313
+ transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease;
314
+
315
+ &:disabled {
316
+ cursor: not-allowed;
317
+ opacity: 0.45;
318
+ }
319
+
320
+ &.is-primary {
321
+ background: var(--brand);
322
+ color: #fff;
323
+
324
+ &:hover:not(:disabled) {
325
+ background: var(--brand-deep);
326
+ }
327
+ }
328
+
329
+ &.is-ghost {
330
+ background: var(--muted);
331
+ color: var(--foreground);
332
+
333
+ &:hover:not(:disabled) {
334
+ background: color-mix(in srgb, var(--muted) 70%, var(--foreground) 8%);
335
+ }
336
+ }
337
+
338
+ &.is-danger {
339
+ background: var(--danger-soft);
340
+ color: var(--danger);
341
+
342
+ &:hover:not(:disabled) {
343
+ background: color-mix(in srgb, var(--danger-soft) 70%, var(--danger) 12%);
344
+ }
345
+ }
346
+ }
347
+
348
+ /* 中窄屏(含侧栏半宽):展平左右分区,统一流式换行;宽屏仍左右布局 */
349
+ @media (max-width: 1280px) {
350
+ .vm-crud-toolbar,
351
+ .vm-crud-toolbar__left,
352
+ .vm-crud-toolbar__right,
353
+ .vm-crud-toolbar__search {
354
+ display: contents;
355
+ }
356
+ }
357
+ </style>