vome-core 0.3.69 → 0.3.71

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 (280) hide show
  1. package/dist/admin/components/ui/avatar/Avatar.vue +18 -18
  2. package/dist/admin/components/ui/avatar/AvatarFallback.vue +21 -21
  3. package/dist/admin/components/ui/avatar/AvatarImage.vue +16 -16
  4. package/dist/admin/components/ui/avatar/index.js +1 -1
  5. package/dist/admin/components/ui/badge/Badge.vue +26 -26
  6. package/dist/admin/components/ui/button/Button.vue +31 -31
  7. package/dist/admin/components/ui/button/index.d.ts +1 -1
  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.d.ts +7 -0
  119. package/dist/admin/crud/auto-fields.js +1 -1
  120. package/dist/admin/crud/components/vm-avatar.vue +104 -104
  121. package/dist/admin/crud/components/vm-color-picker.vue +1626 -1626
  122. package/dist/admin/crud/components/vm-column-custom.vue +193 -193
  123. package/dist/admin/crud/components/vm-context-menu.vue +105 -105
  124. package/dist/admin/crud/components/vm-copy-btn.vue +102 -102
  125. package/dist/admin/crud/components/vm-date-calendar-panel.vue +537 -537
  126. package/dist/admin/crud/components/vm-date-picker.vue +75 -75
  127. package/dist/admin/crud/components/vm-date-range.vue +88 -88
  128. package/dist/admin/crud/components/vm-date-text.vue +42 -42
  129. package/dist/admin/crud/components/vm-datetime-field.vue +215 -215
  130. package/dist/admin/crud/components/vm-datetime-picker.vue +9 -9
  131. package/dist/admin/crud/components/vm-dict-tag.vue +112 -112
  132. package/dist/admin/crud/components/vm-ellipsis-text.vue +34 -34
  133. package/dist/admin/crud/components/vm-form-hint.vue +81 -81
  134. package/dist/admin/crud/components/vm-json-code.vue +41 -41
  135. package/dist/admin/crud/components/vm-json-editor.vue +161 -161
  136. package/dist/admin/crud/components/vm-json-kv-editor.vue +318 -318
  137. package/dist/admin/crud/components/vm-kv-row.vue +51 -51
  138. package/dist/admin/crud/components/vm-multi-select.vue +279 -279
  139. package/dist/admin/crud/components/vm-number-range.vue +204 -204
  140. package/dist/admin/crud/components/vm-preview-viewer.vue +894 -894
  141. package/dist/admin/crud/components/vm-radio.vue +87 -87
  142. package/dist/admin/crud/components/vm-richtext.vue +313 -313
  143. package/dist/admin/crud/components/vm-select.vue +570 -570
  144. package/dist/admin/crud/components/vm-status-tag.vue +158 -158
  145. package/dist/admin/crud/components/vm-switch.vue +158 -158
  146. package/dist/admin/crud/components/vm-tag-list.vue +108 -108
  147. package/dist/admin/crud/components/vm-text-link.vue +52 -52
  148. package/dist/admin/crud/components/vm-toggle-switch.vue +84 -84
  149. package/dist/admin/crud/components/vm-tree-select.vue +450 -450
  150. package/dist/admin/crud/components/vm-upload-item.vue +298 -298
  151. package/dist/admin/crud/components/vm-upload.vue +436 -436
  152. package/dist/admin/crud/config.js +1 -1
  153. package/dist/admin/crud/confirm.js +1 -1
  154. package/dist/admin/crud/crud-page-request.js +1 -1
  155. package/dist/admin/crud/data-i18n.js +1 -1
  156. package/dist/admin/crud/dict.js +1 -1
  157. package/dist/admin/crud/export-fetch.js +1 -1
  158. package/dist/admin/crud/index.d.ts +1 -1
  159. package/dist/admin/crud/index.js +1 -0
  160. package/dist/admin/crud/key.js +1 -1
  161. package/dist/admin/crud/plugins.js +1 -1
  162. package/dist/admin/crud/span.js +1 -1
  163. package/dist/admin/crud/style.js +1 -1
  164. package/dist/admin/crud/validate.js +1 -1
  165. package/dist/admin/crud/vm-add-btn.vue +70 -70
  166. package/dist/admin/crud/vm-adv-search.vue +83 -83
  167. package/dist/admin/crud/vm-crud.vue +711 -711
  168. package/dist/admin/crud/vm-data-i18n-btn.vue +456 -456
  169. package/dist/admin/crud/vm-data-i18n-lang.vue +183 -183
  170. package/dist/admin/crud/vm-export-btn.vue +183 -183
  171. package/dist/admin/crud/vm-flex.vue +14 -14
  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/hooks/useVome.d.ts +2 -2
  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/stores/app.d.ts +13 -1
  204. package/dist/admin/stores/tags.d.ts +14 -1
  205. package/dist/admin/stores/user.d.ts +48 -1
  206. package/dist/admin/styles/base.css +121 -121
  207. package/dist/admin/vendor/browser-image-compression.js +1144 -1144
  208. package/dist/admin/vendor/decimal-js.js +12 -12
  209. package/dist/admin/vendor/xlsx.js +263 -263
  210. package/dist/ai/index.js +1 -1
  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.d.ts +7 -4
  217. package/dist/client/eps.js +1 -1
  218. package/dist/client/index.d.ts +1 -1
  219. package/dist/client/index.js +1 -1
  220. package/dist/client/locale-change.js +1 -1
  221. package/dist/client/locale-store.d.ts +45 -1
  222. package/dist/client/locale-store.js +1 -1
  223. package/dist/client/path.js +1 -1
  224. package/dist/client/service.d.ts +8 -0
  225. package/dist/client/service.js +1 -1
  226. package/dist/client/vite-admin.js +1 -1
  227. package/dist/client/vite-auto-import.js +1 -1
  228. package/dist/client/vite-micro-proxy.js +1 -1
  229. package/dist/client/vite-plugin-eps.d.ts +5 -0
  230. package/dist/client/vite-plugin-eps.js +1 -1
  231. package/dist/client/vite-resolve.js +1 -1
  232. package/dist/config/index.js +1 -1
  233. package/dist/core/index.d.ts +2 -2
  234. package/dist/index.js +1 -1
  235. package/dist/orm/index.d.ts +2 -0
  236. package/dist/orm/patch-bun-sql-jsonb.d.ts +1 -0
  237. package/dist/routing/context.d.ts +12 -2
  238. package/dist/routing/eps.d.ts +4 -1
  239. package/dist/routing/index.d.ts +2 -1
  240. package/dist/routing/metadata.d.ts +7 -3
  241. package/dist/server/index.d.ts +4 -2
  242. package/dist/server/index.js +1 -1
  243. package/dist/shared/datetime-picker.js +1 -1
  244. package/dist/shared/decimal.js +1 -1
  245. package/dist/shared/excel.js +1 -1
  246. package/dist/shared/index.js +1 -1
  247. package/dist/shared/locale-json.js +1 -1
  248. package/dist/shared/tree.js +1 -1
  249. package/dist/typings/routing/eps.d.ts +3 -1
  250. package/dist/typings/routing/meta.d.ts +15 -0
  251. package/package.json +1 -1
  252. package/typings/admin/base/auth.ts +24 -24
  253. package/typings/admin/base/permission.ts +19 -19
  254. package/typings/admin/comm/cascader.ts +7 -7
  255. package/typings/admin/comm/check-tree.ts +7 -7
  256. package/typings/admin/comm/crud.ts +427 -427
  257. package/typings/admin/comm/eps.ts +88 -86
  258. package/typings/admin/comm/request.ts +16 -16
  259. package/typings/admin/comm/service.ts +43 -43
  260. package/typings/admin/comm/upload.ts +39 -39
  261. package/typings/admin/theme.ts +10 -10
  262. package/typings/admin/vome/browser.ts +11 -11
  263. package/typings/admin/vome/module.ts +13 -13
  264. package/typings/admin/vome/tags.ts +9 -9
  265. package/typings/comm/crud.ts +83 -83
  266. package/typings/comm/page.ts +18 -18
  267. package/typings/comm/scan.ts +6 -6
  268. package/typings/common.ts +4 -4
  269. package/typings/context/data.ts +10 -10
  270. package/typings/ext/market-seat.ts +42 -42
  271. package/typings/ext/market.ts +55 -55
  272. package/typings/ext/module.ts +64 -64
  273. package/typings/ext/plugin.ts +38 -38
  274. package/typings/ioc/metadata.ts +34 -34
  275. package/typings/logger/config.ts +6 -6
  276. package/typings/routing/crud.ts +199 -199
  277. package/typings/routing/eps.ts +90 -88
  278. package/typings/routing/meta.ts +80 -63
  279. package/typings/routing/register.ts +21 -21
  280. package/typings/routing/scan-context.ts +7 -7
@@ -1,183 +1,183 @@
1
- <template>
2
- <button
3
- v-if="visible"
4
- type="button"
5
- class="vm-crud-toolbar__btn is-ghost"
6
- :disabled="disabled || submitting"
7
- @click="onExport"
8
- >
9
- <i class="ri-download-2-line" />
10
- {{ buttonText }}
11
- </button>
12
- </template>
13
-
14
- <script setup lang="ts">
15
- import { computed, inject, ref } from 'vue'
16
- import { toast } from 'vue-sonner'
17
- import {
18
- exportCrudExcel,
19
- flattenExportRows,
20
- pickExportColumns,
21
- } from '../lib/export-excel'
22
- import {
23
- injectTableOptions,
24
- TABLE_API_KEY,
25
- type TableApi,
26
- } from './key'
27
- import { fetchExportRowsByPage } from './export-fetch'
28
- import { useCrud } from './useCrud'
29
- import { crudFormat, crudLabel, getCrudStyle } from './style'
30
- import { resolveMergedTableColumns } from './auto-fields'
31
- import type {
32
- CrudColumn,
33
- CrudPermission,
34
- } from '../../../typings/admin/comm/crud'
35
-
36
- defineOptions({ name: 'vm-export-btn' })
37
-
38
- const props = withDefaults(
39
- defineProps<{
40
- /** 列配置;默认取 Table.getColumns() 或 useTable columns */
41
- columns?: CrudColumn[]
42
- /** 自定义数据源;默认按当前筛选 POST page 自动翻页拉全量 */
43
- data?:
44
- | Record<string, unknown>[]
45
- | ((params: Record<string, unknown>) => Promise<Record<string, unknown>[]>)
46
- filename?: string | (() => string)
47
- maxExportLimit?: number
48
- disabled?: boolean
49
- text?: string
50
- /** 权限键,默认 page */
51
- permission?: keyof CrudPermission
52
- }>(),
53
- {
54
- filename: undefined,
55
- maxExportLimit: 5000,
56
- disabled: false,
57
- permission: 'page',
58
- },
59
- )
60
-
61
- const crud = useCrud()
62
- const tableOpts = injectTableOptions()
63
- const tableApi = inject(TABLE_API_KEY, null as TableApi | null)
64
- const submitting = ref(false)
65
-
66
- /** 导出长请求:不走默认 5s 超时 */
67
- const EXPORT_REQUEST_OPTS = { timeoutMs: 0 } as const
68
-
69
- const visible = computed(() => Boolean(crud.getPermission(props.permission)))
70
-
71
- const buttonText = computed(
72
- () => props.text || crudLabel('export', crud.dict.label),
73
- )
74
-
75
- const exportColumns = computed(() => {
76
- void crud.permission.value
77
- if (props.columns?.length) return pickExportColumns(props.columns)
78
- const fromTable = tableApi?.getColumns()
79
- if (fromTable?.length) return pickExportColumns(fromTable)
80
- // toolbar 与 table 是兄弟,inject 不到 Table API;须与表格同源合并 EPS + 手写列
81
- return pickExportColumns(
82
- resolveMergedTableColumns({
83
- service: crud.service,
84
- tableOpts,
85
- tablePlugins: (getCrudStyle().table.plugins || []) as Array<{
86
- __plugin?: string
87
- ignoreFields?: string[]
88
- }>,
89
- }),
90
- )
91
- })
92
-
93
- function resolveFilename() {
94
- const raw = props.filename
95
- const name = typeof raw === 'function' ? raw() : raw
96
- return name || crudLabel('export')
97
- }
98
-
99
- async function fetchRowsByPage(): Promise<Record<string, unknown>[]> {
100
- const svc = crud.service
101
- if (!svc.page) {
102
- return flattenExportRows(crud.list.value, tableOpts?.tree)
103
- }
104
-
105
- const pageKey = crud.dict.pagination.page
106
- const sizeKey = crud.dict.pagination.size
107
-
108
- return fetchExportRowsByPage({
109
- buildQuery: (extra) => crud.buildListQuery(extra),
110
- pageKey,
111
- sizeKey,
112
- page: (body, opts) => crud.requestPage(body, opts),
113
- maxExportLimit: props.maxExportLimit,
114
- totalHint: crud.pagination.value.total,
115
- requestOpts: EXPORT_REQUEST_OPTS,
116
- })
117
- }
118
-
119
- async function fetchRows(): Promise<Record<string, unknown>[]> {
120
- if (props.data) {
121
- if (typeof props.data === 'function') {
122
- return props.data(crud.buildExportQuery())
123
- }
124
- return props.data
125
- }
126
-
127
- return fetchRowsByPage()
128
- }
129
-
130
- async function onExport() {
131
- if (submitting.value || props.disabled) return
132
- if (!exportColumns.value.length) {
133
- toast.error(crudLabel('exportNoCols'))
134
- return
135
- }
136
-
137
- submitting.value = true
138
- try {
139
- const rows = await fetchRows()
140
- if (!rows.length) {
141
- toast.warning(crudLabel('exportNoData'))
142
- return
143
- }
144
- const flat = flattenExportRows(rows, tableOpts?.tree)
145
- exportCrudExcel(exportColumns.value, flat, resolveFilename())
146
- toast.success(crudFormat(crudLabel('exportSuccess'), flat.length))
147
- } catch (e) {
148
- toast.error(e instanceof Error ? e.message : crudLabel('exportFail'))
149
- } finally {
150
- submitting.value = false
151
- }
152
- }
153
- </script>
154
-
155
- <style lang="scss" scoped>
156
- .vm-crud-toolbar__btn {
157
- display: inline-flex;
158
- height: 36px;
159
- align-items: center;
160
- gap: 4px;
161
- padding: 0 14px;
162
- border: none;
163
- border-radius: 12px;
164
- font-size: 13px;
165
- font-weight: 600;
166
- cursor: pointer;
167
- transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease;
168
-
169
- &:disabled {
170
- cursor: not-allowed;
171
- opacity: 0.45;
172
- }
173
-
174
- &.is-ghost {
175
- background: var(--muted);
176
- color: var(--foreground);
177
-
178
- &:hover:not(:disabled) {
179
- background: color-mix(in srgb, var(--muted) 70%, var(--foreground) 8%);
180
- }
181
- }
182
- }
183
- </style>
1
+ <template>
2
+ <button
3
+ v-if="visible"
4
+ type="button"
5
+ class="vm-crud-toolbar__btn is-ghost"
6
+ :disabled="disabled || submitting"
7
+ @click="onExport"
8
+ >
9
+ <i class="ri-download-2-line" />
10
+ {{ buttonText }}
11
+ </button>
12
+ </template>
13
+
14
+ <script setup lang="ts">
15
+ import { computed, inject, ref } from 'vue'
16
+ import { toast } from 'vue-sonner'
17
+ import {
18
+ exportCrudExcel,
19
+ flattenExportRows,
20
+ pickExportColumns,
21
+ } from '../lib/export-excel'
22
+ import {
23
+ injectTableOptions,
24
+ TABLE_API_KEY,
25
+ type TableApi,
26
+ } from './key'
27
+ import { fetchExportRowsByPage } from './export-fetch'
28
+ import { useCrud } from './useCrud'
29
+ import { crudFormat, crudLabel, getCrudStyle } from './style'
30
+ import { resolveMergedTableColumns } from './auto-fields'
31
+ import type {
32
+ CrudColumn,
33
+ CrudPermission,
34
+ } from '../../../typings/admin/comm/crud'
35
+
36
+ defineOptions({ name: 'vm-export-btn' })
37
+
38
+ const props = withDefaults(
39
+ defineProps<{
40
+ /** 列配置;默认取 Table.getColumns() 或 useTable columns */
41
+ columns?: CrudColumn[]
42
+ /** 自定义数据源;默认按当前筛选 POST page 自动翻页拉全量 */
43
+ data?:
44
+ | Record<string, unknown>[]
45
+ | ((params: Record<string, unknown>) => Promise<Record<string, unknown>[]>)
46
+ filename?: string | (() => string)
47
+ maxExportLimit?: number
48
+ disabled?: boolean
49
+ text?: string
50
+ /** 权限键,默认 page */
51
+ permission?: keyof CrudPermission
52
+ }>(),
53
+ {
54
+ filename: undefined,
55
+ maxExportLimit: 5000,
56
+ disabled: false,
57
+ permission: 'page',
58
+ },
59
+ )
60
+
61
+ const crud = useCrud()
62
+ const tableOpts = injectTableOptions()
63
+ const tableApi = inject(TABLE_API_KEY, null as TableApi | null)
64
+ const submitting = ref(false)
65
+
66
+ /** 导出长请求:不走默认 5s 超时 */
67
+ const EXPORT_REQUEST_OPTS = { timeoutMs: 0 } as const
68
+
69
+ const visible = computed(() => Boolean(crud.getPermission(props.permission)))
70
+
71
+ const buttonText = computed(
72
+ () => props.text || crudLabel('export', crud.dict.label),
73
+ )
74
+
75
+ const exportColumns = computed(() => {
76
+ void crud.permission.value
77
+ if (props.columns?.length) return pickExportColumns(props.columns)
78
+ const fromTable = tableApi?.getColumns()
79
+ if (fromTable?.length) return pickExportColumns(fromTable)
80
+ // toolbar 与 table 是兄弟,inject 不到 Table API;须与表格同源合并 EPS + 手写列
81
+ return pickExportColumns(
82
+ resolveMergedTableColumns({
83
+ service: crud.service,
84
+ tableOpts,
85
+ tablePlugins: (getCrudStyle().table.plugins || []) as Array<{
86
+ __plugin?: string
87
+ ignoreFields?: string[]
88
+ }>,
89
+ }),
90
+ )
91
+ })
92
+
93
+ function resolveFilename() {
94
+ const raw = props.filename
95
+ const name = typeof raw === 'function' ? raw() : raw
96
+ return name || crudLabel('export')
97
+ }
98
+
99
+ async function fetchRowsByPage(): Promise<Record<string, unknown>[]> {
100
+ const svc = crud.service
101
+ if (!svc.page) {
102
+ return flattenExportRows(crud.list.value, tableOpts?.tree)
103
+ }
104
+
105
+ const pageKey = crud.dict.pagination.page
106
+ const sizeKey = crud.dict.pagination.size
107
+
108
+ return fetchExportRowsByPage({
109
+ buildQuery: (extra) => crud.buildListQuery(extra),
110
+ pageKey,
111
+ sizeKey,
112
+ page: (body, opts) => crud.requestPage(body, opts),
113
+ maxExportLimit: props.maxExportLimit,
114
+ totalHint: crud.pagination.value.total,
115
+ requestOpts: EXPORT_REQUEST_OPTS,
116
+ })
117
+ }
118
+
119
+ async function fetchRows(): Promise<Record<string, unknown>[]> {
120
+ if (props.data) {
121
+ if (typeof props.data === 'function') {
122
+ return props.data(crud.buildExportQuery())
123
+ }
124
+ return props.data
125
+ }
126
+
127
+ return fetchRowsByPage()
128
+ }
129
+
130
+ async function onExport() {
131
+ if (submitting.value || props.disabled) return
132
+ if (!exportColumns.value.length) {
133
+ toast.error(crudLabel('exportNoCols'))
134
+ return
135
+ }
136
+
137
+ submitting.value = true
138
+ try {
139
+ const rows = await fetchRows()
140
+ if (!rows.length) {
141
+ toast.warning(crudLabel('exportNoData'))
142
+ return
143
+ }
144
+ const flat = flattenExportRows(rows, tableOpts?.tree)
145
+ exportCrudExcel(exportColumns.value, flat, resolveFilename())
146
+ toast.success(crudFormat(crudLabel('exportSuccess'), flat.length))
147
+ } catch (e) {
148
+ toast.error(e instanceof Error ? e.message : crudLabel('exportFail'))
149
+ } finally {
150
+ submitting.value = false
151
+ }
152
+ }
153
+ </script>
154
+
155
+ <style lang="scss" scoped>
156
+ .vm-crud-toolbar__btn {
157
+ display: inline-flex;
158
+ height: 36px;
159
+ align-items: center;
160
+ gap: 4px;
161
+ padding: 0 14px;
162
+ border: none;
163
+ border-radius: 12px;
164
+ font-size: 13px;
165
+ font-weight: 600;
166
+ cursor: pointer;
167
+ transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease;
168
+
169
+ &:disabled {
170
+ cursor: not-allowed;
171
+ opacity: 0.45;
172
+ }
173
+
174
+ &.is-ghost {
175
+ background: var(--muted);
176
+ color: var(--foreground);
177
+
178
+ &:hover:not(:disabled) {
179
+ background: color-mix(in srgb, var(--muted) 70%, var(--foreground) 8%);
180
+ }
181
+ }
182
+ }
183
+ </style>
@@ -1,14 +1,14 @@
1
- <template>
2
- <div class="vm-crud-flex" />
3
- </template>
4
-
5
- <script setup lang="ts">
6
- defineOptions({ name: 'vm-flex' })
7
- </script>
8
-
9
- <style lang="scss" scoped>
10
- .vm-crud-flex {
11
- flex: 1;
12
- min-width: 0;
13
- }
14
- </style>
1
+ <template>
2
+ <div class="vm-crud-flex" />
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ defineOptions({ name: 'vm-flex' })
7
+ </script>
8
+
9
+ <style lang="scss" scoped>
10
+ .vm-crud-flex {
11
+ flex: 1;
12
+ min-width: 0;
13
+ }
14
+ </style>