@robot-admin/request-core 0.4.0 → 0.5.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 (45) hide show
  1. package/CHANGELOG.md +24 -3
  2. package/README.md +43 -3
  3. package/dist/{chunk-WUZ43MLM.cjs → chunk-3VKMESSO.cjs} +4 -4
  4. package/dist/{chunk-WUZ43MLM.cjs.map → chunk-3VKMESSO.cjs.map} +1 -1
  5. package/dist/{chunk-QSDNDTOZ.js → chunk-5ZK67Q2E.js} +3 -3
  6. package/dist/{chunk-QSDNDTOZ.js.map → chunk-5ZK67Q2E.js.map} +1 -1
  7. package/dist/{chunk-2JXH7SIL.js → chunk-ICWJ3KIS.js} +37 -17
  8. package/dist/chunk-ICWJ3KIS.js.map +1 -0
  9. package/dist/chunk-NCTU7EUD.cjs +27 -0
  10. package/dist/chunk-NCTU7EUD.cjs.map +1 -0
  11. package/dist/chunk-ONOINBRA.js +25 -0
  12. package/dist/chunk-ONOINBRA.js.map +1 -0
  13. package/dist/{chunk-KHI6XQRN.cjs → chunk-PWK5GFU3.cjs} +37 -17
  14. package/dist/chunk-PWK5GFU3.cjs.map +1 -0
  15. package/dist/chunk-SENLCWTU.js +8 -0
  16. package/dist/{chunk-56QOEWUS.js.map → chunk-SENLCWTU.js.map} +1 -1
  17. package/dist/chunk-SUYY5N5J.cjs +10 -0
  18. package/dist/{chunk-WXHQXPS4.cjs.map → chunk-SUYY5N5J.cjs.map} +1 -1
  19. package/dist/createTableCrud-C8GsAwxO.d.ts +9 -0
  20. package/dist/createTableCrud-Ctl2qZY-.d.cts +9 -0
  21. package/dist/crud.cjs +5 -5
  22. package/dist/crud.d.cts +1 -1
  23. package/dist/crud.d.ts +1 -1
  24. package/dist/crud.js +3 -3
  25. package/dist/index.cjs +10 -5
  26. package/dist/index.d.cts +2 -1
  27. package/dist/index.d.ts +2 -1
  28. package/dist/index.js +4 -3
  29. package/dist/naive.cjs +3 -3
  30. package/dist/naive.d.cts +2 -2
  31. package/dist/naive.d.ts +2 -2
  32. package/dist/naive.js +2 -2
  33. package/dist/{types-CUyibJZX.d.ts → types-4y_P4TzY.d.ts} +29 -1
  34. package/dist/{types-BRDRqYFs.d.cts → types-DHOiso_K.d.cts} +29 -1
  35. package/dist/vue.cjs +11 -6
  36. package/dist/vue.cjs.map +1 -1
  37. package/dist/vue.d.cts +3 -2
  38. package/dist/vue.d.ts +3 -2
  39. package/dist/vue.js +2 -1
  40. package/dist/vue.js.map +1 -1
  41. package/package.json +1 -1
  42. package/dist/chunk-2JXH7SIL.js.map +0 -1
  43. package/dist/chunk-56QOEWUS.js +0 -8
  44. package/dist/chunk-KHI6XQRN.cjs.map +0 -1
  45. package/dist/chunk-WXHQXPS4.cjs +0 -10
package/CHANGELOG.md CHANGED
@@ -1,8 +1,29 @@
1
1
  # @robot-admin/request-core
2
2
 
3
- > `0.4.0` is the cumulative release candidate. The `0.2.1` and `0.3.0`
4
- > sections below record the internal implementation milestones folded into it;
5
- > they are not separate publication requirements.
3
+ > `0.4.0` is the cumulative feature release. The `0.2.1` and `0.3.0` sections
4
+ > below record the internal implementation milestones folded into it; they were
5
+ > not published as separate package versions.
6
+
7
+ ## 0.5.0
8
+
9
+ ### Minor Changes
10
+
11
+ - Add the UI-independent `createTableCrud()` factory so applications can define a
12
+ request client, lifecycle defaults and standard list parameter names once without
13
+ class inheritance or shared reactive state.
14
+ - Add `listParams` object and function mappings for endpoint-based tables, supporting
15
+ backend conventions such as `current/size` without repeated page adapters.
16
+ - Document the intended split between the headless request/table state and project-owned
17
+ Naive UI, Element Plus or other presentation components.
18
+ - Expand runtime, public-type and package-entry verification for the new factory and
19
+ parameter mapping behavior.
20
+
21
+ ## 0.4.1
22
+
23
+ ### Patch Changes
24
+
25
+ - Clarify the cumulative release history after the formal `0.4.0` publication.
26
+ - Keep package and repository version references aligned; runtime behavior is unchanged.
6
27
 
7
28
  ## 0.4.0
8
29
 
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![license](https://img.shields.io/npm/l/@robot-admin/request-core.svg)](./LICENSE)
5
5
 
6
6
  面向生产环境的实例化请求编排与 Vue 3 Headless CRUD 工具。当前版本:
7
- `0.4.0`。
7
+ `0.5.0`。
8
8
 
9
9
  它保留 Axios 的完整能力,只收拢应用中最容易重复出错的部分:并发请求、缓存、
10
10
  取消、重试、Token 刷新、错误标准化以及列表 CRUD 生命周期。
@@ -18,6 +18,7 @@
18
18
  - 重试支持幂等方法白名单、指数退避、抖动、`Retry-After` 和总时间预算。
19
19
  - Token 主动刷新、并发 401 恢复和重新登录均使用 single-flight。
20
20
  - `RequestError` 统一业务、HTTP、网络、超时、取消和配置错误。
21
+ - `createTableCrud()` 以函数式应用预配置消除类继承和页面级分页映射重复。
21
22
  - Vue 层不依赖具体 UI;Naive UI 仅作为可选兼容适配层。
22
23
  - ESM、CJS 和 TypeScript 类型入口均经过发布前验证。
23
24
 
@@ -30,7 +31,7 @@ bun add @robot-admin/request-core axios
30
31
  | 入口 | 依赖边界 | 用途 |
31
32
  | --- | --- | --- |
32
33
  | `@robot-admin/request-core/axios` | Axios | 推荐的请求 Client、策略及兼容 API |
33
- | `@robot-admin/request-core/vue` | Axios + Vue | `useRequest`、Headless `useTableCrud`、Client 注入 |
34
+ | `@robot-admin/request-core/vue` | Axios + Vue | `useRequest`、Headless `useTableCrud/createTableCrud`、Client 注入 |
34
35
  | `@robot-admin/request-core/naive` | Axios + Vue + Naive UI | `useNaiveTableCrud` 兼容适配 |
35
36
  | `@robot-admin/request-core` | 完整兼容入口 | 旧项目平滑迁移,当前仍会引用 Naive UI |
36
37
  | `@robot-admin/request-core/crud` | 兼容入口 | 已废弃,迁移到 `/vue` 或 `/naive` |
@@ -272,6 +273,44 @@ await table.search({ keyword: 'robot' })
272
273
  await table.resetSearch()
273
274
  ```
274
275
 
276
+ ### 函数式单表预配置
277
+
278
+ 同一项目中的 Client、加载时机、分页字段名等通常完全相同。使用
279
+ `createTableCrud()` 定义一次应用约定,页面只保留自己的接口、筛选项和变更函数:
280
+
281
+ ```ts
282
+ // src/composables/useAppTable.ts
283
+ import { createTableCrud } from '@robot-admin/request-core/vue'
284
+ import { request } from '@/services/request'
285
+
286
+ export const useAppTable = createTableCrud({
287
+ client: request,
288
+ autoLoad: 'mounted',
289
+ defaultPageSize: 20,
290
+ listParams: { page: 'current', pageSize: 'size' },
291
+ })
292
+
293
+ // user-page.ts
294
+ const table = useAppTable<User, UserFilters>({
295
+ api: { list: '/users' },
296
+ initialFilters: { keyword: '' },
297
+ mutations: {
298
+ create: (row, { signal }) => request.post('/users', row, { signal }),
299
+ update: (row, { signal }) =>
300
+ request.put(`/users/${row.id}`, row, { signal }),
301
+ remove: (row, { signal }) =>
302
+ request.delete(`/users/${row.id}`, { signal }),
303
+ },
304
+ })
305
+ ```
306
+
307
+ 工厂只保存配置快照,每次调用仍创建完全隔离的响应式状态。页面配置可以覆盖任意
308
+ 默认项;`listParams` 对象用于重命名或省略 `page/pageSize/sort`,函数形式则可完全
309
+ 接管参数生成。复杂页面仍直接使用 `useTableCrud()`,不需要迁移到另一套抽象。
310
+
311
+ 使用侧不需要把整个返回对象逐项转发。控制器代码可保留 `table` 能力对象,Vue
312
+ 模板只解构实际使用的字段,避免形成新的“大而全返回值”约定。
313
+
275
314
  主要返回值:
276
315
 
277
316
  | 状态/方法 | 说明 |
@@ -301,7 +340,8 @@ const table = useNaiveTableCrud({
301
340
  ```
302
341
 
303
342
  `useNaiveTableCrud` 只注入 Naive UI 的 Message/Dialog,数据能力与 `/vue` 完全
304
- 共用。Element Plus 项目直接使用 `/vue`,在真实业务需要前无需额外 UI 适配包。
343
+ 共用。Element Plus 或其他 Vue UI 项目直接使用 `/vue` 并在应用边界传入可选 `ui`
344
+ 适配器;表格、查询表单、列配置和工具栏继续由项目自己的呈现层负责。
305
345
 
306
346
  ## 兼容 API
307
347
 
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var chunkKHI6XQRN_cjs = require('./chunk-KHI6XQRN.cjs');
3
+ var chunkPWK5GFU3_cjs = require('./chunk-PWK5GFU3.cjs');
4
4
  var naiveUi = require('naive-ui');
5
5
 
6
6
  function useNaiveTableCrud(config) {
7
7
  const message = naiveUi.useMessage();
8
8
  const dialog = naiveUi.useDialog();
9
- return chunkKHI6XQRN_cjs.useTableCrud({
9
+ return chunkPWK5GFU3_cjs.useTableCrud({
10
10
  ...config,
11
11
  ui: config.ui ?? {
12
12
  message: {
@@ -26,5 +26,5 @@ function useNaiveTableCrud(config) {
26
26
  }
27
27
 
28
28
  exports.useNaiveTableCrud = useNaiveTableCrud;
29
- //# sourceMappingURL=chunk-WUZ43MLM.cjs.map
30
- //# sourceMappingURL=chunk-WUZ43MLM.cjs.map
29
+ //# sourceMappingURL=chunk-3VKMESSO.cjs.map
30
+ //# sourceMappingURL=chunk-3VKMESSO.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/naive/useNaiveTableCrud.ts"],"names":["useMessage","useDialog","useTableCrud"],"mappings":";;;;;AAQO,SAAS,kBAKd,MAAA,EACsC;AACtC,EAAA,MAAM,UAAUA,kBAAA,EAAW;AAC3B,EAAA,MAAM,SAASC,iBAAA,EAAU;AACzB,EAAA,OAAOC,8BAAA,CAAa;AAAA,IAClB,GAAG,MAAA;AAAA,IACH,EAAA,EAAI,OAAO,EAAA,IAAM;AAAA,MACf,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,CAAC,IAAA,KAAS,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,QACvC,KAAA,EAAO,CAAC,IAAA,KAAS,OAAA,CAAQ,MAAM,IAAI,CAAA;AAAA,QACnC,OAAA,EAAS,CAAC,IAAA,KAAS,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,QACvC,IAAA,EAAM,CAAC,IAAA,KAAS,OAAA,CAAQ,KAAK,IAAI;AAAA,OACnC;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,OAAA,EAAS,CAAC,OAAA,KACR,MAAA,CAAO,QAAQ,OAA+C,CAAA;AAAA,QAChE,KAAA,EAAO,CAAC,OAAA,KACN,MAAA,CAAO,MAAM,OAA6C,CAAA;AAAA,QAC5D,OAAA,EAAS,CAAC,OAAA,KACR,MAAA,CAAO,QAAQ,OAA+C,CAAA;AAAA,QAChE,IAAA,EAAM,CAAC,OAAA,KACL,MAAA,CAAO,KAAK,OAA4C;AAAA;AAC5D;AACF,GACD,CAAA;AACH","file":"chunk-WUZ43MLM.cjs","sourcesContent":["import { useDialog, useMessage } from \"naive-ui\";\nimport { useTableCrud } from \"../composables/useTableCrud/useTableCrud\";\nimport type {\n DataRecord,\n UseTableCrudConfig,\n UseTableCrudReturn,\n} from \"../composables/useTableCrud/types\";\n\nexport function useNaiveTableCrud<\n T extends DataRecord,\n Filters extends object = Record<string, unknown>,\n Sort extends object = Record<string, unknown>,\n>(\n config: UseTableCrudConfig<T, Filters, Sort>,\n): UseTableCrudReturn<T, Filters, Sort> {\n const message = useMessage();\n const dialog = useDialog();\n return useTableCrud({\n ...config,\n ui: config.ui ?? {\n message: {\n success: (text) => message.success(text),\n error: (text) => message.error(text),\n warning: (text) => message.warning(text),\n info: (text) => message.info(text),\n },\n dialog: {\n warning: (options) =>\n dialog.warning(options as Parameters<typeof dialog.warning>[0]),\n error: (options) =>\n dialog.error(options as Parameters<typeof dialog.error>[0]),\n success: (options) =>\n dialog.success(options as Parameters<typeof dialog.success>[0]),\n info: (options) =>\n dialog.info(options as Parameters<typeof dialog.info>[0]),\n },\n },\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/naive/useNaiveTableCrud.ts"],"names":["useMessage","useDialog","useTableCrud"],"mappings":";;;;;AAQO,SAAS,kBAKd,MAAA,EACsC;AACtC,EAAA,MAAM,UAAUA,kBAAA,EAAW;AAC3B,EAAA,MAAM,SAASC,iBAAA,EAAU;AACzB,EAAA,OAAOC,8BAAA,CAAa;AAAA,IAClB,GAAG,MAAA;AAAA,IACH,EAAA,EAAI,OAAO,EAAA,IAAM;AAAA,MACf,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,CAAC,IAAA,KAAS,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,QACvC,KAAA,EAAO,CAAC,IAAA,KAAS,OAAA,CAAQ,MAAM,IAAI,CAAA;AAAA,QACnC,OAAA,EAAS,CAAC,IAAA,KAAS,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,QACvC,IAAA,EAAM,CAAC,IAAA,KAAS,OAAA,CAAQ,KAAK,IAAI;AAAA,OACnC;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,OAAA,EAAS,CAAC,OAAA,KACR,MAAA,CAAO,QAAQ,OAA+C,CAAA;AAAA,QAChE,KAAA,EAAO,CAAC,OAAA,KACN,MAAA,CAAO,MAAM,OAA6C,CAAA;AAAA,QAC5D,OAAA,EAAS,CAAC,OAAA,KACR,MAAA,CAAO,QAAQ,OAA+C,CAAA;AAAA,QAChE,IAAA,EAAM,CAAC,OAAA,KACL,MAAA,CAAO,KAAK,OAA4C;AAAA;AAC5D;AACF,GACD,CAAA;AACH","file":"chunk-3VKMESSO.cjs","sourcesContent":["import { useDialog, useMessage } from \"naive-ui\";\nimport { useTableCrud } from \"../composables/useTableCrud/useTableCrud\";\nimport type {\n DataRecord,\n UseTableCrudConfig,\n UseTableCrudReturn,\n} from \"../composables/useTableCrud/types\";\n\nexport function useNaiveTableCrud<\n T extends DataRecord,\n Filters extends object = Record<string, unknown>,\n Sort extends object = Record<string, unknown>,\n>(\n config: UseTableCrudConfig<T, Filters, Sort>,\n): UseTableCrudReturn<T, Filters, Sort> {\n const message = useMessage();\n const dialog = useDialog();\n return useTableCrud({\n ...config,\n ui: config.ui ?? {\n message: {\n success: (text) => message.success(text),\n error: (text) => message.error(text),\n warning: (text) => message.warning(text),\n info: (text) => message.info(text),\n },\n dialog: {\n warning: (options) =>\n dialog.warning(options as Parameters<typeof dialog.warning>[0]),\n error: (options) =>\n dialog.error(options as Parameters<typeof dialog.error>[0]),\n success: (options) =>\n dialog.success(options as Parameters<typeof dialog.success>[0]),\n info: (options) =>\n dialog.info(options as Parameters<typeof dialog.info>[0]),\n },\n },\n });\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { useTableCrud } from './chunk-2JXH7SIL.js';
1
+ import { useTableCrud } from './chunk-ICWJ3KIS.js';
2
2
  import { useMessage, useDialog } from 'naive-ui';
3
3
 
4
4
  function useNaiveTableCrud(config) {
@@ -24,5 +24,5 @@ function useNaiveTableCrud(config) {
24
24
  }
25
25
 
26
26
  export { useNaiveTableCrud };
27
- //# sourceMappingURL=chunk-QSDNDTOZ.js.map
28
- //# sourceMappingURL=chunk-QSDNDTOZ.js.map
27
+ //# sourceMappingURL=chunk-5ZK67Q2E.js.map
28
+ //# sourceMappingURL=chunk-5ZK67Q2E.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/naive/useNaiveTableCrud.ts"],"names":[],"mappings":";;;AAQO,SAAS,kBAKd,MAAA,EACsC;AACtC,EAAA,MAAM,UAAU,UAAA,EAAW;AAC3B,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,OAAO,YAAA,CAAa;AAAA,IAClB,GAAG,MAAA;AAAA,IACH,EAAA,EAAI,OAAO,EAAA,IAAM;AAAA,MACf,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,CAAC,IAAA,KAAS,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,QACvC,KAAA,EAAO,CAAC,IAAA,KAAS,OAAA,CAAQ,MAAM,IAAI,CAAA;AAAA,QACnC,OAAA,EAAS,CAAC,IAAA,KAAS,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,QACvC,IAAA,EAAM,CAAC,IAAA,KAAS,OAAA,CAAQ,KAAK,IAAI;AAAA,OACnC;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,OAAA,EAAS,CAAC,OAAA,KACR,MAAA,CAAO,QAAQ,OAA+C,CAAA;AAAA,QAChE,KAAA,EAAO,CAAC,OAAA,KACN,MAAA,CAAO,MAAM,OAA6C,CAAA;AAAA,QAC5D,OAAA,EAAS,CAAC,OAAA,KACR,MAAA,CAAO,QAAQ,OAA+C,CAAA;AAAA,QAChE,IAAA,EAAM,CAAC,OAAA,KACL,MAAA,CAAO,KAAK,OAA4C;AAAA;AAC5D;AACF,GACD,CAAA;AACH","file":"chunk-QSDNDTOZ.js","sourcesContent":["import { useDialog, useMessage } from \"naive-ui\";\nimport { useTableCrud } from \"../composables/useTableCrud/useTableCrud\";\nimport type {\n DataRecord,\n UseTableCrudConfig,\n UseTableCrudReturn,\n} from \"../composables/useTableCrud/types\";\n\nexport function useNaiveTableCrud<\n T extends DataRecord,\n Filters extends object = Record<string, unknown>,\n Sort extends object = Record<string, unknown>,\n>(\n config: UseTableCrudConfig<T, Filters, Sort>,\n): UseTableCrudReturn<T, Filters, Sort> {\n const message = useMessage();\n const dialog = useDialog();\n return useTableCrud({\n ...config,\n ui: config.ui ?? {\n message: {\n success: (text) => message.success(text),\n error: (text) => message.error(text),\n warning: (text) => message.warning(text),\n info: (text) => message.info(text),\n },\n dialog: {\n warning: (options) =>\n dialog.warning(options as Parameters<typeof dialog.warning>[0]),\n error: (options) =>\n dialog.error(options as Parameters<typeof dialog.error>[0]),\n success: (options) =>\n dialog.success(options as Parameters<typeof dialog.success>[0]),\n info: (options) =>\n dialog.info(options as Parameters<typeof dialog.info>[0]),\n },\n },\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/naive/useNaiveTableCrud.ts"],"names":[],"mappings":";;;AAQO,SAAS,kBAKd,MAAA,EACsC;AACtC,EAAA,MAAM,UAAU,UAAA,EAAW;AAC3B,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,OAAO,YAAA,CAAa;AAAA,IAClB,GAAG,MAAA;AAAA,IACH,EAAA,EAAI,OAAO,EAAA,IAAM;AAAA,MACf,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,CAAC,IAAA,KAAS,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,QACvC,KAAA,EAAO,CAAC,IAAA,KAAS,OAAA,CAAQ,MAAM,IAAI,CAAA;AAAA,QACnC,OAAA,EAAS,CAAC,IAAA,KAAS,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,QACvC,IAAA,EAAM,CAAC,IAAA,KAAS,OAAA,CAAQ,KAAK,IAAI;AAAA,OACnC;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,OAAA,EAAS,CAAC,OAAA,KACR,MAAA,CAAO,QAAQ,OAA+C,CAAA;AAAA,QAChE,KAAA,EAAO,CAAC,OAAA,KACN,MAAA,CAAO,MAAM,OAA6C,CAAA;AAAA,QAC5D,OAAA,EAAS,CAAC,OAAA,KACR,MAAA,CAAO,QAAQ,OAA+C,CAAA;AAAA,QAChE,IAAA,EAAM,CAAC,OAAA,KACL,MAAA,CAAO,KAAK,OAA4C;AAAA;AAC5D;AACF,GACD,CAAA;AACH","file":"chunk-5ZK67Q2E.js","sourcesContent":["import { useDialog, useMessage } from \"naive-ui\";\nimport { useTableCrud } from \"../composables/useTableCrud/useTableCrud\";\nimport type {\n DataRecord,\n UseTableCrudConfig,\n UseTableCrudReturn,\n} from \"../composables/useTableCrud/types\";\n\nexport function useNaiveTableCrud<\n T extends DataRecord,\n Filters extends object = Record<string, unknown>,\n Sort extends object = Record<string, unknown>,\n>(\n config: UseTableCrudConfig<T, Filters, Sort>,\n): UseTableCrudReturn<T, Filters, Sort> {\n const message = useMessage();\n const dialog = useDialog();\n return useTableCrud({\n ...config,\n ui: config.ui ?? {\n message: {\n success: (text) => message.success(text),\n error: (text) => message.error(text),\n warning: (text) => message.warning(text),\n info: (text) => message.info(text),\n },\n dialog: {\n warning: (options) =>\n dialog.warning(options as Parameters<typeof dialog.warning>[0]),\n error: (options) =>\n dialog.error(options as Parameters<typeof dialog.error>[0]),\n success: (options) =>\n dialog.success(options as Parameters<typeof dialog.success>[0]),\n info: (options) =>\n dialog.info(options as Parameters<typeof dialog.info>[0]),\n },\n },\n });\n}\n"]}
@@ -244,9 +244,33 @@ function asQueryResult(value) {
244
244
  const candidate = value;
245
245
  return Array.isArray(candidate.items) && Number.isFinite(candidate.total) ? { items: candidate.items, total: Number(candidate.total) } : null;
246
246
  }
247
+ function resolveParamKey(value, fallback) {
248
+ if (value === false) return false;
249
+ if (value === void 0) return fallback;
250
+ if (value.trim().length === 0) {
251
+ throw new RangeError("List parameter keys cannot be empty strings.");
252
+ }
253
+ return value;
254
+ }
255
+ function buildListParams(context, keys = {}) {
256
+ const pageKey = resolveParamKey(keys.page, "page");
257
+ const pageSizeKey = resolveParamKey(keys.pageSize, "pageSize");
258
+ const sortKey = resolveParamKey(keys.sort, "sort");
259
+ const paginationParams = {};
260
+ if (context.paginationEnabled) {
261
+ if (pageKey !== false) paginationParams[pageKey] = context.page;
262
+ if (pageSizeKey !== false) paginationParams[pageSizeKey] = context.pageSize;
263
+ }
264
+ return {
265
+ ...paginationParams,
266
+ ...context.filters,
267
+ ...context.sort && sortKey !== false ? { [sortKey]: context.sort } : {}
268
+ };
269
+ }
247
270
  function useTableCrud(config) {
248
271
  const {
249
272
  api,
273
+ listParams,
250
274
  query,
251
275
  mutations = {},
252
276
  columns = [],
@@ -356,22 +380,18 @@ function useTableCrud(config) {
356
380
  }
357
381
  };
358
382
  const requestList = async (signal) => {
359
- if (query) {
360
- return query({
361
- page: page.current,
362
- pageSize: page.size,
363
- paginationEnabled: paginationEnabled.value,
364
- filters: filters.value,
365
- sort: sort.value,
366
- signal
367
- });
368
- }
369
- const paginationParams = paginationEnabled.value ? { page: page.current, pageSize: page.size } : {};
370
- const params = {
371
- ...paginationParams,
372
- ...filters.value,
373
- ...sort.value ? { sort: sort.value } : {}
383
+ const context = {
384
+ page: page.current,
385
+ pageSize: page.size,
386
+ paginationEnabled: paginationEnabled.value,
387
+ filters: filters.value,
388
+ sort: sort.value,
389
+ signal
374
390
  };
391
+ if (query) {
392
+ return query(context);
393
+ }
394
+ const params = typeof listParams === "function" ? listParams(context) : buildListParams(context, listParams);
375
395
  return client ? client.get(api.list, { params, signal, concurrency: "takeLatest" }) : getData(api.list, { params, signal, dedupe: true });
376
396
  };
377
397
  const refresh = async () => {
@@ -707,5 +727,5 @@ function useTableCrud(config) {
707
727
  }
708
728
 
709
729
  export { REQUEST_CLIENT_KEY, createRequestPlugin, provideRequestClient, useRequestClient, useTableCrud };
710
- //# sourceMappingURL=chunk-2JXH7SIL.js.map
711
- //# sourceMappingURL=chunk-2JXH7SIL.js.map
730
+ //# sourceMappingURL=chunk-ICWJ3KIS.js.map
731
+ //# sourceMappingURL=chunk-ICWJ3KIS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vue/context.ts","../src/composables/useTableCrud/constants.ts","../src/composables/useTableCrud/utils.ts","../src/composables/useTableCrud/useTableCrud.ts"],"names":["rootTotal"],"mappings":"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","file":"chunk-ICWJ3KIS.js","sourcesContent":["import {\n inject,\n provide,\n type App,\n type InjectionKey,\n} from \"vue\";\nimport type { RequestClient } from \"../client/types\";\n\nexport const REQUEST_CLIENT_KEY = Symbol.for(\n \"@robot-admin/request-core/vue-client/v1\",\n) as InjectionKey<RequestClient>;\n\nexport function createRequestPlugin(client: RequestClient) {\n return {\n install(app: App): void {\n app.provide(REQUEST_CLIENT_KEY, client);\n },\n };\n}\n\nexport function provideRequestClient(client: RequestClient): RequestClient {\n provide(REQUEST_CLIENT_KEY, client);\n return client;\n}\n\nexport function useRequestClient(optional = false): RequestClient | undefined {\n const client = inject(REQUEST_CLIENT_KEY, undefined);\n if (!client && !optional) {\n throw new Error(\n \"Request client was not provided. Install createRequestPlugin(client) or pass client explicitly.\",\n );\n }\n return client;\n}\n","/*\n * @Author: ChenYu ycyplus@gmail.com\n * @Date: 2026-02-07 10:00:00\n * @LastEditors: ChenYu ycyplus@gmail.com\n * @LastEditTime: 2026-02-07 10:00:00\n * @FilePath: \\robot-admin-request-core\\src\\composables\\useTableCrud\\constants.ts\n * @Description: useTableCrud 常量定义\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\n */\n\n/**\n * 默认配置\n */\nexport const DEFAULT_CONFIG = {\n /** 默认 ID 字段名 */\n idKey: \"id\",\n /** 默认分页大小 */\n pageSize: 10,\n /** 默认启用分页 */\n paginationEnabled: true,\n /** 默认当前页 */\n currentPage: 1,\n} as const;\n\n/**\n * 响应字段别名配置(支持多种后端响应格式)\n */\n\n/** 数据字段别名(按优先级排序) - 用于从响应中提取数据层 */\nexport const DATA_FIELD_ALIASES = [\"data\", \"list\", \"items\", \"records\"] as const;\n\n/** 列表字段别名(按优先级排序) - 用于从数据层提取列表数组 */\nexport const LIST_FIELD_ALIASES = [\n \"list\",\n \"items\",\n \"records\",\n \"rows\",\n \"data\",\n] as const;\n\n/** 总数字段别名(按优先级排序) - 用于提取数据总数 */\nexport const TOTAL_FIELD_ALIASES = [\n \"total\",\n \"totalCount\",\n \"count\",\n \"totalElements\",\n] as const;\n\n/** 成功状态码(支持数字和字符串) */\nexport const SUCCESS_CODES = [200, 0, \"200\", \"0\"] as const;\n\n/**\n * 默认消息文本\n */\nexport const DEFAULT_MESSAGES = {\n createSuccess: \"新增成功\",\n updateSuccess: \"更新成功\",\n deleteSuccess: \"删除成功\",\n saveError: \"保存失败\",\n deleteError: \"删除失败\",\n loadError: \"数据加载失败\",\n detailError: \"详情获取失败\",\n noDeleteApi: \"未配置删除接口\",\n} as const;\n","/*\n * @Author: ChenYu ycyplus@gmail.com\n * @Date: 2026-02-07 10:00:00\n * @LastEditors: ChenYu ycyplus@gmail.com\n * @LastEditTime: 2026-02-07 10:00:00\n * @FilePath: \\robot-admin-request-core\\src\\composables\\useTableCrud\\utils.ts\n * @Description: useTableCrud 工具函数\n * Copyright (c) 2026 by CHENY, All Rights Reserved 😎.\n */\n\nimport type { DataRecord } from \"./types\";\nimport {\n DATA_FIELD_ALIASES,\n LIST_FIELD_ALIASES,\n TOTAL_FIELD_ALIASES,\n SUCCESS_CODES,\n} from \"./constants\";\nimport { getGlobalConfig } from \"../../core\";\n\n/**\n * 获取运行时字段别名(优先使用全局配置)\n */\nfunction getRuntimeFieldAliases() {\n const config = getGlobalConfig();\n return {\n data: config.fieldAliases.data || DATA_FIELD_ALIASES,\n list: config.fieldAliases.list || LIST_FIELD_ALIASES,\n total: config.fieldAliases.total || TOTAL_FIELD_ALIASES,\n };\n}\n\n/**\n * 获取运行时成功状态码(优先使用全局配置)\n */\nfunction getRuntimeSuccessCodes() {\n const config = getGlobalConfig();\n return config.successCodes || SUCCESS_CODES;\n}\n\n/**\n * 字段查找器(支持多种字段别名)\n */\nexport const FieldFinder = {\n /**\n * 查找第一个存在的字段值\n */\n findFirst<T>(\n obj: object | null | undefined,\n aliases: readonly string[],\n defaultValue: T,\n ): T {\n if (!obj || typeof obj !== \"object\") return defaultValue;\n\n const record = obj as Record<string, unknown>;\n for (const key of aliases) {\n if (key in record && record[key] !== undefined) {\n return record[key] as T;\n }\n }\n return defaultValue;\n },\n\n /**\n * 查找第一个存在的数字字段\n */\n findNumber(\n obj: object | null | undefined,\n aliases: readonly string[],\n defaultValue = 0,\n ): number {\n const value = this.findFirst(obj, aliases, defaultValue);\n const numberValue = Number(value);\n return Number.isFinite(numberValue) ? numberValue : defaultValue;\n },\n};\n\n/**\n * 响应标准化工具\n */\nexport const ResponseNormalizer = {\n /**\n * 判断响应是否成功\n */\n isSuccess(res: unknown): boolean {\n if (!res || typeof res !== \"object\") return false;\n const record = res as Record<string, unknown>;\n if (typeof record.success === \"boolean\") return record.success;\n if (!(\"code\" in record)) return true;\n // 使用运行时配置的成功状态码\n const successCodes = getRuntimeSuccessCodes();\n return (\n successCodes.includes(record.code as number | string) ||\n successCodes.some((code) => String(code) === String(record.code))\n );\n },\n\n /**\n * 标准化响应数据(提取 data 层)\n */\n normalize<T = unknown>(\n res: unknown,\n ): { data: T; success: boolean; raw: unknown } {\n if (!res || typeof res !== \"object\") {\n return { data: res as T, success: true, raw: res };\n }\n\n const aliases = getRuntimeFieldAliases();\n const record = res as Record<string, unknown>;\n const hasDataLayer = aliases.data.some((key) => key in record);\n if (!hasDataLayer) {\n return { data: res as T, success: ResponseNormalizer.isSuccess(res), raw: res };\n }\n return {\n data: FieldFinder.findFirst(record, aliases.data, res) as T,\n success: ResponseNormalizer.isSuccess(res),\n raw: res,\n };\n },\n};\n\n/**\n * URL 工具\n */\nexport const UrlUtils = {\n /**\n * 构建 URL(处理路径参数)\n */\n buildUrl(endpoint: string, id?: unknown): string {\n if (id !== undefined && endpoint.includes(\":id\")) {\n return endpoint.replace(\":id\", encodeURIComponent(String(id)));\n }\n return endpoint;\n },\n};\n\n/**\n * 数据提取工具(增强版,支持多种响应格式)\n */\nexport const DataExtractor = {\n /**\n * 从响应中提取列表数据(支持多种格式)\n *\n * 支持的响应结构:\n * 1. { code: 0, data: { list: [...], total: 10 } } // 嵌套结构(最常见)\n * 2. { data: { items: [...], total: 10 } } // 嵌套结构\n * 3. { list: [...], total: 10 } // 扁平结构\n * 4. { items: [...], totalCount: 10 } // 不同字段名\n * 5. { data: [...] } // 直接数组\n * 6. [...] // 纯数组\n */\n extractList<T = unknown>(response: unknown): { items: T[]; total: number } {\n // 第一步:标准化响应,提取 data 层\n const normalized = ResponseNormalizer.normalize(response);\n const dataLayer = normalized.data;\n const aliases = getRuntimeFieldAliases();\n\n if (Array.isArray(dataLayer)) {\n const rootTotal = FieldFinder.findNumber(\n response && typeof response === \"object\" ? response : null,\n aliases.total,\n dataLayer.length,\n );\n return { items: dataLayer as T[], total: rootTotal };\n }\n\n if (!dataLayer || typeof dataLayer !== \"object\") {\n return { items: [], total: 0 };\n }\n\n // 第二步:从 data 层提取列表数组(使用运行时配置)\n const list = FieldFinder.findFirst<unknown[]>(dataLayer, aliases.list, []);\n\n // 第三步:提取总数(使用运行时配置)\n const rootTotal = FieldFinder.findNumber(\n response && typeof response === \"object\" ? response : null,\n aliases.total,\n Array.isArray(list) ? list.length : 0,\n );\n const total = FieldFinder.findNumber(dataLayer, aliases.total, rootTotal);\n\n return {\n items: Array.isArray(list) ? (list as T[]) : [],\n total,\n };\n },\n\n /**\n * 从响应中提取详情数据\n */\n extractDetail<T = unknown>(response: unknown): T | null {\n // 标准化响应\n const normalized = ResponseNormalizer.normalize(response);\n return normalized.data as T | null;\n },\n};\n\n/**\n * 行操作工具\n */\nexport const RowUtils = {\n /**\n * 从数组中查找行索引\n */\n findIndex<T extends DataRecord>(items: T[], idKey: keyof T, id: unknown): number {\n return items.findIndex((item) => item[idKey] === id);\n },\n\n /**\n * 从数组中移除行\n */\n remove<T extends DataRecord>(items: T[], idKey: keyof T, id: unknown): boolean {\n const index = this.findIndex(items, idKey, id);\n if (index !== -1) {\n items.splice(index, 1);\n return true;\n }\n return false;\n },\n\n /**\n * 生成默认 ID\n */\n generateId(): number {\n return Date.now() + Math.floor(Math.random() * 1000);\n },\n};\n","import {\n computed,\n getCurrentInstance,\n getCurrentScope,\n onMounted,\n onScopeDispose,\n reactive,\n ref,\n shallowRef,\n type Ref,\n} from \"vue\";\nimport {\n deleteData,\n getData,\n postData,\n putData,\n} from \"../../axios/service\";\nimport {\n isCanceledError,\n normalizeRequestError,\n RequestError,\n} from \"../../client/errors\";\nimport { useRequestClient } from \"../../vue/context\";\nimport { DEFAULT_CONFIG, DEFAULT_MESSAGES } from \"./constants\";\nimport type {\n ActionContext,\n CrudDialogApi,\n CrudMessageApi,\n DataRecord,\n TableActions,\n TableListParamKeys,\n TablePageState,\n TableQueryContext,\n TableQueryResult,\n UseTableCrudConfig,\n UseTableCrudReturn,\n} from \"./types\";\nimport { DataExtractor, RowUtils, UrlUtils } from \"./utils\";\n\ntype Operation = \"refresh\" | \"detail\" | \"create\" | \"update\" | \"remove\";\n\nconst noopMessage: CrudMessageApi = {\n success: () => undefined,\n error: () => undefined,\n warning: () => undefined,\n info: () => undefined,\n};\n\nconst noopDialog: CrudDialogApi = {\n warning: () => undefined,\n error: () => undefined,\n success: () => undefined,\n info: () => undefined,\n};\n\nfunction cloneValue<T>(value: T): T {\n if (typeof structuredClone === \"function\") {\n try {\n return structuredClone(value);\n } catch {\n // Shallow fallback supports reactive proxies and class-backed filters.\n }\n }\n return Array.isArray(value)\n ? ([...value] as T)\n : value && typeof value === \"object\"\n ? ({ ...value } as T)\n : value;\n}\n\nfunction recordValue<T extends object>(row: T, key: keyof T): unknown {\n return row[key];\n}\n\nfunction asQueryResult<T>(value: unknown): TableQueryResult<T> | null {\n if (!value || typeof value !== \"object\") return null;\n const candidate = value as Partial<TableQueryResult<T>>;\n return Array.isArray(candidate.items) && Number.isFinite(candidate.total)\n ? { items: candidate.items, total: Number(candidate.total) }\n : null;\n}\n\nfunction resolveParamKey(\n value: string | false | undefined,\n fallback: string,\n): string | false {\n if (value === false) return false;\n if (value === undefined) return fallback;\n if (value.trim().length === 0) {\n throw new RangeError(\"List parameter keys cannot be empty strings.\");\n }\n return value;\n}\n\nfunction buildListParams<Filters extends object, Sort extends object>(\n context: TableQueryContext<Filters, Sort>,\n keys: TableListParamKeys = {},\n): Record<string, unknown> {\n const pageKey = resolveParamKey(keys.page, \"page\");\n const pageSizeKey = resolveParamKey(keys.pageSize, \"pageSize\");\n const sortKey = resolveParamKey(keys.sort, \"sort\");\n const paginationParams: Record<string, unknown> = {};\n\n if (context.paginationEnabled) {\n if (pageKey !== false) paginationParams[pageKey] = context.page;\n if (pageSizeKey !== false) paginationParams[pageSizeKey] = context.pageSize;\n }\n\n return {\n ...paginationParams,\n ...(context.filters as Record<string, unknown>),\n ...(context.sort && sortKey !== false\n ? { [sortKey]: context.sort }\n : {}),\n };\n}\n\nexport function useTableCrud<\n T extends DataRecord,\n Filters extends object = Record<string, unknown>,\n Sort extends object = Record<string, unknown>,\n>(\n config: UseTableCrudConfig<T, Filters, Sort>,\n): UseTableCrudReturn<T, Filters, Sort> {\n const {\n api,\n listParams,\n query,\n mutations = {},\n columns = [],\n customActions = [],\n detail: detailConfig,\n idKey = DEFAULT_CONFIG.idKey as keyof T,\n defaultPageSize = DEFAULT_CONFIG.pageSize,\n defaultPaginationEnabled = DEFAULT_CONFIG.paginationEnabled,\n initialFilters = {} as Filters,\n initialSort = null,\n createNewRow,\n autoLoad = true,\n extractListData,\n refreshAfterMutation = true,\n batchConcurrency = 4,\n detailTitle,\n } = config;\n\n if (!query && !api?.list) {\n throw new Error(\"useTableCrud requires either query or api.list.\");\n }\n if (!Number.isInteger(batchConcurrency) || batchConcurrency < 1) {\n throw new RangeError(\"batchConcurrency must be an integer greater than 0.\");\n }\n\n const injectedClient = getCurrentInstance() ? useRequestClient(true) : undefined;\n const client = config.client ?? injectedClient;\n const message = config.ui?.message ?? noopMessage;\n const dialog: CrudDialogApi = config.ui?.dialog ?? noopDialog;\n const notify = (\n type: \"success\" | \"error\" | \"warning\",\n text: string,\n ): void => {\n try {\n void Promise.resolve(message[type](text)).catch(() => undefined);\n } catch {\n // Presentation adapters must not alter request outcomes.\n }\n };\n\n const data = shallowRef<T[]>([]);\n const total = ref(0);\n const tableRef = ref<unknown>();\n const paginationEnabled = ref(defaultPaginationEnabled);\n const filters = ref(cloneValue(initialFilters)) as Ref<Filters>;\n const sort = ref(cloneValue(initialSort)) as Ref<Sort | null>;\n const error = shallowRef<RequestError | null>(null);\n const lastUpdated = ref<number | null>(null);\n const page: TablePageState = reactive({\n current: DEFAULT_CONFIG.currentPage,\n size: defaultPageSize,\n });\n const counts = reactive<Record<Operation, number>>({\n refresh: 0,\n detail: 0,\n create: 0,\n update: 0,\n remove: 0,\n });\n const controllers = new Set<AbortController>();\n let refreshController: AbortController | null = null;\n let refreshSequence = 0;\n let disposed = false;\n\n const loading = computed(() => Object.values(counts).some((count) => count > 0));\n const isInitialLoading = computed(\n () => counts.refresh > 0 && lastUpdated.value === null,\n );\n const isRefreshing = computed(\n () => counts.refresh > 0 && lastUpdated.value !== null,\n );\n const creating = computed(() => counts.create > 0);\n const updating = computed(() => counts.update > 0);\n const removing = computed(() => counts.remove > 0);\n\n const startOperation = (operation: Operation): AbortController => {\n counts[operation] += 1;\n const controller = new AbortController();\n controllers.add(controller);\n return controller;\n };\n\n const finishOperation = (\n operation: Operation,\n controller: AbortController,\n ): void => {\n counts[operation] = Math.max(0, counts[operation] - 1);\n controllers.delete(controller);\n };\n\n const reportError = async (\n cause: unknown,\n operation: Operation,\n fallbackMessage: string,\n ): Promise<RequestError> => {\n const normalized = normalizeRequestError(cause);\n if (!isCanceledError(normalized)) {\n error.value = normalized;\n notify(\"error\", fallbackMessage);\n try {\n await config.onError?.(normalized, operation);\n } catch {\n // Error observers must not replace the request failure.\n }\n }\n return normalized;\n };\n\n const detailVisible = ref(false);\n const detailData = ref<T | null>(null) as Ref<T | null>;\n const detailTitleState = ref(\"\");\n const detail = {\n visible: detailVisible,\n data: detailData,\n title: detailTitleState,\n show: (row: T): void => {\n detailData.value = row;\n detailTitleState.value =\n detailTitle?.(row) ??\n `详情 - ${String(\n (row as Record<string, unknown>).name ?? recordValue(row, idKey) ?? \"\",\n )}`;\n detailVisible.value = true;\n },\n close: (): void => {\n detailVisible.value = false;\n detailData.value = null;\n detailTitleState.value = \"\";\n },\n };\n\n const requestList = async (signal: AbortSignal): Promise<unknown> => {\n const context: TableQueryContext<Filters, Sort> = {\n page: page.current,\n pageSize: page.size,\n paginationEnabled: paginationEnabled.value,\n filters: filters.value,\n sort: sort.value,\n signal,\n };\n if (query) {\n return query(context);\n }\n const params =\n typeof listParams === \"function\"\n ? listParams(context)\n : buildListParams(context, listParams);\n return client\n ? client.get(api!.list, { params, signal, concurrency: \"takeLatest\" })\n : getData(api!.list, { params, signal, dedupe: true });\n };\n\n const refresh = async (): Promise<void> => {\n if (disposed) return;\n refreshController?.abort();\n const sequence = ++refreshSequence;\n const controller = startOperation(\"refresh\");\n refreshController = controller;\n error.value = null;\n try {\n const response = await requestList(controller.signal);\n if (sequence !== refreshSequence || controller.signal.aborted) return;\n const extracted =\n extractListData?.(response) ??\n asQueryResult<T>(response) ??\n DataExtractor.extractList<T>(response);\n data.value = [...extracted.items];\n total.value = extracted.total;\n lastUpdated.value = Date.now();\n } catch (cause) {\n if (!controller.signal.aborted) {\n await reportError(cause, \"refresh\", DEFAULT_MESSAGES.loadError);\n }\n } finally {\n if (refreshController === controller) refreshController = null;\n finishOperation(\"refresh\", controller);\n }\n };\n\n const maybeRefresh = async (): Promise<void> => {\n if (refreshAfterMutation) await refresh();\n };\n\n const getDetail = async (row: T): Promise<T | null> => {\n if (!mutations.get && !api?.get) {\n detail.show(row);\n return row;\n }\n const controller = startOperation(\"detail\");\n try {\n let result: T | null;\n if (mutations.get) {\n result = await mutations.get(row, { signal: controller.signal });\n } else {\n const url = UrlUtils.buildUrl(api!.get!, recordValue(row, idKey));\n const response = client\n ? await client.get(url, { signal: controller.signal })\n : await getData(url, { signal: controller.signal });\n result = DataExtractor.extractDetail<T>(response);\n }\n if (result) detail.show(result);\n return result;\n } catch (cause) {\n if (!controller.signal.aborted) {\n await reportError(cause, \"detail\", DEFAULT_MESSAGES.detailError);\n }\n return null;\n } finally {\n finishOperation(\"detail\", controller);\n }\n };\n\n const create = async (row: T): Promise<void> => {\n if (!mutations.create && !api?.create) {\n notify(\"warning\", \"未配置新增操作\");\n return;\n }\n const controller = startOperation(\"create\");\n try {\n if (mutations.create) {\n await mutations.create(row, { signal: controller.signal });\n } else if (client) {\n await client.post(api!.create!, row, { signal: controller.signal });\n } else {\n await postData(api!.create!, row, { signal: controller.signal });\n }\n notify(\"success\", DEFAULT_MESSAGES.createSuccess);\n await maybeRefresh();\n } catch (cause) {\n throw await reportError(cause, \"create\", \"新增失败\");\n } finally {\n finishOperation(\"create\", controller);\n }\n };\n\n const save = async (row: T): Promise<void> => {\n if (!mutations.update && !api?.update) {\n notify(\"warning\", \"未配置更新操作\");\n return;\n }\n const controller = startOperation(\"update\");\n try {\n if (mutations.update) {\n await mutations.update(row, { signal: controller.signal });\n } else {\n const url = UrlUtils.buildUrl(api!.update!, recordValue(row, idKey));\n if (client) await client.put(url, row, { signal: controller.signal });\n else await putData(url, row, { signal: controller.signal });\n }\n notify(\"success\", DEFAULT_MESSAGES.updateSuccess);\n await maybeRefresh();\n } catch (cause) {\n throw await reportError(cause, \"update\", DEFAULT_MESSAGES.saveError);\n } finally {\n finishOperation(\"update\", controller);\n }\n };\n\n const removeOne = async (row: T, signal: AbortSignal): Promise<void> => {\n if (mutations.remove) {\n await mutations.remove(row, { signal });\n return;\n }\n if (!api?.remove) throw new Error(\"Delete operation is not configured.\");\n const url = UrlUtils.buildUrl(api.remove, recordValue(row, idKey));\n if (client) await client.delete(url, { signal });\n else await deleteData(url, { signal });\n };\n\n const removeRowsLocally = (rows: readonly T[]): void => {\n let removed = 0;\n for (const row of rows) {\n if (RowUtils.remove(data.value, idKey, recordValue(row, idKey))) {\n removed += 1;\n }\n }\n if (removed > 0) {\n data.value = [...data.value];\n total.value = Math.max(0, total.value - removed);\n }\n };\n\n const remove = async (row: T): Promise<void> => {\n if (!mutations.remove && !api?.remove) {\n notify(\"warning\", DEFAULT_MESSAGES.noDeleteApi);\n return;\n }\n const controller = startOperation(\"remove\");\n try {\n await removeOne(row, controller.signal);\n notify(\"success\", DEFAULT_MESSAGES.deleteSuccess);\n if (refreshAfterMutation) await refresh();\n else removeRowsLocally([row]);\n } catch (cause) {\n throw await reportError(cause, \"remove\", DEFAULT_MESSAGES.deleteError);\n } finally {\n finishOperation(\"remove\", controller);\n }\n };\n\n const batchRemove = async (rows: T[]): Promise<void> => {\n if (rows.length === 0) {\n notify(\"warning\", \"请选择要删除的数据\");\n return;\n }\n if (!mutations.batchRemove && !mutations.remove && !api?.batchRemove && !api?.remove) {\n notify(\"warning\", DEFAULT_MESSAGES.noDeleteApi);\n return;\n }\n const controller = startOperation(\"remove\");\n try {\n if (mutations.batchRemove) {\n await mutations.batchRemove(rows, { signal: controller.signal });\n } else if (api?.batchRemove) {\n const ids = rows.map((row) => recordValue(row, idKey));\n if (client) {\n await client.post(api.batchRemove, { ids }, { signal: controller.signal });\n } else {\n await postData(api.batchRemove, { ids }, { signal: controller.signal });\n }\n } else {\n let cursor = 0;\n const failures: unknown[] = [];\n const worker = async (): Promise<void> => {\n while (cursor < rows.length && !controller.signal.aborted) {\n const current = rows[cursor++];\n try {\n await removeOne(current, controller.signal);\n } catch (cause) {\n failures.push(cause);\n }\n }\n };\n await Promise.all(\n Array.from({ length: Math.min(batchConcurrency, rows.length) }, worker),\n );\n if (controller.signal.aborted) {\n throw Object.assign(new Error(\"canceled\"), {\n name: \"AbortError\",\n code: \"ERR_CANCELED\",\n });\n }\n if (failures.length > 0) {\n throw new RequestError({\n kind: \"business\",\n message: `${failures.length} delete operation(s) failed.`,\n data: failures,\n });\n }\n }\n notify(\"success\", `成功删除 ${rows.length} 条数据`);\n if (refreshAfterMutation) await refresh();\n else removeRowsLocally(rows);\n } catch (cause) {\n throw await reportError(cause, \"remove\", \"批量删除失败\");\n } finally {\n finishOperation(\"remove\", controller);\n }\n };\n\n const search = async (next?: Partial<Filters>): Promise<void> => {\n if (next) Object.assign(filters.value, next);\n page.current = DEFAULT_CONFIG.currentPage;\n await refresh();\n };\n\n const resetSearch = async (): Promise<void> => {\n filters.value = cloneValue(initialFilters);\n page.current = DEFAULT_CONFIG.currentPage;\n await refresh();\n };\n\n const setSort = async (next: Sort | null): Promise<void> => {\n sort.value = cloneValue(next);\n page.current = DEFAULT_CONFIG.currentPage;\n await refresh();\n };\n\n const handlePaginationChange = (pageNumber: number, pageSize: number): void => {\n page.current = pageNumber;\n page.size = pageSize;\n void refresh();\n };\n\n const handleRowDelete = (row: T): void => {\n removeRowsLocally([row]);\n };\n\n const createActionContext = (index: number): ActionContext<T> => ({\n data: data.value,\n index,\n page,\n paginationEnabled: paginationEnabled.value,\n message,\n dialog,\n refresh,\n });\n\n const actions = computed<TableActions<T>>(() => {\n const result: TableActions<T> = {};\n if (mutations.update || api?.update) {\n result.edit = async (row) => {\n try {\n await save(row);\n return { data: row, error: null };\n } catch (cause) {\n return { data: null, error: normalizeRequestError(cause) };\n }\n };\n }\n if (mutations.remove || api?.remove) {\n result.delete = async (row) => {\n try {\n await remove(row);\n return { data: { success: true }, error: null };\n } catch (cause) {\n return { data: null, error: normalizeRequestError(cause) };\n }\n };\n }\n if (mutations.get || api?.get) {\n result.detail = async (row) => {\n const value = await getDetail(row);\n return { data: value, error: error.value };\n };\n }\n if (customActions.length > 0) {\n result.custom = customActions.map((action) => ({\n key: action.key,\n label: action.label,\n icon: action.icon,\n type: action.type ?? \"default\",\n onClick: (row, index) => action.handler(row, createActionContext(index)),\n }));\n }\n return result;\n });\n\n const pagination = computed(() =>\n paginationEnabled.value\n ? {\n enabled: true as const,\n page: page.current,\n pageSize: page.size,\n itemCount: total.value,\n }\n : false,\n );\n\n const createDraft = (): T => createNewRow?.() ?? ({} as T);\n const cancel = (): void => {\n refreshSequence += 1;\n refreshController?.abort();\n refreshController = null;\n for (const controller of controllers) controller.abort();\n };\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n cancel();\n };\n\n if (getCurrentScope()) onScopeDispose(dispose);\n if (autoLoad === \"mounted\" && getCurrentInstance()) {\n onMounted(() => void refresh());\n } else if (autoLoad === \"mounted\") {\n void refresh();\n }\n else if (autoLoad) void refresh();\n\n return {\n data,\n rows: data,\n loading,\n isInitialLoading,\n isRefreshing,\n creating,\n updating,\n removing,\n total,\n error,\n lastUpdated,\n columns: computed(() => columns),\n actions,\n tableRef,\n page,\n filters,\n sort,\n paginationEnabled,\n pagination,\n refresh,\n reload: refresh,\n search,\n resetSearch,\n setSort,\n create,\n save,\n remove,\n batchRemove,\n getDetail,\n createDraft,\n cancel,\n dispose,\n handleCancel: refresh,\n handlePaginationChange,\n handleRowDelete,\n detail,\n detailConfig,\n };\n}\n"]}
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ var chunkPWK5GFU3_cjs = require('./chunk-PWK5GFU3.cjs');
4
+
5
+ // src/composables/useTableCrud/createTableCrud.ts
6
+ function snapshotListParams(value) {
7
+ return value ? { ...value } : void 0;
8
+ }
9
+ function createTableCrud(defaults = {}) {
10
+ const shared = {
11
+ ...defaults,
12
+ listParams: snapshotListParams(defaults.listParams)
13
+ };
14
+ return (config) => {
15
+ const localListParams = config.listParams;
16
+ const listParams = localListParams && typeof localListParams === "object" ? { ...shared.listParams, ...localListParams } : localListParams ?? shared.listParams;
17
+ return chunkPWK5GFU3_cjs.useTableCrud({
18
+ ...shared,
19
+ ...config,
20
+ listParams
21
+ });
22
+ };
23
+ }
24
+
25
+ exports.createTableCrud = createTableCrud;
26
+ //# sourceMappingURL=chunk-NCTU7EUD.cjs.map
27
+ //# sourceMappingURL=chunk-NCTU7EUD.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/composables/useTableCrud/createTableCrud.ts"],"names":["useTableCrud"],"mappings":";;;;;AAUA,SAAS,mBACP,KAAA,EACgC;AAChC,EAAA,OAAO,KAAA,GAAQ,EAAE,GAAG,KAAA,EAAM,GAAI,MAAA;AAChC;AAMO,SAAS,eAAA,CACd,QAAA,GAA8B,EAAC,EACb;AAClB,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,GAAG,QAAA;AAAA,IACH,UAAA,EAAY,kBAAA,CAAmB,QAAA,CAAS,UAAU;AAAA,GACpD;AAEA,EAAA,OAAO,CAKL,MAAA,KACyC;AACzC,IAAA,MAAM,kBAAkB,MAAA,CAAO,UAAA;AAC/B,IAAA,MAAM,UAAA,GACJ,eAAA,IAAmB,OAAO,eAAA,KAAoB,QAAA,GAC1C,EAAE,GAAG,MAAA,CAAO,UAAA,EAAY,GAAG,eAAA,EAAgB,GAC1C,mBAAmB,MAAA,CAAO,UAAA;AAEjC,IAAA,OAAOA,8BAAA,CAA+B;AAAA,MACpC,GAAG,MAAA;AAAA,MACH,GAAG,MAAA;AAAA,MACH;AAAA,KACD,CAAA;AAAA,EACH,CAAA;AACF","file":"chunk-NCTU7EUD.cjs","sourcesContent":["import { useTableCrud } from \"./useTableCrud\";\nimport type {\n DataRecord,\n TableCrudDefaults,\n TableCrudFactory,\n TableListParamKeys,\n UseTableCrudConfig,\n UseTableCrudReturn,\n} from \"./types\";\n\nfunction snapshotListParams(\n value: TableListParamKeys | undefined,\n): TableListParamKeys | undefined {\n return value ? { ...value } : undefined;\n}\n\n/**\n * Creates a typed table composable with application-level defaults. Each call\n * still owns isolated reactive state and can override every shared default.\n */\nexport function createTableCrud(\n defaults: TableCrudDefaults = {},\n): TableCrudFactory {\n const shared = {\n ...defaults,\n listParams: snapshotListParams(defaults.listParams),\n };\n\n return <\n T extends DataRecord,\n Filters extends object = Record<string, unknown>,\n Sort extends object = Record<string, unknown>,\n >(\n config: UseTableCrudConfig<T, Filters, Sort>,\n ): UseTableCrudReturn<T, Filters, Sort> => {\n const localListParams = config.listParams;\n const listParams =\n localListParams && typeof localListParams === \"object\"\n ? { ...shared.listParams, ...localListParams }\n : (localListParams ?? shared.listParams);\n\n return useTableCrud<T, Filters, Sort>({\n ...shared,\n ...config,\n listParams,\n });\n };\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import { useTableCrud } from './chunk-ICWJ3KIS.js';
2
+
3
+ // src/composables/useTableCrud/createTableCrud.ts
4
+ function snapshotListParams(value) {
5
+ return value ? { ...value } : void 0;
6
+ }
7
+ function createTableCrud(defaults = {}) {
8
+ const shared = {
9
+ ...defaults,
10
+ listParams: snapshotListParams(defaults.listParams)
11
+ };
12
+ return (config) => {
13
+ const localListParams = config.listParams;
14
+ const listParams = localListParams && typeof localListParams === "object" ? { ...shared.listParams, ...localListParams } : localListParams ?? shared.listParams;
15
+ return useTableCrud({
16
+ ...shared,
17
+ ...config,
18
+ listParams
19
+ });
20
+ };
21
+ }
22
+
23
+ export { createTableCrud };
24
+ //# sourceMappingURL=chunk-ONOINBRA.js.map
25
+ //# sourceMappingURL=chunk-ONOINBRA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/composables/useTableCrud/createTableCrud.ts"],"names":[],"mappings":";;;AAUA,SAAS,mBACP,KAAA,EACgC;AAChC,EAAA,OAAO,KAAA,GAAQ,EAAE,GAAG,KAAA,EAAM,GAAI,MAAA;AAChC;AAMO,SAAS,eAAA,CACd,QAAA,GAA8B,EAAC,EACb;AAClB,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,GAAG,QAAA;AAAA,IACH,UAAA,EAAY,kBAAA,CAAmB,QAAA,CAAS,UAAU;AAAA,GACpD;AAEA,EAAA,OAAO,CAKL,MAAA,KACyC;AACzC,IAAA,MAAM,kBAAkB,MAAA,CAAO,UAAA;AAC/B,IAAA,MAAM,UAAA,GACJ,eAAA,IAAmB,OAAO,eAAA,KAAoB,QAAA,GAC1C,EAAE,GAAG,MAAA,CAAO,UAAA,EAAY,GAAG,eAAA,EAAgB,GAC1C,mBAAmB,MAAA,CAAO,UAAA;AAEjC,IAAA,OAAO,YAAA,CAA+B;AAAA,MACpC,GAAG,MAAA;AAAA,MACH,GAAG,MAAA;AAAA,MACH;AAAA,KACD,CAAA;AAAA,EACH,CAAA;AACF","file":"chunk-ONOINBRA.js","sourcesContent":["import { useTableCrud } from \"./useTableCrud\";\nimport type {\n DataRecord,\n TableCrudDefaults,\n TableCrudFactory,\n TableListParamKeys,\n UseTableCrudConfig,\n UseTableCrudReturn,\n} from \"./types\";\n\nfunction snapshotListParams(\n value: TableListParamKeys | undefined,\n): TableListParamKeys | undefined {\n return value ? { ...value } : undefined;\n}\n\n/**\n * Creates a typed table composable with application-level defaults. Each call\n * still owns isolated reactive state and can override every shared default.\n */\nexport function createTableCrud(\n defaults: TableCrudDefaults = {},\n): TableCrudFactory {\n const shared = {\n ...defaults,\n listParams: snapshotListParams(defaults.listParams),\n };\n\n return <\n T extends DataRecord,\n Filters extends object = Record<string, unknown>,\n Sort extends object = Record<string, unknown>,\n >(\n config: UseTableCrudConfig<T, Filters, Sort>,\n ): UseTableCrudReturn<T, Filters, Sort> => {\n const localListParams = config.listParams;\n const listParams =\n localListParams && typeof localListParams === \"object\"\n ? { ...shared.listParams, ...localListParams }\n : (localListParams ?? shared.listParams);\n\n return useTableCrud<T, Filters, Sort>({\n ...shared,\n ...config,\n listParams,\n });\n };\n}\n"]}
@@ -246,9 +246,33 @@ function asQueryResult(value) {
246
246
  const candidate = value;
247
247
  return Array.isArray(candidate.items) && Number.isFinite(candidate.total) ? { items: candidate.items, total: Number(candidate.total) } : null;
248
248
  }
249
+ function resolveParamKey(value, fallback) {
250
+ if (value === false) return false;
251
+ if (value === void 0) return fallback;
252
+ if (value.trim().length === 0) {
253
+ throw new RangeError("List parameter keys cannot be empty strings.");
254
+ }
255
+ return value;
256
+ }
257
+ function buildListParams(context, keys = {}) {
258
+ const pageKey = resolveParamKey(keys.page, "page");
259
+ const pageSizeKey = resolveParamKey(keys.pageSize, "pageSize");
260
+ const sortKey = resolveParamKey(keys.sort, "sort");
261
+ const paginationParams = {};
262
+ if (context.paginationEnabled) {
263
+ if (pageKey !== false) paginationParams[pageKey] = context.page;
264
+ if (pageSizeKey !== false) paginationParams[pageSizeKey] = context.pageSize;
265
+ }
266
+ return {
267
+ ...paginationParams,
268
+ ...context.filters,
269
+ ...context.sort && sortKey !== false ? { [sortKey]: context.sort } : {}
270
+ };
271
+ }
249
272
  function useTableCrud(config) {
250
273
  const {
251
274
  api,
275
+ listParams,
252
276
  query,
253
277
  mutations = {},
254
278
  columns = [],
@@ -358,22 +382,18 @@ function useTableCrud(config) {
358
382
  }
359
383
  };
360
384
  const requestList = async (signal) => {
361
- if (query) {
362
- return query({
363
- page: page.current,
364
- pageSize: page.size,
365
- paginationEnabled: paginationEnabled.value,
366
- filters: filters.value,
367
- sort: sort.value,
368
- signal
369
- });
370
- }
371
- const paginationParams = paginationEnabled.value ? { page: page.current, pageSize: page.size } : {};
372
- const params = {
373
- ...paginationParams,
374
- ...filters.value,
375
- ...sort.value ? { sort: sort.value } : {}
385
+ const context = {
386
+ page: page.current,
387
+ pageSize: page.size,
388
+ paginationEnabled: paginationEnabled.value,
389
+ filters: filters.value,
390
+ sort: sort.value,
391
+ signal
376
392
  };
393
+ if (query) {
394
+ return query(context);
395
+ }
396
+ const params = typeof listParams === "function" ? listParams(context) : buildListParams(context, listParams);
377
397
  return client ? client.get(api.list, { params, signal, concurrency: "takeLatest" }) : chunkJGFRUAZT_cjs.getData(api.list, { params, signal, dedupe: true });
378
398
  };
379
399
  const refresh = async () => {
@@ -713,5 +733,5 @@ exports.createRequestPlugin = createRequestPlugin;
713
733
  exports.provideRequestClient = provideRequestClient;
714
734
  exports.useRequestClient = useRequestClient;
715
735
  exports.useTableCrud = useTableCrud;
716
- //# sourceMappingURL=chunk-KHI6XQRN.cjs.map
717
- //# sourceMappingURL=chunk-KHI6XQRN.cjs.map
736
+ //# sourceMappingURL=chunk-PWK5GFU3.cjs.map
737
+ //# sourceMappingURL=chunk-PWK5GFU3.cjs.map