z-crud-table 0.0.23 → 0.0.24

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