z-crud-table 0.0.23 → 0.0.25

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.
@@ -140,6 +140,15 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
140
140
  type: ObjectConstructor;
141
141
  default: () => {};
142
142
  };
143
+ /**
144
+ * @description 是否以 multipart/form-data 格式提交表单。
145
+ * 适用于需要上传文件的场景。
146
+ * @type {Boolean}
147
+ */
148
+ submitAsFormData: {
149
+ type: BooleanConstructor;
150
+ default: boolean;
151
+ };
143
152
  }>, {
144
153
  refresh: () => Promise<void>;
145
154
  search: () => void;
@@ -290,6 +299,15 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
290
299
  type: ObjectConstructor;
291
300
  default: () => {};
292
301
  };
302
+ /**
303
+ * @description 是否以 multipart/form-data 格式提交表单。
304
+ * 适用于需要上传文件的场景。
305
+ * @type {Boolean}
306
+ */
307
+ submitAsFormData: {
308
+ type: BooleanConstructor;
309
+ default: boolean;
310
+ };
293
311
  }>> & Readonly<{
294
312
  onSubmit?: ((...args: any[]) => any) | undefined;
295
313
  onDelete?: ((...args: any[]) => any) | undefined;
@@ -317,6 +335,7 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
317
335
  paginationHideOnSinglePage: boolean;
318
336
  dialogFormConfig: any[];
319
337
  dialogFormRules: Record<string, any>;
338
+ submitAsFormData: boolean;
320
339
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>, Partial<Record<any, (_: {
321
340
  row: any;
322
341
  }) => any>> & {
@@ -1,83 +1,83 @@
1
- import { defineComponent as H, ref as F, resolveComponent as g, createBlock as p, openBlock as n, mergeProps as _, withCtx as u, createElementBlock as b, Fragment as V, renderList as q, createCommentVNode as m, createTextVNode as v, toDisplayString as re, computed as j, reactive as T, onMounted as ne, resolveDirective as ie, normalizeClass as se, renderSlot as y, withDirectives as W, createVNode as w, createElementVNode as E, createSlots as ue } from "vue";
2
- import { ElMessage as $ } from "element-plus";
1
+ import { defineComponent as G, ref as O, resolveComponent as g, createBlock as f, openBlock as n, mergeProps as D, withCtx as u, createElementBlock as w, Fragment as $, renderList as q, createCommentVNode as c, createTextVNode as C, toDisplayString as re, computed as j, reactive as H, onMounted as ne, resolveDirective as ie, normalizeClass as se, renderSlot as b, withDirectives as M, createVNode as v, createElementVNode as I, createSlots as ue } from "vue";
2
+ import { ElMessage as k } from "element-plus";
3
3
  import de from "axios";
4
- const pe = /* @__PURE__ */ H({
4
+ const pe = /* @__PURE__ */ G({
5
5
  __name: "DynamicForm",
6
6
  props: {
7
7
  modelValue: {},
8
8
  formConfig: {},
9
9
  rules: {}
10
10
  },
11
- setup(c, { expose: k }) {
12
- const z = F(null);
13
- return k({
11
+ setup(y, { expose: B }) {
12
+ const N = O(null);
13
+ return B({
14
14
  validate: () => {
15
15
  var s;
16
- return (s = z.value) == null ? void 0 : s.validate();
16
+ return (s = N.value) == null ? void 0 : s.validate();
17
17
  }
18
18
  }), (s, e) => {
19
- const A = g("el-input"), Q = g("el-option"), S = g("el-select"), N = g("el-radio"), f = g("el-radio-group"), D = g("el-form-item"), B = g("el-form");
20
- return n(), p(B, _({
19
+ const z = g("el-input"), Q = g("el-option"), h = g("el-select"), x = g("el-radio"), m = g("el-radio-group"), V = g("el-form-item"), A = g("el-form");
20
+ return n(), f(A, D({
21
21
  model: s.modelValue,
22
22
  rules: s.rules,
23
23
  ref_key: "formRef",
24
- ref: z
24
+ ref: N
25
25
  }, s.$attrs), {
26
26
  default: u(() => [
27
- (n(!0), b(V, null, q(s.formConfig, (r) => (n(), p(D, {
27
+ (n(!0), w($, null, q(s.formConfig, (r) => (n(), f(V, {
28
28
  key: r.prop,
29
29
  label: r.label,
30
30
  prop: r.prop
31
31
  }, {
32
32
  default: u(() => [
33
- r.type === "input" ? (n(), p(A, _({
33
+ r.type === "input" ? (n(), f(z, D({
34
34
  key: 0,
35
35
  modelValue: s.modelValue[r.prop],
36
36
  "onUpdate:modelValue": (d) => s.modelValue[r.prop] = d
37
- }, { ref_for: !0 }, r.componentProps), null, 16, ["modelValue", "onUpdate:modelValue"])) : m("", !0),
38
- r.type === "textarea" ? (n(), p(A, _({
37
+ }, { ref_for: !0 }, r.componentProps), null, 16, ["modelValue", "onUpdate:modelValue"])) : c("", !0),
38
+ r.type === "textarea" ? (n(), f(z, D({
39
39
  key: 1,
40
40
  type: "textarea",
41
41
  modelValue: s.modelValue[r.prop],
42
42
  "onUpdate:modelValue": (d) => s.modelValue[r.prop] = d
43
- }, { ref_for: !0 }, r.componentProps), null, 16, ["modelValue", "onUpdate:modelValue"])) : m("", !0),
44
- r.type === "select" ? (n(), p(S, _({
43
+ }, { ref_for: !0 }, r.componentProps), null, 16, ["modelValue", "onUpdate:modelValue"])) : c("", !0),
44
+ r.type === "select" ? (n(), f(h, D({
45
45
  key: 2,
46
46
  modelValue: s.modelValue[r.prop],
47
47
  "onUpdate:modelValue": (d) => s.modelValue[r.prop] = d
48
48
  }, { ref_for: !0 }, r.componentProps), {
49
49
  default: u(() => [
50
- (n(!0), b(V, null, q(r.options, (d) => (n(), p(Q, {
50
+ (n(!0), w($, null, q(r.options, (d) => (n(), f(Q, {
51
51
  key: d.value,
52
52
  label: d.label,
53
53
  value: d.value
54
54
  }, null, 8, ["label", "value"]))), 128))
55
55
  ]),
56
56
  _: 2
57
- }, 1040, ["modelValue", "onUpdate:modelValue"])) : m("", !0),
58
- r.type === "radio-group" ? (n(), p(f, _({
57
+ }, 1040, ["modelValue", "onUpdate:modelValue"])) : c("", !0),
58
+ r.type === "radio-group" ? (n(), f(m, D({
59
59
  key: 3,
60
60
  modelValue: s.modelValue[r.prop],
61
61
  "onUpdate:modelValue": (d) => s.modelValue[r.prop] = d
62
62
  }, { ref_for: !0 }, r.componentProps), {
63
63
  default: u(() => [
64
- (n(!0), b(V, null, q(r.options, (d) => (n(), p(N, {
64
+ (n(!0), w($, null, q(r.options, (d) => (n(), f(x, {
65
65
  key: d.value,
66
66
  label: d.value
67
67
  }, {
68
68
  default: u(() => [
69
- v(re(d.label), 1)
69
+ C(re(d.label), 1)
70
70
  ]),
71
71
  _: 2
72
72
  }, 1032, ["label"]))), 128))
73
73
  ]),
74
74
  _: 2
75
- }, 1040, ["modelValue", "onUpdate:modelValue"])) : m("", !0),
76
- r.type === "input-disabled" ? (n(), p(A, _({
75
+ }, 1040, ["modelValue", "onUpdate:modelValue"])) : c("", !0),
76
+ r.type === "input-disabled" ? (n(), f(z, D({
77
77
  key: 4,
78
78
  "model-value": s.modelValue[r.prop],
79
79
  disabled: ""
80
- }, { ref_for: !0 }, r.componentProps), null, 16, ["model-value"])) : m("", !0)
80
+ }, { ref_for: !0 }, r.componentProps), null, 16, ["model-value"])) : c("", !0)
81
81
  ]),
82
82
  _: 2
83
83
  }, 1032, ["label", "prop"]))), 128))
@@ -86,39 +86,39 @@ const pe = /* @__PURE__ */ H({
86
86
  }, 16, ["model", "rules"]);
87
87
  };
88
88
  }
89
- }), C = de.create({
89
+ }), S = de.create({
90
90
  // VITE_APP_BASE_API 是在 .env 文件中定义的基础 URL
91
91
  // 您可以根据您的项目需求进行修改
92
92
  baseURL: "",
93
93
  timeout: 1e4
94
94
  // 请求超时时间
95
95
  });
96
- C.interceptors.request.use(
97
- (c) => {
98
- const k = localStorage.getItem("token");
99
- return k && (c.headers.Authorization = "Bearer " + k), c;
96
+ S.interceptors.request.use(
97
+ (y) => {
98
+ const B = localStorage.getItem("token");
99
+ return B && (y.headers.Authorization = "Bearer " + B), y;
100
100
  },
101
- (c) => (console.log(c), Promise.reject(c))
101
+ (y) => (console.log(y), Promise.reject(y))
102
102
  );
103
- C.interceptors.response.use(
104
- (c) => c.data,
105
- (c) => (console.log("err" + c), $({
103
+ S.interceptors.response.use(
104
+ (y) => y.data,
105
+ (y) => (console.log("err" + y), k({
106
106
  message: "接口错误,请刷新接口",
107
107
  // 这里是您要求的统一错误提示
108
108
  type: "error",
109
109
  duration: 5 * 1e3
110
- }), Promise.reject(c))
110
+ }), Promise.reject(y))
111
111
  );
112
112
  const fe = {
113
113
  key: 0,
114
114
  class: "flex flex-wrap items-center justify-between gap-4 mb-6"
115
- }, me = { class: "flex items-center gap-x-2" }, ge = { class: "flex items-center gap-x-3 action-buttons flex-shrink-0" }, ce = {
115
+ }, me = { class: "flex items-center gap-x-2" }, ce = { class: "flex items-center gap-x-3 action-buttons flex-shrink-0" }, ge = {
116
116
  key: 0,
117
117
  class: "flex items-center gap-x-2"
118
118
  }, ye = {
119
119
  key: 1,
120
120
  class: "flex justify-end"
121
- }, be = { class: "dialog-footer" }, _e = /* @__PURE__ */ H({
121
+ }, be = { class: "dialog-footer" }, Se = /* @__PURE__ */ G({
122
122
  __name: "CrudTable",
123
123
  props: {
124
124
  /**
@@ -171,42 +171,59 @@ const fe = {
171
171
  paginationHideOnSinglePage: { type: Boolean, default: !1 },
172
172
  // 弹窗表单配置
173
173
  dialogFormConfig: { type: Array, default: () => [] },
174
- dialogFormRules: { type: Object, default: () => ({}) }
174
+ dialogFormRules: { type: Object, default: () => ({}) },
175
+ /**
176
+ * @description 是否以 multipart/form-data 格式提交表单。
177
+ * 适用于需要上传文件的场景。
178
+ * @type {Boolean}
179
+ */
180
+ submitAsFormData: { type: Boolean, default: !1 }
175
181
  },
176
182
  emits: ["open-dialog", "submit", "delete"],
177
- setup(c, { expose: k, emit: z }) {
178
- const s = z, e = c, A = j(() => ["crud-table-wrapper", `theme-${e.theme}`, e.customClass]), Q = j(() => e.theme === "large-screen" ? "large-screen-dialog" : ""), S = (t, o) => t ? !0 : ($.error(`${o} prop is required.`), !1), N = async (t, o) => {
183
+ setup(y, { expose: B, emit: N }) {
184
+ const s = N, e = y, z = j(() => ["crud-table-wrapper", `theme-${e.theme}`, e.customClass]), Q = j(() => e.theme === "large-screen" ? "large-screen-dialog" : ""), h = (t, o) => t ? !0 : (k.error(`${o} prop is required.`), !1), x = async (t, o) => {
179
185
  try {
180
186
  let a = { ...o };
181
- if (e.onBeforeSubmit && (a = await e.onBeforeSubmit(a)), l.submitting = !0, t === "add") {
182
- if (!S(e.apiUrlCreate, "apiUrlCreate")) return;
183
- await C.post(e.apiUrlCreate, a), $.success("新增成功");
187
+ e.onBeforeSubmit && (a = await e.onBeforeSubmit(a));
188
+ let p = a;
189
+ if (e.submitAsFormData) {
190
+ const F = new FormData();
191
+ for (const _ in a)
192
+ if (Object.prototype.hasOwnProperty.call(a, _)) {
193
+ const E = a[_];
194
+ F.append(_, E ?? "");
195
+ }
196
+ p = F;
197
+ }
198
+ if (l.submitting = !0, t === "add") {
199
+ if (!h(e.apiUrlCreate, "apiUrlCreate")) throw new Error("apiUrlCreate is not configured.");
200
+ await S.post(e.apiUrlCreate, p), k.success("新增成功");
184
201
  } else {
185
- if (!S(e.apiUrlUpdate, "apiUrlUpdate")) return;
186
- await C.put(e.apiUrlUpdate, a), $.success("更新成功");
202
+ if (!h(e.apiUrlUpdate, "apiUrlUpdate")) throw new Error("apiUrlUpdate is not configured.");
203
+ await S.put(e.apiUrlUpdate, p), k.success("更新成功");
187
204
  }
188
205
  return e.onAfterSubmit && e.onAfterSubmit(t, a), s("submit", { mode: t, data: a }), l.visible && (l.visible = !1), U(), Promise.resolve();
189
206
  } catch (a) {
190
- return console.log("Submit error:", a), Promise.reject(a);
207
+ return console.error("Submit failed:", a), Promise.reject(a);
191
208
  } finally {
192
209
  l.submitting = !1;
193
210
  }
194
- }, f = T({ pageNum: 1, pageSize: 10, ...e.initialSearchForm }), D = F([]), B = F(0), r = F(!1), d = F([]), l = T({ visible: !1, loading: !1, submitting: !1, mode: "add", data: {}, formRef: null }), M = j(() => l.mode === "add" ? "新增" : "编辑"), G = j(() => {
211
+ }, m = H({ pageNum: 1, pageSize: 10, ...e.initialSearchForm }), V = O([]), A = O(0), r = O(!1), d = O([]), l = H({ visible: !1, loading: !1, submitting: !1, mode: "add", data: {}, formRef: null }), J = j(() => l.mode === "add" ? "新增" : "编辑"), K = j(() => {
195
212
  if (l.mode === "add") return e.dialogFormConfig.filter((o) => o.prop !== "id");
196
213
  const t = [...e.dialogFormConfig.filter((o) => o.prop !== "id")];
197
214
  return t.some((o) => o.prop === "id") || t.unshift({ type: "input-disabled", prop: "id", label: "用户ID" }), t;
198
215
  }), U = async () => {
199
- if (S(e.apiUrlQuery, "apiUrlQuery")) {
216
+ if (h(e.apiUrlQuery, "apiUrlQuery")) {
200
217
  r.value = !0;
201
218
  try {
202
- let t = { ...f };
219
+ let t = { ...m };
203
220
  e.onBeforeQuery && (t = await e.onBeforeQuery(t));
204
- const o = await C.get(e.apiUrlQuery, { params: t });
221
+ const o = await S.get(e.apiUrlQuery, { params: t });
205
222
  if (o && o.data && Array.isArray(o.data.rows) && typeof o.data.total == "number") {
206
223
  let a = o.data.rows;
207
- e.onAfterQuery && (a = await e.onAfterQuery(a)), D.value = a, B.value = o.data.total;
224
+ e.onAfterQuery && (a = await e.onAfterQuery(a)), V.value = a, A.value = o.data.total;
208
225
  } else
209
- console.warn("API response is not in the expected { data: { rows: [], total: 0 } } format."), D.value = [], B.value = 0;
226
+ console.warn("API response is not in the expected { data: { rows: [], total: 0 } } format."), V.value = [], A.value = 0;
210
227
  } catch (t) {
211
228
  console.error("Fetch data failed:", t);
212
229
  } finally {
@@ -214,102 +231,125 @@ const fe = {
214
231
  }
215
232
  }
216
233
  }, P = () => {
217
- f.pageNum = 1, U();
218
- }, J = () => {
234
+ m.pageNum = 1, U();
235
+ }, X = () => {
219
236
  const { pageNum: t, pageSize: o, ...a } = e.initialSearchForm;
220
- Object.keys(f).forEach((h) => {
221
- h !== "pageNum" && h !== "pageSize" && delete f[h];
222
- }), Object.assign(f, a), P();
223
- }, K = (t) => {
237
+ Object.keys(m).forEach((p) => {
238
+ p !== "pageNum" && p !== "pageSize" && delete m[p];
239
+ }), Object.assign(m, a), P();
240
+ }, Y = (t) => {
224
241
  d.value = t;
225
- }, x = async (t, o) => {
242
+ }, R = async (t, o) => {
226
243
  let a;
227
244
  if (t === "add" ? a = o ? { ...o } : { role: "user" } : a = { ...o }, e.onBeforeOpenDialog) {
228
- const h = await e.onBeforeOpenDialog(t, a);
229
- h && (a = h);
245
+ const p = await e.onBeforeOpenDialog(t, a);
246
+ p && (a = p);
230
247
  }
231
248
  if (l.mode = t, l.visible = !0, t === "edit") {
232
- if (!S(e.apiUrlDetail, "apiUrlDetail")) return;
249
+ if (!h(e.apiUrlDetail, "apiUrlDetail")) return;
233
250
  l.loading = !0;
234
251
  try {
235
- const h = await C.get(e.apiUrlDetail + "/" + a.id.toString());
236
- l.data = h.data.data;
252
+ const p = await S.get(e.apiUrlDetail + "/" + a.id.toString());
253
+ l.data = p.data.data;
237
254
  } finally {
238
255
  l.loading = !1, e.onAfterOpenDialog && e.onAfterOpenDialog(t, l.data), s("open-dialog", { mode: t, data: l.data });
239
256
  }
240
257
  } else
241
258
  l.data = a, e.onAfterOpenDialog && e.onAfterOpenDialog(t, l.data), s("open-dialog", { mode: t, data: l.data });
242
- }, X = async () => {
259
+ }, Z = async () => {
243
260
  try {
244
- l.formRef && await l.formRef.validate(), await N(l.mode, l.data);
261
+ l.formRef && await l.formRef.validate();
262
+ let t = { ...l.data };
263
+ e.onBeforeSubmit && (t = await e.onBeforeSubmit(t));
264
+ let o = t;
265
+ if (e.submitAsFormData) {
266
+ const a = new FormData();
267
+ for (const p in t)
268
+ if (Object.prototype.hasOwnProperty.call(t, p)) {
269
+ const F = t[p];
270
+ a.append(p, F ?? "");
271
+ }
272
+ o = a;
273
+ debugger;
274
+ }
275
+ if (l.submitting = !0, l.mode === "add") {
276
+ if (!h(e.apiUrlCreate, "apiUrlCreate")) return;
277
+ await S.post(e.apiUrlCreate, o), k.success("新增成功");
278
+ } else {
279
+ if (!h(e.apiUrlUpdate, "apiUrlUpdate")) return;
280
+ await S.put(e.apiUrlUpdate, o), k.success("更新成功");
281
+ }
282
+ e.onAfterSubmit && e.onAfterSubmit(l.mode, t), s("submit", { mode: l.mode, data: t }), l.visible = !1, U();
245
283
  } catch (t) {
246
- console.log("Validation failed:", t);
284
+ console.log("Submit error or validation failed:", t);
285
+ } finally {
286
+ l.submitting = !1;
247
287
  }
248
- }, I = async (t) => {
249
- if (S(e.apiUrlDelete, "apiUrlDelete"))
288
+ }, L = async (t) => {
289
+ if (h(e.apiUrlDelete, "apiUrlDelete"))
250
290
  try {
251
291
  if (e.onBeforeDelete && await e.onBeforeDelete(t) === !1)
252
292
  return;
253
293
  const o = t.join(",");
254
- await C.delete(e.apiUrlDelete + "/" + o.toString()), $.success("删除成功"), e.onAfterDelete && e.onAfterDelete(t), s("delete", t), D.value.length === t.length && f.pageNum > 1 && f.pageNum--, U();
294
+ await S.delete(e.apiUrlDelete + "/" + o.toString()), k.success("删除成功"), e.onAfterDelete && e.onAfterDelete(t), s("delete", t), V.value.length === t.length && m.pageNum > 1 && m.pageNum--, U();
255
295
  } catch (o) {
256
296
  console.error("Delete failed", o);
257
297
  }
258
- }, Y = (t) => {
259
- f.pageSize = t, P();
260
- }, Z = (t) => {
261
- f.pageNum = t, U();
298
+ }, ee = (t) => {
299
+ m.pageSize = t, P();
300
+ }, te = (t) => {
301
+ m.pageNum = t, U();
262
302
  };
263
- return ne(U), k({
303
+ return ne(U), B({
264
304
  refresh: U,
265
305
  // 刷新表格
266
306
  search: P,
267
307
  // 按当前条件搜索
268
- handleDelete: I,
308
+ handleDelete: L,
269
309
  // 手动触发删除
270
- openDialog: x,
310
+ openDialog: R,
271
311
  // 手动打开弹窗
272
- submit: N
312
+ submit: x
273
313
  // 手动提交
274
314
  }), (t, o) => {
275
- const a = g("el-button"), h = g("el-form-item"), ee = g("el-form"), O = g("el-table-column"), te = g("el-popconfirm"), oe = g("el-table"), ae = g("el-pagination"), le = g("el-dialog"), L = ie("loading");
276
- return n(), b("div", {
277
- class: se(A.value)
315
+ const a = g("el-button"), p = g("el-form-item"), F = g("el-form"), _ = g("el-table-column"), E = g("el-popconfirm"), oe = g("el-table"), ae = g("el-pagination"), le = g("el-dialog"), W = ie("loading");
316
+ return n(), w("div", {
317
+ class: se(z.value)
278
318
  }, [
279
- y(t.$slots, "header"),
280
- e.showSearchSection ? (n(), b("div", fe, [
281
- w(ee, {
282
- model: f,
319
+ b(t.$slots, "header"),
320
+ e.showSearchSection ? (n(), w("div", fe, [
321
+ v(F, {
322
+ model: m,
283
323
  class: "query-form flex flex-nowrap items-center gap-x-4",
284
324
  style: { "overflow-x": "auto", "padding-bottom": "8px" }
285
325
  }, {
286
326
  default: u(() => [
287
- y(t.$slots, "query-conditions", { searchForm: f }),
288
- w(h, { class: "!mr-0 flex-shrink-0" }, {
327
+ b(t.$slots, "query-conditions", { searchForm: m }),
328
+ v(p, { class: "!mr-0 flex-shrink-0" }, {
289
329
  default: u(() => [
290
- E("div", me, [
291
- y(t.$slots, "query-left"),
292
- e.showSearchActionButtons ? (n(), b(V, { key: 0 }, [
293
- w(a, {
330
+ I("div", me, [
331
+ b(t.$slots, "query-left"),
332
+ e.showSearchActionButtons ? (n(), w($, { key: 0 }, [
333
+ v(a, {
294
334
  type: "primary",
295
335
  onClick: P,
296
336
  loading: r.value
297
337
  }, {
298
338
  default: u(() => o[6] || (o[6] = [
299
- v("搜索")
339
+ C("搜索")
300
340
  ])),
301
341
  _: 1,
302
342
  __: [6]
303
343
  }, 8, ["loading"]),
304
- w(a, { onClick: J }, {
344
+ v(a, { onClick: X }, {
305
345
  default: u(() => o[7] || (o[7] = [
306
- v("清空")
346
+ C("清空")
307
347
  ])),
308
348
  _: 1,
309
349
  __: [7]
310
350
  })
311
- ], 64)) : m("", !0),
312
- y(t.$slots, "query-right")
351
+ ], 64)) : c("", !0),
352
+ b(t.$slots, "query-right")
313
353
  ])
314
354
  ]),
315
355
  _: 3
@@ -317,43 +357,43 @@ const fe = {
317
357
  ]),
318
358
  _: 3
319
359
  }, 8, ["model"]),
320
- E("div", ge, [
321
- y(t.$slots, "action-left", { selections: d.value }),
322
- y(t.$slots, "add-button-content", {}, () => [
323
- e.showNewBtn ? (n(), p(a, {
360
+ I("div", ce, [
361
+ b(t.$slots, "action-left", { selections: d.value }),
362
+ b(t.$slots, "add-button-content", {}, () => [
363
+ e.showNewBtn ? (n(), f(a, {
324
364
  key: 0,
325
365
  type: "success",
326
- onClick: o[0] || (o[0] = (i) => x("add"))
366
+ onClick: o[0] || (o[0] = (i) => R("add"))
327
367
  }, {
328
368
  default: u(() => o[8] || (o[8] = [
329
- v("新增")
369
+ C("新增")
330
370
  ])),
331
371
  _: 1,
332
372
  __: [8]
333
- })) : m("", !0)
373
+ })) : c("", !0)
334
374
  ]),
335
- y(t.$slots, "action-right")
375
+ b(t.$slots, "action-right")
336
376
  ])
337
- ])) : m("", !0),
338
- W((n(), p(oe, _({
339
- data: D.value,
340
- onSelectionChange: K
377
+ ])) : c("", !0),
378
+ M((n(), f(oe, D({
379
+ data: V.value,
380
+ onSelectionChange: Y
341
381
  }, t.$attrs, { style: { width: "100%", "margin-bottom": "1.5rem" } }), {
342
382
  default: u(() => [
343
- e.showSelectionColumn ? (n(), p(O, {
383
+ e.showSelectionColumn ? (n(), f(_, {
344
384
  key: 0,
345
385
  type: "selection",
346
386
  width: "55",
347
387
  fixed: ""
348
- })) : m("", !0),
349
- e.showIndexColumn ? (n(), p(O, {
388
+ })) : c("", !0),
389
+ e.showIndexColumn ? (n(), f(_, {
350
390
  key: 1,
351
391
  type: "index",
352
392
  label: "序号",
353
393
  width: "70",
354
394
  fixed: ""
355
- })) : m("", !0),
356
- (n(!0), b(V, null, q(e.columns, (i) => (n(), p(O, _({
395
+ })) : c("", !0),
396
+ (n(!0), w($, null, q(e.columns, (i) => (n(), f(_, D({
357
397
  key: i.prop,
358
398
  prop: i.prop,
359
399
  label: i.label,
@@ -362,119 +402,119 @@ const fe = {
362
402
  }, { ref_for: !0 }, i.attrs), ue({ _: 2 }, [
363
403
  i.slot ? {
364
404
  name: "default",
365
- fn: u((R) => [
366
- y(t.$slots, i.slot, {
367
- row: R.row
405
+ fn: u((T) => [
406
+ b(t.$slots, i.slot, {
407
+ row: T.row
368
408
  })
369
409
  ]),
370
410
  key: "0"
371
411
  } : void 0
372
412
  ]), 1040, ["prop", "label", "width", "sortable"]))), 128)),
373
- e.showActionsColumn ? (n(), p(O, {
413
+ e.showActionsColumn ? (n(), f(_, {
374
414
  key: 2,
375
415
  label: "操作",
376
- width: c.actionsColumnWidth
416
+ width: y.actionsColumnWidth
377
417
  }, {
378
418
  default: u((i) => [
379
- i.row ? (n(), b("div", ce, [
380
- t.$slots.actions ? y(t.$slots, "actions", {
419
+ i.row ? (n(), w("div", ge, [
420
+ t.$slots.actions ? b(t.$slots, "actions", {
381
421
  key: 0,
382
422
  row: i.row
383
- }) : (n(), b(V, { key: 1 }, [
384
- y(t.$slots, "action-before-edit", {
423
+ }) : (n(), w($, { key: 1 }, [
424
+ b(t.$slots, "action-before-edit", {
385
425
  row: i.row
386
426
  }),
387
- e.showEditButton ? (n(), p(a, {
427
+ e.showEditButton ? (n(), f(a, {
388
428
  key: 0,
389
429
  size: "small",
390
430
  type: "primary",
391
431
  link: "",
392
- onClick: (R) => x("edit", i.row)
432
+ onClick: (T) => R("edit", i.row)
393
433
  }, {
394
434
  default: u(() => o[9] || (o[9] = [
395
- v("编辑 ")
435
+ C("编辑 ")
396
436
  ])),
397
437
  _: 2,
398
438
  __: [9]
399
- }, 1032, ["onClick"])) : m("", !0),
400
- e.showDeleteButton ? (n(), p(te, {
439
+ }, 1032, ["onClick"])) : c("", !0),
440
+ e.showDeleteButton ? (n(), f(E, {
401
441
  key: 1,
402
442
  title: "确定要删除这条数据吗?",
403
- onConfirm: (R) => I([i.row.id]),
443
+ onConfirm: (T) => L([i.row.id]),
404
444
  "confirm-button-text": "确定",
405
445
  "cancel-button-text": "取消",
406
446
  width: "200"
407
447
  }, {
408
448
  reference: u(() => [
409
- w(a, {
449
+ v(a, {
410
450
  size: "small",
411
451
  type: "danger",
412
452
  link: ""
413
453
  }, {
414
454
  default: u(() => o[10] || (o[10] = [
415
- v("删除")
455
+ C("删除")
416
456
  ])),
417
457
  _: 1,
418
458
  __: [10]
419
459
  })
420
460
  ]),
421
461
  _: 2
422
- }, 1032, ["onConfirm"])) : m("", !0),
423
- y(t.$slots, "action-after-delete", {
462
+ }, 1032, ["onConfirm"])) : c("", !0),
463
+ b(t.$slots, "action-after-delete", {
424
464
  row: i.row
425
465
  })
426
466
  ], 64))
427
- ])) : m("", !0)
467
+ ])) : c("", !0)
428
468
  ]),
429
469
  _: 3
430
- }, 8, ["width"])) : m("", !0)
470
+ }, 8, ["width"])) : c("", !0)
431
471
  ]),
432
472
  _: 3
433
473
  }, 16, ["data"])), [
434
- [L, r.value]
474
+ [W, r.value]
435
475
  ]),
436
- e.showPagination && B.value > 0 ? (n(), b("div", ye, [
437
- w(ae, {
438
- "current-page": f.pageNum,
439
- "onUpdate:currentPage": o[1] || (o[1] = (i) => f.pageNum = i),
440
- "page-size": f.pageSize,
441
- "onUpdate:pageSize": o[2] || (o[2] = (i) => f.pageSize = i),
476
+ e.showPagination && A.value > 0 ? (n(), w("div", ye, [
477
+ v(ae, {
478
+ "current-page": m.pageNum,
479
+ "onUpdate:currentPage": o[1] || (o[1] = (i) => m.pageNum = i),
480
+ "page-size": m.pageSize,
481
+ "onUpdate:pageSize": o[2] || (o[2] = (i) => m.pageSize = i),
442
482
  "page-sizes": e.pageSizes,
443
483
  layout: e.paginationLayout,
444
- total: B.value,
484
+ total: A.value,
445
485
  background: e.paginationBackground,
446
486
  small: e.paginationSmall,
447
487
  "hide-on-single-page": e.paginationHideOnSinglePage,
448
- onSizeChange: Y,
449
- onCurrentChange: Z
488
+ onSizeChange: ee,
489
+ onCurrentChange: te
450
490
  }, null, 8, ["current-page", "page-size", "page-sizes", "layout", "total", "background", "small", "hide-on-single-page"])
451
- ])) : m("", !0),
452
- w(le, {
491
+ ])) : c("", !0),
492
+ v(le, {
453
493
  modelValue: l.visible,
454
494
  "onUpdate:modelValue": o[5] || (o[5] = (i) => l.visible = i),
455
- title: M.value,
495
+ title: J.value,
456
496
  width: e.dialogWidth,
457
497
  "destroy-on-close": !0,
458
498
  "custom-class": Q.value
459
499
  }, {
460
500
  footer: u(() => [
461
- E("div", be, [
462
- w(a, {
501
+ I("div", be, [
502
+ v(a, {
463
503
  onClick: o[4] || (o[4] = (i) => l.visible = !1)
464
504
  }, {
465
505
  default: u(() => o[11] || (o[11] = [
466
- v("取消")
506
+ C("取消")
467
507
  ])),
468
508
  _: 1,
469
509
  __: [11]
470
510
  }),
471
- w(a, {
511
+ v(a, {
472
512
  type: "primary",
473
- onClick: X,
513
+ onClick: Z,
474
514
  loading: l.submitting
475
515
  }, {
476
516
  default: u(() => o[12] || (o[12] = [
477
- v("确定")
517
+ C("确定")
478
518
  ])),
479
519
  _: 1,
480
520
  __: [12]
@@ -482,23 +522,23 @@ const fe = {
482
522
  ])
483
523
  ]),
484
524
  default: u(() => [
485
- W((n(), b("div", null, [
486
- y(t.$slots, "dialog-form-content", {
525
+ M((n(), w("div", null, [
526
+ b(t.$slots, "dialog-form-content", {
487
527
  formData: l.data,
488
528
  mode: l.mode
489
529
  }, () => [
490
- e.dialogFormConfig.length > 0 ? (n(), p(pe, {
530
+ e.dialogFormConfig.length > 0 ? (n(), f(pe, {
491
531
  key: 0,
492
- "form-config": G.value,
532
+ "form-config": K.value,
493
533
  modelValue: l.data,
494
534
  "onUpdate:modelValue": o[3] || (o[3] = (i) => l.data = i),
495
535
  ref: (i) => l.formRef = i,
496
536
  rules: e.dialogFormRules,
497
537
  "label-width": "80px"
498
- }, null, 8, ["form-config", "modelValue", "rules"])) : m("", !0)
538
+ }, null, 8, ["form-config", "modelValue", "rules"])) : c("", !0)
499
539
  ])
500
540
  ])), [
501
- [L, l.loading]
541
+ [W, l.loading]
502
542
  ])
503
543
  ]),
504
544
  _: 3
@@ -508,5 +548,5 @@ const fe = {
508
548
  }
509
549
  });
510
550
  export {
511
- _e as CrudTable
551
+ Se as CrudTable
512
552
  };
@@ -1 +1 @@
1
- (function(f,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("element-plus"),require("axios")):typeof define=="function"&&define.amd?define(["exports","vue","element-plus","axios"],e):(f=typeof globalThis<"u"?globalThis:f||self,e(f.ZCrudTable={},f.Vue,f.ElementPlus,f.axios))})(this,function(f,e,h,A){"use strict";const E=e.defineComponent({__name:"DynamicForm",props:{modelValue:{},formConfig:{},rules:{}},setup(c,{expose:y}){const b=e.ref(null);return y({validate:()=>{var s;return(s=b.value)==null?void 0:s.validate()}}),(s,t)=>{const w=e.resolveComponent("el-input"),N=e.resolveComponent("el-option"),u=e.resolveComponent("el-select"),V=e.resolveComponent("el-radio"),p=e.resolveComponent("el-radio-group"),C=e.resolveComponent("el-form-item"),k=e.resolveComponent("el-form");return e.openBlock(),e.createBlock(k,e.mergeProps({model:s.modelValue,rules:s.rules,ref_key:"formRef",ref:b},s.$attrs),{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(s.formConfig,n=>(e.openBlock(),e.createBlock(C,{key:n.prop,label:n.label,prop:n.prop},{default:e.withCtx(()=>[n.type==="input"?(e.openBlock(),e.createBlock(w,e.mergeProps({key:0,modelValue:s.modelValue[n.prop],"onUpdate:modelValue":d=>s.modelValue[n.prop]=d},{ref_for:!0},n.componentProps),null,16,["modelValue","onUpdate:modelValue"])):e.createCommentVNode("",!0),n.type==="textarea"?(e.openBlock(),e.createBlock(w,e.mergeProps({key:1,type:"textarea",modelValue:s.modelValue[n.prop],"onUpdate:modelValue":d=>s.modelValue[n.prop]=d},{ref_for:!0},n.componentProps),null,16,["modelValue","onUpdate:modelValue"])):e.createCommentVNode("",!0),n.type==="select"?(e.openBlock(),e.createBlock(u,e.mergeProps({key:2,modelValue:s.modelValue[n.prop],"onUpdate:modelValue":d=>s.modelValue[n.prop]=d},{ref_for:!0},n.componentProps),{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.options,d=>(e.openBlock(),e.createBlock(N,{key:d.value,label:d.label,value:d.value},null,8,["label","value"]))),128))]),_:2},1040,["modelValue","onUpdate:modelValue"])):e.createCommentVNode("",!0),n.type==="radio-group"?(e.openBlock(),e.createBlock(p,e.mergeProps({key:3,modelValue:s.modelValue[n.prop],"onUpdate:modelValue":d=>s.modelValue[n.prop]=d},{ref_for:!0},n.componentProps),{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.options,d=>(e.openBlock(),e.createBlock(V,{key:d.value,label:d.value},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(d.label),1)]),_:2},1032,["label"]))),128))]),_:2},1040,["modelValue","onUpdate:modelValue"])):e.createCommentVNode("",!0),n.type==="input-disabled"?(e.openBlock(),e.createBlock(w,e.mergeProps({key:4,"model-value":s.modelValue[n.prop],disabled:""},{ref_for:!0},n.componentProps),null,16,["model-value"])):e.createCommentVNode("",!0)]),_:2},1032,["label","prop"]))),128))]),_:1},16,["model","rules"])}}}),g=A.create({baseURL:"",timeout:1e4});g.interceptors.request.use(c=>{const y=localStorage.getItem("token");return y&&(c.headers.Authorization="Bearer "+y),c},c=>(console.log(c),Promise.reject(c))),g.interceptors.response.use(c=>c.data,c=>(console.log("err"+c),h.ElMessage({message:"接口错误,请刷新接口",type:"error",duration:5*1e3}),Promise.reject(c)));const $={key:0,class:"flex flex-wrap items-center justify-between gap-4 mb-6"},z={class:"flex items-center gap-x-2"},P={class:"flex items-center gap-x-3 action-buttons flex-shrink-0"},O={key:0,class:"flex items-center gap-x-2"},T={key:1,class:"flex justify-end"},q={class:"dialog-footer"},j=e.defineComponent({__name:"CrudTable",props:{theme:{type:String,default:"default"},customClass:{type:String,default:""},apiUrlQuery:{type:String,required:!0},apiUrlDetail:{type:String,required:!0},apiUrlCreate:{type:String,required:!0},apiUrlUpdate:{type:String,required:!0},apiUrlDelete:{type:String,required:!0},showSearchSection:{type:Boolean,default:!0},showSearchActionButtons:{type:Boolean,default:!0},showNewBtn:{type:Boolean,default:!0},columns:{type:Array,default:()=>[]},onBeforeQuery:{type:Function},onAfterQuery:{type:Function},onBeforeOpenDialog:{type:Function},onAfterOpenDialog:{type:Function},onBeforeSubmit:{type:Function},onAfterSubmit:{type:Function},onBeforeDelete:{type:Function},onAfterDelete:{type:Function},showSelectionColumn:{type:Boolean,default:!0},showIndexColumn:{type:Boolean,default:!0},showActionsColumn:{type:Boolean,default:!0},showEditButton:{type:Boolean,default:!0},showDeleteButton:{type:Boolean,default:!0},actionsColumnWidth:{type:[String,Number],default:120},dialogWidth:{type:String,default:"50%"},initialSearchForm:{type:Object,default:()=>({pageNum:1,pageSize:10})},showPagination:{type:Boolean,default:!0},pageSizes:{type:Array,default:()=>[10,20,50,100]},paginationLayout:{type:String,default:"total, sizes, prev, pager, next, jumper"},paginationBackground:{type:Boolean,default:!0},paginationSmall:{type:Boolean,default:!1},paginationHideOnSinglePage:{type:Boolean,default:!1},dialogFormConfig:{type:Array,default:()=>[]},dialogFormRules:{type:Object,default:()=>({})}},emits:["open-dialog","submit","delete"],setup(c,{expose:y,emit:b}){const s=b,t=c,w=e.computed(()=>["crud-table-wrapper",`theme-${t.theme}`,t.customClass]),N=e.computed(()=>t.theme==="large-screen"?"large-screen-dialog":""),u=(o,l)=>o?!0:(h.ElMessage.error(`${l} prop is required.`),!1),V=async(o,l)=>{try{let a={...l};if(t.onBeforeSubmit&&(a=await t.onBeforeSubmit(a)),r.submitting=!0,o==="add"){if(!u(t.apiUrlCreate,"apiUrlCreate"))return;await g.post(t.apiUrlCreate,a),h.ElMessage.success("新增成功")}else{if(!u(t.apiUrlUpdate,"apiUrlUpdate"))return;await g.put(t.apiUrlUpdate,a),h.ElMessage.success("更新成功")}return t.onAfterSubmit&&t.onAfterSubmit(o,a),s("submit",{mode:o,data:a}),r.visible&&(r.visible=!1),B(),Promise.resolve()}catch(a){return console.log("Submit error:",a),Promise.reject(a)}finally{r.submitting=!1}},p=e.reactive({pageNum:1,pageSize:10,...t.initialSearchForm}),C=e.ref([]),k=e.ref(0),n=e.ref(!1),d=e.ref([]),r=e.reactive({visible:!1,loading:!1,submitting:!1,mode:"add",data:{},formRef:null}),Q=e.computed(()=>r.mode==="add"?"新增":"编辑"),R=e.computed(()=>{if(r.mode==="add")return t.dialogFormConfig.filter(l=>l.prop!=="id");const o=[...t.dialogFormConfig.filter(l=>l.prop!=="id")];return o.some(l=>l.prop==="id")||o.unshift({type:"input-disabled",prop:"id",label:"用户ID"}),o}),B=async()=>{if(u(t.apiUrlQuery,"apiUrlQuery")){n.value=!0;try{let o={...p};t.onBeforeQuery&&(o=await t.onBeforeQuery(o));const l=await g.get(t.apiUrlQuery,{params:o});if(l&&l.data&&Array.isArray(l.data.rows)&&typeof l.data.total=="number"){let a=l.data.rows;t.onAfterQuery&&(a=await t.onAfterQuery(a)),C.value=a,k.value=l.data.total}else console.warn("API response is not in the expected { data: { rows: [], total: 0 } } format."),C.value=[],k.value=0}catch(o){console.error("Fetch data failed:",o)}finally{n.value=!1}}},S=()=>{p.pageNum=1,B()},L=()=>{const{pageNum:o,pageSize:l,...a}=t.initialSearchForm;Object.keys(p).forEach(m=>{m!=="pageNum"&&m!=="pageSize"&&delete p[m]}),Object.assign(p,a),S()},M=o=>{d.value=o},D=async(o,l)=>{let a;if(o==="add"?a=l?{...l}:{role:"user"}:a={...l},t.onBeforeOpenDialog){const m=await t.onBeforeOpenDialog(o,a);m&&(a=m)}if(r.mode=o,r.visible=!0,o==="edit"){if(!u(t.apiUrlDetail,"apiUrlDetail"))return;r.loading=!0;try{const m=await g.get(t.apiUrlDetail+"/"+a.id.toString());r.data=m.data.data}finally{r.loading=!1,t.onAfterOpenDialog&&t.onAfterOpenDialog(o,r.data),s("open-dialog",{mode:o,data:r.data})}}else r.data=a,t.onAfterOpenDialog&&t.onAfterOpenDialog(o,r.data),s("open-dialog",{mode:o,data:r.data})},I=async()=>{try{r.formRef&&await r.formRef.validate(),await V(r.mode,r.data)}catch(o){console.log("Validation failed:",o)}},U=async o=>{if(u(t.apiUrlDelete,"apiUrlDelete"))try{if(t.onBeforeDelete&&await t.onBeforeDelete(o)===!1)return;const l=o.join(",");await g.delete(t.apiUrlDelete+"/"+l.toString()),h.ElMessage.success("删除成功"),t.onAfterDelete&&t.onAfterDelete(o),s("delete",o),C.value.length===o.length&&p.pageNum>1&&p.pageNum--,B()}catch(l){console.error("Delete failed",l)}},W=o=>{p.pageSize=o,S()},H=o=>{p.pageNum=o,B()};return e.onMounted(B),y({refresh:B,search:S,handleDelete:U,openDialog:D,submit:V}),(o,l)=>{const a=e.resolveComponent("el-button"),m=e.resolveComponent("el-form-item"),Z=e.resolveComponent("el-form"),_=e.resolveComponent("el-table-column"),G=e.resolveComponent("el-popconfirm"),J=e.resolveComponent("el-table"),K=e.resolveComponent("el-pagination"),X=e.resolveComponent("el-dialog"),F=e.resolveDirective("loading");return e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(w.value)},[e.renderSlot(o.$slots,"header"),t.showSearchSection?(e.openBlock(),e.createElementBlock("div",$,[e.createVNode(Z,{model:p,class:"query-form flex flex-nowrap items-center gap-x-4",style:{"overflow-x":"auto","padding-bottom":"8px"}},{default:e.withCtx(()=>[e.renderSlot(o.$slots,"query-conditions",{searchForm:p}),e.createVNode(m,{class:"!mr-0 flex-shrink-0"},{default:e.withCtx(()=>[e.createElementVNode("div",z,[e.renderSlot(o.$slots,"query-left"),t.showSearchActionButtons?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(a,{type:"primary",onClick:S,loading:n.value},{default:e.withCtx(()=>l[6]||(l[6]=[e.createTextVNode("搜索")])),_:1,__:[6]},8,["loading"]),e.createVNode(a,{onClick:L},{default:e.withCtx(()=>l[7]||(l[7]=[e.createTextVNode("清空")])),_:1,__:[7]})],64)):e.createCommentVNode("",!0),e.renderSlot(o.$slots,"query-right")])]),_:3})]),_:3},8,["model"]),e.createElementVNode("div",P,[e.renderSlot(o.$slots,"action-left",{selections:d.value}),e.renderSlot(o.$slots,"add-button-content",{},()=>[t.showNewBtn?(e.openBlock(),e.createBlock(a,{key:0,type:"success",onClick:l[0]||(l[0]=i=>D("add"))},{default:e.withCtx(()=>l[8]||(l[8]=[e.createTextVNode("新增")])),_:1,__:[8]})):e.createCommentVNode("",!0)]),e.renderSlot(o.$slots,"action-right")])])):e.createCommentVNode("",!0),e.withDirectives((e.openBlock(),e.createBlock(J,e.mergeProps({data:C.value,onSelectionChange:M},o.$attrs,{style:{width:"100%","margin-bottom":"1.5rem"}}),{default:e.withCtx(()=>[t.showSelectionColumn?(e.openBlock(),e.createBlock(_,{key:0,type:"selection",width:"55",fixed:""})):e.createCommentVNode("",!0),t.showIndexColumn?(e.openBlock(),e.createBlock(_,{key:1,type:"index",label:"序号",width:"70",fixed:""})):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.columns,i=>(e.openBlock(),e.createBlock(_,e.mergeProps({key:i.prop,prop:i.prop,label:i.label,width:i.width,sortable:i.sortable||!1},{ref_for:!0},i.attrs),e.createSlots({_:2},[i.slot?{name:"default",fn:e.withCtx(x=>[e.renderSlot(o.$slots,i.slot,{row:x.row})]),key:"0"}:void 0]),1040,["prop","label","width","sortable"]))),128)),t.showActionsColumn?(e.openBlock(),e.createBlock(_,{key:2,label:"操作",width:c.actionsColumnWidth},{default:e.withCtx(i=>[i.row?(e.openBlock(),e.createElementBlock("div",O,[o.$slots.actions?e.renderSlot(o.$slots,"actions",{key:0,row:i.row}):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.renderSlot(o.$slots,"action-before-edit",{row:i.row}),t.showEditButton?(e.openBlock(),e.createBlock(a,{key:0,size:"small",type:"primary",link:"",onClick:x=>D("edit",i.row)},{default:e.withCtx(()=>l[9]||(l[9]=[e.createTextVNode("编辑 ")])),_:2,__:[9]},1032,["onClick"])):e.createCommentVNode("",!0),t.showDeleteButton?(e.openBlock(),e.createBlock(G,{key:1,title:"确定要删除这条数据吗?",onConfirm:x=>U([i.row.id]),"confirm-button-text":"确定","cancel-button-text":"取消",width:"200"},{reference:e.withCtx(()=>[e.createVNode(a,{size:"small",type:"danger",link:""},{default:e.withCtx(()=>l[10]||(l[10]=[e.createTextVNode("删除")])),_:1,__:[10]})]),_:2},1032,["onConfirm"])):e.createCommentVNode("",!0),e.renderSlot(o.$slots,"action-after-delete",{row:i.row})],64))])):e.createCommentVNode("",!0)]),_:3},8,["width"])):e.createCommentVNode("",!0)]),_:3},16,["data"])),[[F,n.value]]),t.showPagination&&k.value>0?(e.openBlock(),e.createElementBlock("div",T,[e.createVNode(K,{"current-page":p.pageNum,"onUpdate:currentPage":l[1]||(l[1]=i=>p.pageNum=i),"page-size":p.pageSize,"onUpdate:pageSize":l[2]||(l[2]=i=>p.pageSize=i),"page-sizes":t.pageSizes,layout:t.paginationLayout,total:k.value,background:t.paginationBackground,small:t.paginationSmall,"hide-on-single-page":t.paginationHideOnSinglePage,onSizeChange:W,onCurrentChange:H},null,8,["current-page","page-size","page-sizes","layout","total","background","small","hide-on-single-page"])])):e.createCommentVNode("",!0),e.createVNode(X,{modelValue:r.visible,"onUpdate:modelValue":l[5]||(l[5]=i=>r.visible=i),title:Q.value,width:t.dialogWidth,"destroy-on-close":!0,"custom-class":N.value},{footer:e.withCtx(()=>[e.createElementVNode("div",q,[e.createVNode(a,{onClick:l[4]||(l[4]=i=>r.visible=!1)},{default:e.withCtx(()=>l[11]||(l[11]=[e.createTextVNode("取消")])),_:1,__:[11]}),e.createVNode(a,{type:"primary",onClick:I,loading:r.submitting},{default:e.withCtx(()=>l[12]||(l[12]=[e.createTextVNode("确定")])),_:1,__:[12]},8,["loading"])])]),default:e.withCtx(()=>[e.withDirectives((e.openBlock(),e.createElementBlock("div",null,[e.renderSlot(o.$slots,"dialog-form-content",{formData:r.data,mode:r.mode},()=>[t.dialogFormConfig.length>0?(e.openBlock(),e.createBlock(E,{key:0,"form-config":R.value,modelValue:r.data,"onUpdate:modelValue":l[3]||(l[3]=i=>r.data=i),ref:i=>r.formRef=i,rules:t.dialogFormRules,"label-width":"80px"},null,8,["form-config","modelValue","rules"])):e.createCommentVNode("",!0)])])),[[F,r.loading]])]),_:3},8,["modelValue","title","width","custom-class"])],2)}}});f.CrudTable=j,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
1
+ (function(f,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("element-plus"),require("axios")):typeof define=="function"&&define.amd?define(["exports","vue","element-plus","axios"],e):(f=typeof globalThis<"u"?globalThis:f||self,e(f.ZCrudTable={},f.Vue,f.ElementPlus,f.axios))})(this,function(f,e,C,$){"use strict";const z=e.defineComponent({__name:"DynamicForm",props:{modelValue:{},formConfig:{},rules:{}},setup(m,{expose:w}){const V=e.ref(null);return w({validate:()=>{var s;return(s=V.value)==null?void 0:s.validate()}}),(s,t)=>{const S=e.resolveComponent("el-input"),D=e.resolveComponent("el-option"),u=e.resolveComponent("el-select"),U=e.resolveComponent("el-radio"),c=e.resolveComponent("el-radio-group"),B=e.resolveComponent("el-form-item"),h=e.resolveComponent("el-form");return e.openBlock(),e.createBlock(h,e.mergeProps({model:s.modelValue,rules:s.rules,ref_key:"formRef",ref:V},s.$attrs),{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(s.formConfig,n=>(e.openBlock(),e.createBlock(B,{key:n.prop,label:n.label,prop:n.prop},{default:e.withCtx(()=>[n.type==="input"?(e.openBlock(),e.createBlock(S,e.mergeProps({key:0,modelValue:s.modelValue[n.prop],"onUpdate:modelValue":d=>s.modelValue[n.prop]=d},{ref_for:!0},n.componentProps),null,16,["modelValue","onUpdate:modelValue"])):e.createCommentVNode("",!0),n.type==="textarea"?(e.openBlock(),e.createBlock(S,e.mergeProps({key:1,type:"textarea",modelValue:s.modelValue[n.prop],"onUpdate:modelValue":d=>s.modelValue[n.prop]=d},{ref_for:!0},n.componentProps),null,16,["modelValue","onUpdate:modelValue"])):e.createCommentVNode("",!0),n.type==="select"?(e.openBlock(),e.createBlock(u,e.mergeProps({key:2,modelValue:s.modelValue[n.prop],"onUpdate:modelValue":d=>s.modelValue[n.prop]=d},{ref_for:!0},n.componentProps),{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.options,d=>(e.openBlock(),e.createBlock(D,{key:d.value,label:d.label,value:d.value},null,8,["label","value"]))),128))]),_:2},1040,["modelValue","onUpdate:modelValue"])):e.createCommentVNode("",!0),n.type==="radio-group"?(e.openBlock(),e.createBlock(c,e.mergeProps({key:3,modelValue:s.modelValue[n.prop],"onUpdate:modelValue":d=>s.modelValue[n.prop]=d},{ref_for:!0},n.componentProps),{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.options,d=>(e.openBlock(),e.createBlock(U,{key:d.value,label:d.value},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(d.label),1)]),_:2},1032,["label"]))),128))]),_:2},1040,["modelValue","onUpdate:modelValue"])):e.createCommentVNode("",!0),n.type==="input-disabled"?(e.openBlock(),e.createBlock(S,e.mergeProps({key:4,"model-value":s.modelValue[n.prop],disabled:""},{ref_for:!0},n.componentProps),null,16,["model-value"])):e.createCommentVNode("",!0)]),_:2},1032,["label","prop"]))),128))]),_:1},16,["model","rules"])}}}),g=$.create({baseURL:"",timeout:1e4});g.interceptors.request.use(m=>{const w=localStorage.getItem("token");return w&&(m.headers.Authorization="Bearer "+w),m},m=>(console.log(m),Promise.reject(m))),g.interceptors.response.use(m=>m.data,m=>(console.log("err"+m),C.ElMessage({message:"接口错误,请刷新接口",type:"error",duration:5*1e3}),Promise.reject(m)));const P={key:0,class:"flex flex-wrap items-center justify-between gap-4 mb-6"},O={class:"flex items-center gap-x-2"},T={class:"flex items-center gap-x-3 action-buttons flex-shrink-0"},j={key:0,class:"flex items-center gap-x-2"},q={key:1,class:"flex justify-end"},Q={class:"dialog-footer"},M=e.defineComponent({__name:"CrudTable",props:{theme:{type:String,default:"default"},customClass:{type:String,default:""},apiUrlQuery:{type:String,required:!0},apiUrlDetail:{type:String,required:!0},apiUrlCreate:{type:String,required:!0},apiUrlUpdate:{type:String,required:!0},apiUrlDelete:{type:String,required:!0},showSearchSection:{type:Boolean,default:!0},showSearchActionButtons:{type:Boolean,default:!0},showNewBtn:{type:Boolean,default:!0},columns:{type:Array,default:()=>[]},onBeforeQuery:{type:Function},onAfterQuery:{type:Function},onBeforeOpenDialog:{type:Function},onAfterOpenDialog:{type:Function},onBeforeSubmit:{type:Function},onAfterSubmit:{type:Function},onBeforeDelete:{type:Function},onAfterDelete:{type:Function},showSelectionColumn:{type:Boolean,default:!0},showIndexColumn:{type:Boolean,default:!0},showActionsColumn:{type:Boolean,default:!0},showEditButton:{type:Boolean,default:!0},showDeleteButton:{type:Boolean,default:!0},actionsColumnWidth:{type:[String,Number],default:120},dialogWidth:{type:String,default:"50%"},initialSearchForm:{type:Object,default:()=>({pageNum:1,pageSize:10})},showPagination:{type:Boolean,default:!0},pageSizes:{type:Array,default:()=>[10,20,50,100]},paginationLayout:{type:String,default:"total, sizes, prev, pager, next, jumper"},paginationBackground:{type:Boolean,default:!0},paginationSmall:{type:Boolean,default:!1},paginationHideOnSinglePage:{type:Boolean,default:!1},dialogFormConfig:{type:Array,default:()=>[]},dialogFormRules:{type:Object,default:()=>({})},submitAsFormData:{type:Boolean,default:!1}},emits:["open-dialog","submit","delete"],setup(m,{expose:w,emit:V}){const s=V,t=m,S=e.computed(()=>["crud-table-wrapper",`theme-${t.theme}`,t.customClass]),D=e.computed(()=>t.theme==="large-screen"?"large-screen-dialog":""),u=(o,a)=>o?!0:(C.ElMessage.error(`${a} prop is required.`),!1),U=async(o,a)=>{try{let l={...a};t.onBeforeSubmit&&(l=await t.onBeforeSubmit(l));let p=l;if(t.submitAsFormData){const b=new FormData;for(const y in l)if(Object.prototype.hasOwnProperty.call(l,y)){const x=l[y];b.append(y,x??"")}p=b}if(r.submitting=!0,o==="add"){if(!u(t.apiUrlCreate,"apiUrlCreate"))throw new Error("apiUrlCreate is not configured.");await g.post(t.apiUrlCreate,p),C.ElMessage.success("新增成功")}else{if(!u(t.apiUrlUpdate,"apiUrlUpdate"))throw new Error("apiUrlUpdate is not configured.");await g.put(t.apiUrlUpdate,p),C.ElMessage.success("更新成功")}return t.onAfterSubmit&&t.onAfterSubmit(o,l),s("submit",{mode:o,data:l}),r.visible&&(r.visible=!1),k(),Promise.resolve()}catch(l){return console.error("Submit failed:",l),Promise.reject(l)}finally{r.submitting=!1}},c=e.reactive({pageNum:1,pageSize:10,...t.initialSearchForm}),B=e.ref([]),h=e.ref(0),n=e.ref(!1),d=e.ref([]),r=e.reactive({visible:!1,loading:!1,submitting:!1,mode:"add",data:{},formRef:null}),R=e.computed(()=>r.mode==="add"?"新增":"编辑"),L=e.computed(()=>{if(r.mode==="add")return t.dialogFormConfig.filter(a=>a.prop!=="id");const o=[...t.dialogFormConfig.filter(a=>a.prop!=="id")];return o.some(a=>a.prop==="id")||o.unshift({type:"input-disabled",prop:"id",label:"用户ID"}),o}),k=async()=>{if(u(t.apiUrlQuery,"apiUrlQuery")){n.value=!0;try{let o={...c};t.onBeforeQuery&&(o=await t.onBeforeQuery(o));const a=await g.get(t.apiUrlQuery,{params:o});if(a&&a.data&&Array.isArray(a.data.rows)&&typeof a.data.total=="number"){let l=a.data.rows;t.onAfterQuery&&(l=await t.onAfterQuery(l)),B.value=l,h.value=a.data.total}else console.warn("API response is not in the expected { data: { rows: [], total: 0 } } format."),B.value=[],h.value=0}catch(o){console.error("Fetch data failed:",o)}finally{n.value=!1}}},_=()=>{c.pageNum=1,k()},I=()=>{const{pageNum:o,pageSize:a,...l}=t.initialSearchForm;Object.keys(c).forEach(p=>{p!=="pageNum"&&p!=="pageSize"&&delete c[p]}),Object.assign(c,l),_()},W=o=>{d.value=o},N=async(o,a)=>{let l;if(o==="add"?l=a?{...a}:{role:"user"}:l={...a},t.onBeforeOpenDialog){const p=await t.onBeforeOpenDialog(o,l);p&&(l=p)}if(r.mode=o,r.visible=!0,o==="edit"){if(!u(t.apiUrlDetail,"apiUrlDetail"))return;r.loading=!0;try{const p=await g.get(t.apiUrlDetail+"/"+l.id.toString());r.data=p.data.data}finally{r.loading=!1,t.onAfterOpenDialog&&t.onAfterOpenDialog(o,r.data),s("open-dialog",{mode:o,data:r.data})}}else r.data=l,t.onAfterOpenDialog&&t.onAfterOpenDialog(o,r.data),s("open-dialog",{mode:o,data:r.data})},H=async()=>{try{r.formRef&&await r.formRef.validate();let o={...r.data};t.onBeforeSubmit&&(o=await t.onBeforeSubmit(o));let a=o;if(t.submitAsFormData){const l=new FormData;for(const p in o)if(Object.prototype.hasOwnProperty.call(o,p)){const b=o[p];l.append(p,b??"")}a=l;debugger}if(r.submitting=!0,r.mode==="add"){if(!u(t.apiUrlCreate,"apiUrlCreate"))return;await g.post(t.apiUrlCreate,a),C.ElMessage.success("新增成功")}else{if(!u(t.apiUrlUpdate,"apiUrlUpdate"))return;await g.put(t.apiUrlUpdate,a),C.ElMessage.success("更新成功")}t.onAfterSubmit&&t.onAfterSubmit(r.mode,o),s("submit",{mode:r.mode,data:o}),r.visible=!1,k()}catch(o){console.log("Submit error or validation failed:",o)}finally{r.submitting=!1}},A=async o=>{if(u(t.apiUrlDelete,"apiUrlDelete"))try{if(t.onBeforeDelete&&await t.onBeforeDelete(o)===!1)return;const a=o.join(",");await g.delete(t.apiUrlDelete+"/"+a.toString()),C.ElMessage.success("删除成功"),t.onAfterDelete&&t.onAfterDelete(o),s("delete",o),B.value.length===o.length&&c.pageNum>1&&c.pageNum--,k()}catch(a){console.error("Delete failed",a)}},Z=o=>{c.pageSize=o,_()},G=o=>{c.pageNum=o,k()};return e.onMounted(k),w({refresh:k,search:_,handleDelete:A,openDialog:N,submit:U}),(o,a)=>{const l=e.resolveComponent("el-button"),p=e.resolveComponent("el-form-item"),b=e.resolveComponent("el-form"),y=e.resolveComponent("el-table-column"),x=e.resolveComponent("el-popconfirm"),J=e.resolveComponent("el-table"),K=e.resolveComponent("el-pagination"),X=e.resolveComponent("el-dialog"),E=e.resolveDirective("loading");return e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(S.value)},[e.renderSlot(o.$slots,"header"),t.showSearchSection?(e.openBlock(),e.createElementBlock("div",P,[e.createVNode(b,{model:c,class:"query-form flex flex-nowrap items-center gap-x-4",style:{"overflow-x":"auto","padding-bottom":"8px"}},{default:e.withCtx(()=>[e.renderSlot(o.$slots,"query-conditions",{searchForm:c}),e.createVNode(p,{class:"!mr-0 flex-shrink-0"},{default:e.withCtx(()=>[e.createElementVNode("div",O,[e.renderSlot(o.$slots,"query-left"),t.showSearchActionButtons?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(l,{type:"primary",onClick:_,loading:n.value},{default:e.withCtx(()=>a[6]||(a[6]=[e.createTextVNode("搜索")])),_:1,__:[6]},8,["loading"]),e.createVNode(l,{onClick:I},{default:e.withCtx(()=>a[7]||(a[7]=[e.createTextVNode("清空")])),_:1,__:[7]})],64)):e.createCommentVNode("",!0),e.renderSlot(o.$slots,"query-right")])]),_:3})]),_:3},8,["model"]),e.createElementVNode("div",T,[e.renderSlot(o.$slots,"action-left",{selections:d.value}),e.renderSlot(o.$slots,"add-button-content",{},()=>[t.showNewBtn?(e.openBlock(),e.createBlock(l,{key:0,type:"success",onClick:a[0]||(a[0]=i=>N("add"))},{default:e.withCtx(()=>a[8]||(a[8]=[e.createTextVNode("新增")])),_:1,__:[8]})):e.createCommentVNode("",!0)]),e.renderSlot(o.$slots,"action-right")])])):e.createCommentVNode("",!0),e.withDirectives((e.openBlock(),e.createBlock(J,e.mergeProps({data:B.value,onSelectionChange:W},o.$attrs,{style:{width:"100%","margin-bottom":"1.5rem"}}),{default:e.withCtx(()=>[t.showSelectionColumn?(e.openBlock(),e.createBlock(y,{key:0,type:"selection",width:"55",fixed:""})):e.createCommentVNode("",!0),t.showIndexColumn?(e.openBlock(),e.createBlock(y,{key:1,type:"index",label:"序号",width:"70",fixed:""})):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.columns,i=>(e.openBlock(),e.createBlock(y,e.mergeProps({key:i.prop,prop:i.prop,label:i.label,width:i.width,sortable:i.sortable||!1},{ref_for:!0},i.attrs),e.createSlots({_:2},[i.slot?{name:"default",fn:e.withCtx(F=>[e.renderSlot(o.$slots,i.slot,{row:F.row})]),key:"0"}:void 0]),1040,["prop","label","width","sortable"]))),128)),t.showActionsColumn?(e.openBlock(),e.createBlock(y,{key:2,label:"操作",width:m.actionsColumnWidth},{default:e.withCtx(i=>[i.row?(e.openBlock(),e.createElementBlock("div",j,[o.$slots.actions?e.renderSlot(o.$slots,"actions",{key:0,row:i.row}):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.renderSlot(o.$slots,"action-before-edit",{row:i.row}),t.showEditButton?(e.openBlock(),e.createBlock(l,{key:0,size:"small",type:"primary",link:"",onClick:F=>N("edit",i.row)},{default:e.withCtx(()=>a[9]||(a[9]=[e.createTextVNode("编辑 ")])),_:2,__:[9]},1032,["onClick"])):e.createCommentVNode("",!0),t.showDeleteButton?(e.openBlock(),e.createBlock(x,{key:1,title:"确定要删除这条数据吗?",onConfirm:F=>A([i.row.id]),"confirm-button-text":"确定","cancel-button-text":"取消",width:"200"},{reference:e.withCtx(()=>[e.createVNode(l,{size:"small",type:"danger",link:""},{default:e.withCtx(()=>a[10]||(a[10]=[e.createTextVNode("删除")])),_:1,__:[10]})]),_:2},1032,["onConfirm"])):e.createCommentVNode("",!0),e.renderSlot(o.$slots,"action-after-delete",{row:i.row})],64))])):e.createCommentVNode("",!0)]),_:3},8,["width"])):e.createCommentVNode("",!0)]),_:3},16,["data"])),[[E,n.value]]),t.showPagination&&h.value>0?(e.openBlock(),e.createElementBlock("div",q,[e.createVNode(K,{"current-page":c.pageNum,"onUpdate:currentPage":a[1]||(a[1]=i=>c.pageNum=i),"page-size":c.pageSize,"onUpdate:pageSize":a[2]||(a[2]=i=>c.pageSize=i),"page-sizes":t.pageSizes,layout:t.paginationLayout,total:h.value,background:t.paginationBackground,small:t.paginationSmall,"hide-on-single-page":t.paginationHideOnSinglePage,onSizeChange:Z,onCurrentChange:G},null,8,["current-page","page-size","page-sizes","layout","total","background","small","hide-on-single-page"])])):e.createCommentVNode("",!0),e.createVNode(X,{modelValue:r.visible,"onUpdate:modelValue":a[5]||(a[5]=i=>r.visible=i),title:R.value,width:t.dialogWidth,"destroy-on-close":!0,"custom-class":D.value},{footer:e.withCtx(()=>[e.createElementVNode("div",Q,[e.createVNode(l,{onClick:a[4]||(a[4]=i=>r.visible=!1)},{default:e.withCtx(()=>a[11]||(a[11]=[e.createTextVNode("取消")])),_:1,__:[11]}),e.createVNode(l,{type:"primary",onClick:H,loading:r.submitting},{default:e.withCtx(()=>a[12]||(a[12]=[e.createTextVNode("确定")])),_:1,__:[12]},8,["loading"])])]),default:e.withCtx(()=>[e.withDirectives((e.openBlock(),e.createElementBlock("div",null,[e.renderSlot(o.$slots,"dialog-form-content",{formData:r.data,mode:r.mode},()=>[t.dialogFormConfig.length>0?(e.openBlock(),e.createBlock(z,{key:0,"form-config":L.value,modelValue:r.data,"onUpdate:modelValue":a[3]||(a[3]=i=>r.data=i),ref:i=>r.formRef=i,rules:t.dialogFormRules,"label-width":"80px"},null,8,["form-config","modelValue","rules"])):e.createCommentVNode("",!0)])])),[[E,r.loading]])]),_:3},8,["modelValue","title","width","custom-class"])],2)}}});f.CrudTable=M,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "z-crud-table",
3
3
  "private": false,
4
- "version": "0.0.23",
4
+ "version": "0.0.25",
5
5
  "type": "module",
6
6
  "description": "A powerful and flexible CRUD table component for Vue 3 and Element Plus.",
7
7
  "keywords": [