z-crud-table 0.0.22 → 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.
@@ -37,6 +37,10 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
37
37
  type: BooleanConstructor;
38
38
  default: boolean;
39
39
  };
40
+ showSearchActionButtons: {
41
+ type: BooleanConstructor;
42
+ default: boolean;
43
+ };
40
44
  showNewBtn: {
41
45
  type: BooleanConstructor;
42
46
  default: boolean;
@@ -136,6 +140,15 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
136
140
  type: ObjectConstructor;
137
141
  default: () => {};
138
142
  };
143
+ /**
144
+ * @description 是否以 multipart/form-data 格式提交表单。
145
+ * 适用于需要上传文件的场景。
146
+ * @type {Boolean}
147
+ */
148
+ submitAsFormData: {
149
+ type: BooleanConstructor;
150
+ default: boolean;
151
+ };
139
152
  }>, {
140
153
  refresh: () => Promise<void>;
141
154
  search: () => void;
@@ -183,6 +196,10 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
183
196
  type: BooleanConstructor;
184
197
  default: boolean;
185
198
  };
199
+ showSearchActionButtons: {
200
+ type: BooleanConstructor;
201
+ default: boolean;
202
+ };
186
203
  showNewBtn: {
187
204
  type: BooleanConstructor;
188
205
  default: boolean;
@@ -282,6 +299,15 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
282
299
  type: ObjectConstructor;
283
300
  default: () => {};
284
301
  };
302
+ /**
303
+ * @description 是否以 multipart/form-data 格式提交表单。
304
+ * 适用于需要上传文件的场景。
305
+ * @type {Boolean}
306
+ */
307
+ submitAsFormData: {
308
+ type: BooleanConstructor;
309
+ default: boolean;
310
+ };
285
311
  }>> & Readonly<{
286
312
  onSubmit?: ((...args: any[]) => any) | undefined;
287
313
  onDelete?: ((...args: any[]) => any) | undefined;
@@ -290,6 +316,7 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
290
316
  customClass: string;
291
317
  theme: "default" | "large-screen";
292
318
  showSearchSection: boolean;
319
+ showSearchActionButtons: boolean;
293
320
  showNewBtn: boolean;
294
321
  columns: any[];
295
322
  showSelectionColumn: boolean;
@@ -308,6 +335,7 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
308
335
  paginationHideOnSinglePage: boolean;
309
336
  dialogFormConfig: any[];
310
337
  dialogFormRules: Record<string, any>;
338
+ submitAsFormData: boolean;
311
339
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>, Partial<Record<any, (_: {
312
340
  row: any;
313
341
  }) => any>> & {
@@ -1,53 +1,53 @@
1
- import { defineComponent as H, ref as A, resolveComponent as g, createBlock as p, openBlock as n, mergeProps as _, withCtx as u, createElementBlock as w, Fragment as $, 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 h, createElementVNode as E, createSlots as ue } from "vue";
2
- import { ElMessage as F } 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: D }) {
12
- const z = A(null);
13
- return D({
11
+ setup(g, { expose: k }) {
12
+ const z = $(null);
13
+ return k({
14
14
  validate: () => {
15
15
  var s;
16
16
  return (s = z.value) == null ? void 0 : s.validate();
17
17
  }
18
- }), (s, t) => {
19
- const B = g("el-input"), Q = g("el-option"), S = g("el-select"), N = g("el-radio"), f = g("el-radio-group"), k = g("el-form-item"), U = g("el-form");
20
- return n(), p(U, _({
18
+ }), (s, e) => {
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), w($, null, q(s.formConfig, (r) => (n(), p(k, {
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(B, _({
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(B, _({
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), w($, 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), w($, 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(B, _({
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) => {
98
- const D = localStorage.getItem("token");
99
- return D && (c.headers.Authorization = "Bearer " + D), c;
96
+ S.interceptors.request.use(
97
+ (g) => {
98
+ const k = localStorage.getItem("token");
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), F({
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
  /**
@@ -134,7 +134,8 @@ const fe = {
134
134
  apiUrlUpdate: { type: String, required: !0 },
135
135
  apiUrlDelete: { type: String, required: !0 },
136
136
  showSearchSection: { type: Boolean, default: !0 },
137
- // ✨ 新增:控制搜索区域显隐
137
+ // ✨ [新增] 控制搜索/清空按钮的显示
138
+ showSearchActionButtons: { type: Boolean, default: !0 },
138
139
  // 控制新增按钮
139
140
  showNewBtn: { type: Boolean, default: !0 },
140
141
  // 表格列定义,通过配置数组动态渲染,比 slot 更灵活。
@@ -157,7 +158,6 @@ const fe = {
157
158
  showActionsColumn: { type: Boolean, default: !0 },
158
159
  showEditButton: { type: Boolean, default: !0 },
159
160
  showDeleteButton: { type: Boolean, default: !0 },
160
- showNewBtn: { type: Boolean, default: !0 },
161
161
  // UI 定制化配置
162
162
  actionsColumnWidth: { type: [String, Number], default: 120 },
163
163
  dialogWidth: { type: String, default: "50%" },
@@ -171,143 +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: D, emit: z }) {
178
- const s = z, t = c, B = j(() => ["crud-table-wrapper", `theme-${t.theme}`, t.customClass]), Q = j(() => t.theme === "large-screen" ? "large-screen-dialog" : ""), S = (e, o) => e ? !0 : (F.error(`${o} prop is required.`), !1), N = async (e, 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
186
  let l = { ...o };
181
- if (t.onBeforeSubmit && (l = await t.onBeforeSubmit(l)), a.submitting = !0, e === "add") {
182
- if (!S(t.apiUrlCreate, "apiUrlCreate")) return;
183
- await C.post(t.apiUrlCreate, l), F.success("新增成功");
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(t.apiUrlUpdate, "apiUrlUpdate")) return;
186
- await C.put(t.apiUrlUpdate, l), F.success("更新成功");
191
+ if (!h(e.apiUrlUpdate, "apiUrlUpdate")) return;
192
+ await S.put(e.apiUrlUpdate, l), U.success("更新成功");
187
193
  }
188
- return t.onAfterSubmit && t.onAfterSubmit(e, l), s("submit", { mode: e, data: l }), a.visible && (a.visible = !1), V(), Promise.resolve();
194
+ return e.onAfterSubmit && e.onAfterSubmit(t, l), s("submit", { mode: t, data: l }), a.visible && (a.visible = !1), D(), Promise.resolve();
189
195
  } catch (l) {
190
196
  return console.log("Submit error:", l), Promise.reject(l);
191
197
  } finally {
192
198
  a.submitting = !1;
193
199
  }
194
- }, f = T({ pageNum: 1, pageSize: 10, ...t.initialSearchForm }), k = A([]), U = A(0), r = A(!1), d = A([]), a = T({ visible: !1, loading: !1, submitting: !1, mode: "add", data: {}, formRef: null }), M = j(() => a.mode === "add" ? "新增" : "编辑"), G = j(() => {
195
- if (a.mode === "add") return t.dialogFormConfig.filter((o) => o.prop !== "id");
196
- const e = [...t.dialogFormConfig.filter((o) => o.prop !== "id")];
197
- return e.some((o) => o.prop === "id") || e.unshift({ type: "input-disabled", prop: "id", label: "用户ID" }), e;
198
- }), V = async () => {
199
- if (S(t.apiUrlQuery, "apiUrlQuery")) {
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");
202
+ const t = [...e.dialogFormConfig.filter((o) => o.prop !== "id")];
203
+ return t.some((o) => o.prop === "id") || t.unshift({ type: "input-disabled", prop: "id", label: "用户ID" }), t;
204
+ }), D = async () => {
205
+ if (h(e.apiUrlQuery, "apiUrlQuery")) {
200
206
  r.value = !0;
201
207
  try {
202
- let e = { ...f };
203
- t.onBeforeQuery && (e = await t.onBeforeQuery(e));
204
- const o = await C.get(t.apiUrlQuery, { params: e });
205
- if (o && Array.isArray(o.data.rows) && typeof o.data.total == "number") {
208
+ let t = { ...f };
209
+ e.onBeforeQuery && (t = await e.onBeforeQuery(t));
210
+ const o = await S.get(e.apiUrlQuery, { params: t });
211
+ if (o && o.data && Array.isArray(o.data.rows) && typeof o.data.total == "number") {
206
212
  let l = o.data.rows;
207
- t.onAfterQuery && (l = await t.onAfterQuery(l)), k.value = l, U.value = o.data.total;
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: [], total: 0 } format."), k.value = [], U.value = 0;
210
- } catch (e) {
211
- console.error("Fetch data failed:", e);
215
+ console.warn("API response is not in the expected { data: { rows: [], total: 0 } } format."), B.value = [], V.value = 0;
216
+ } catch (t) {
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, V();
218
- }, J = () => {
219
- const { pageNum: e, pageSize: o, ...l } = t.initialSearchForm;
220
- Object.keys(f).forEach((b) => {
221
- b !== "pageNum" && b !== "pageSize" && delete f[b];
222
- }), Object.assign(f, l), P();
223
- }, K = (e) => {
224
- d.value = e;
225
- }, x = async (e, o) => {
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) => {
230
+ d.value = t;
231
+ }, x = async (t, o) => {
226
232
  let l;
227
- if (e === "add" ? l = o ? { ...o } : { role: "user" } : l = { ...o }, t.onBeforeOpenDialog) {
228
- const b = await t.onBeforeOpenDialog(e, l);
229
- b && (l = b);
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 (a.mode = e, a.visible = !0, e === "edit") {
232
- if (!S(t.apiUrlDetail, "apiUrlDetail")) return;
237
+ if (a.mode = t, a.visible = !0, t === "edit") {
238
+ if (!h(e.apiUrlDetail, "apiUrlDetail")) return;
233
239
  a.loading = !0;
234
240
  try {
235
- const b = await C.get(t.apiUrlDetail, { params: { id: l.id } });
236
- a.data = b.data;
241
+ const y = await S.get(e.apiUrlDetail + "/" + l.id.toString());
242
+ a.data = y.data.data;
237
243
  } finally {
238
- a.loading = !1, t.onAfterOpenDialog && t.onAfterOpenDialog(e, a.data), s("open-dialog", { mode: e, data: a.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
- a.data = l, t.onAfterOpenDialog && t.onAfterOpenDialog(e, a.data), s("open-dialog", { mode: e, data: a.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
- a.formRef && await a.formRef.validate(), await N(a.mode, a.data);
245
- } catch (e) {
246
- console.log("Validation failed:", e);
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();
271
+ } catch (t) {
272
+ console.log("Submit error or validation failed:", t);
273
+ } finally {
274
+ a.submitting = !1;
247
275
  }
248
- }, I = async (e) => {
249
- if (S(t.apiUrlDelete, "apiUrlDelete"))
276
+ }, T = async (t) => {
277
+ if (h(e.apiUrlDelete, "apiUrlDelete"))
250
278
  try {
251
- if (t.onBeforeDelete && await t.onBeforeDelete(e) === !1)
279
+ if (e.onBeforeDelete && await e.onBeforeDelete(t) === !1)
252
280
  return;
253
- const o = e.join(",");
254
- await C.delete(t.apiUrlDelete + "/" + o.toString()), F.success("删除成功"), t.onAfterDelete && t.onAfterDelete(e), s("delete", e), k.value.length === e.length && f.pageNum > 1 && f.pageNum--, V();
281
+ const o = t.join(",");
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 = (e) => {
259
- f.pageSize = e, P();
260
- }, Z = (e) => {
261
- f.pageNum = e, V();
286
+ }, Z = (t) => {
287
+ f.pageSize = t, N();
288
+ }, ee = (t) => {
289
+ f.pageNum = t, D();
262
290
  };
263
- return ne(V), D({
264
- refresh: V,
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
- }), (e, o) => {
275
- const l = g("el-button"), b = g("el-form-item"), ee = g("el-form"), O = g("el-table-column"), te = g("el-popconfirm"), oe = g("el-table"), le = g("el-pagination"), ae = g("el-dialog"), L = ie("loading");
302
+ }), (t, o) => {
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");
276
304
  return n(), w("div", {
277
- class: se(B.value)
305
+ class: se(F.value)
278
306
  }, [
279
- y(e.$slots, "header"),
280
- t.showSearchSection ? (n(), w("div", fe, [
281
- h(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(e.$slots, "query-conditions", { searchForm: f }),
288
- h(b, { 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(e.$slots, "query-left"),
292
- h(l, {
293
- type: "primary",
294
- onClick: P,
295
- loading: r.value
296
- }, {
297
- default: u(() => o[6] || (o[6] = [
298
- v("搜索")
299
- ])),
300
- _: 1,
301
- __: [6]
302
- }, 8, ["loading"]),
303
- h(l, { onClick: J }, {
304
- default: u(() => o[7] || (o[7] = [
305
- v("清空")
306
- ])),
307
- _: 1,
308
- __: [7]
309
- }),
310
- y(e.$slots, "query-right")
318
+ I("div", me, [
319
+ b(t.$slots, "query-left"),
320
+ e.showSearchActionButtons ? (n(), w(A, { key: 0 }, [
321
+ v(l, {
322
+ type: "primary",
323
+ onClick: N,
324
+ loading: r.value
325
+ }, {
326
+ default: u(() => o[6] || (o[6] = [
327
+ _("搜索")
328
+ ])),
329
+ _: 1,
330
+ __: [6]
331
+ }, 8, ["loading"]),
332
+ v(l, { onClick: K }, {
333
+ default: u(() => o[7] || (o[7] = [
334
+ _("清空")
335
+ ])),
336
+ _: 1,
337
+ __: [7]
338
+ })
339
+ ], 64)) : m("", !0),
340
+ b(t.$slots, "query-right")
311
341
  ])
312
342
  ]),
313
343
  _: 3
@@ -315,43 +345,43 @@ const fe = {
315
345
  ]),
316
346
  _: 3
317
347
  }, 8, ["model"]),
318
- E("div", ge, [
319
- y(e.$slots, "action-left", { selections: d.value }),
320
- y(e.$slots, "add-button-content", {}, () => [
321
- t.showNewBtn ? (n(), p(l, {
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, {
322
352
  key: 0,
323
353
  type: "success",
324
354
  onClick: o[0] || (o[0] = (i) => x("add"))
325
355
  }, {
326
356
  default: u(() => o[8] || (o[8] = [
327
- v("新增")
357
+ _("新增")
328
358
  ])),
329
359
  _: 1,
330
360
  __: [8]
331
361
  })) : m("", !0)
332
362
  ]),
333
- y(e.$slots, "action-right")
363
+ b(t.$slots, "action-right")
334
364
  ])
335
365
  ])) : m("", !0),
336
- W((n(), p(oe, _({
337
- data: k.value,
338
- onSelectionChange: K
339
- }, e.$attrs, { style: { width: "100%", "margin-bottom": "1.5rem" } }), {
366
+ H((n(), p(oe, C({
367
+ data: B.value,
368
+ onSelectionChange: X
369
+ }, t.$attrs, { style: { width: "100%", "margin-bottom": "1.5rem" } }), {
340
370
  default: u(() => [
341
- t.showSelectionColumn ? (n(), p(O, {
371
+ e.showSelectionColumn ? (n(), p(O, {
342
372
  key: 0,
343
373
  type: "selection",
344
374
  width: "55",
345
375
  fixed: ""
346
376
  })) : m("", !0),
347
- t.showIndexColumn ? (n(), p(O, {
377
+ e.showIndexColumn ? (n(), p(O, {
348
378
  key: 1,
349
379
  type: "index",
350
380
  label: "序号",
351
381
  width: "70",
352
382
  fixed: ""
353
383
  })) : m("", !0),
354
- (n(!0), w($, null, q(t.columns, (i) => (n(), p(O, _({
384
+ (n(!0), w(A, null, j(e.columns, (i) => (n(), p(O, C({
355
385
  key: i.prop,
356
386
  prop: i.prop,
357
387
  label: i.label,
@@ -360,57 +390,57 @@ const fe = {
360
390
  }, { ref_for: !0 }, i.attrs), ue({ _: 2 }, [
361
391
  i.slot ? {
362
392
  name: "default",
363
- fn: u((R) => [
364
- y(e.$slots, i.slot, {
365
- row: R.row
393
+ fn: u((E) => [
394
+ b(t.$slots, i.slot, {
395
+ row: E.row
366
396
  })
367
397
  ]),
368
398
  key: "0"
369
399
  } : void 0
370
400
  ]), 1040, ["prop", "label", "width", "sortable"]))), 128)),
371
- t.showActionsColumn ? (n(), p(O, {
401
+ e.showActionsColumn ? (n(), p(O, {
372
402
  key: 2,
373
403
  label: "操作",
374
- width: c.actionsColumnWidth
404
+ width: g.actionsColumnWidth
375
405
  }, {
376
406
  default: u((i) => [
377
- i.row ? (n(), w("div", ce, [
378
- e.$slots.actions ? y(e.$slots, "actions", {
407
+ i.row ? (n(), w("div", ge, [
408
+ t.$slots.actions ? b(t.$slots, "actions", {
379
409
  key: 0,
380
410
  row: i.row
381
- }) : (n(), w($, { key: 1 }, [
382
- y(e.$slots, "action-before-edit", {
411
+ }) : (n(), w(A, { key: 1 }, [
412
+ b(t.$slots, "action-before-edit", {
383
413
  row: i.row
384
414
  }),
385
- t.showEditButton ? (n(), p(l, {
415
+ e.showEditButton ? (n(), p(l, {
386
416
  key: 0,
387
417
  size: "small",
388
418
  type: "primary",
389
419
  link: "",
390
- onClick: (R) => x("edit", i.row)
420
+ onClick: (E) => x("edit", i.row)
391
421
  }, {
392
422
  default: u(() => o[9] || (o[9] = [
393
- v("编辑 ")
423
+ _("编辑 ")
394
424
  ])),
395
425
  _: 2,
396
426
  __: [9]
397
427
  }, 1032, ["onClick"])) : m("", !0),
398
- t.showDeleteButton ? (n(), p(te, {
428
+ e.showDeleteButton ? (n(), p(te, {
399
429
  key: 1,
400
430
  title: "确定要删除这条数据吗?",
401
- onConfirm: (R) => I([i.row.id]),
431
+ onConfirm: (E) => T([i.row.id]),
402
432
  "confirm-button-text": "确定",
403
433
  "cancel-button-text": "取消",
404
434
  width: "200"
405
435
  }, {
406
436
  reference: u(() => [
407
- h(l, {
437
+ v(l, {
408
438
  size: "small",
409
439
  type: "danger",
410
440
  link: ""
411
441
  }, {
412
442
  default: u(() => o[10] || (o[10] = [
413
- v("删除")
443
+ _("删除")
414
444
  ])),
415
445
  _: 1,
416
446
  __: [10]
@@ -418,7 +448,7 @@ const fe = {
418
448
  ]),
419
449
  _: 2
420
450
  }, 1032, ["onConfirm"])) : m("", !0),
421
- y(e.$slots, "action-after-delete", {
451
+ b(t.$slots, "action-after-delete", {
422
452
  row: i.row
423
453
  })
424
454
  ], 64))
@@ -431,48 +461,48 @@ const fe = {
431
461
  }, 16, ["data"])), [
432
462
  [L, r.value]
433
463
  ]),
434
- t.showPagination && U.value > 0 ? (n(), w("div", ye, [
435
- h(le, {
464
+ e.showPagination && V.value > 0 ? (n(), w("div", ye, [
465
+ v(ae, {
436
466
  "current-page": f.pageNum,
437
467
  "onUpdate:currentPage": o[1] || (o[1] = (i) => f.pageNum = i),
438
468
  "page-size": f.pageSize,
439
469
  "onUpdate:pageSize": o[2] || (o[2] = (i) => f.pageSize = i),
440
- "page-sizes": t.pageSizes,
441
- layout: t.paginationLayout,
442
- total: U.value,
443
- background: t.paginationBackground,
444
- small: t.paginationSmall,
445
- "hide-on-single-page": t.paginationHideOnSinglePage,
446
- onSizeChange: Y,
447
- onCurrentChange: Z
470
+ "page-sizes": e.pageSizes,
471
+ layout: e.paginationLayout,
472
+ total: V.value,
473
+ background: e.paginationBackground,
474
+ small: e.paginationSmall,
475
+ "hide-on-single-page": e.paginationHideOnSinglePage,
476
+ onSizeChange: Z,
477
+ onCurrentChange: ee
448
478
  }, null, 8, ["current-page", "page-size", "page-sizes", "layout", "total", "background", "small", "hide-on-single-page"])
449
479
  ])) : m("", !0),
450
- h(ae, {
480
+ v(le, {
451
481
  modelValue: a.visible,
452
482
  "onUpdate:modelValue": o[5] || (o[5] = (i) => a.visible = i),
453
- title: M.value,
454
- width: t.dialogWidth,
483
+ title: G.value,
484
+ width: e.dialogWidth,
455
485
  "destroy-on-close": !0,
456
- "custom-class": Q.value
486
+ "custom-class": q.value
457
487
  }, {
458
488
  footer: u(() => [
459
- E("div", be, [
460
- h(l, {
489
+ I("div", be, [
490
+ v(l, {
461
491
  onClick: o[4] || (o[4] = (i) => a.visible = !1)
462
492
  }, {
463
493
  default: u(() => o[11] || (o[11] = [
464
- v("取消")
494
+ _("取消")
465
495
  ])),
466
496
  _: 1,
467
497
  __: [11]
468
498
  }),
469
- h(l, {
499
+ v(l, {
470
500
  type: "primary",
471
- onClick: X,
501
+ onClick: Y,
472
502
  loading: a.submitting
473
503
  }, {
474
504
  default: u(() => o[12] || (o[12] = [
475
- v("确定")
505
+ _("确定")
476
506
  ])),
477
507
  _: 1,
478
508
  __: [12]
@@ -480,18 +510,18 @@ const fe = {
480
510
  ])
481
511
  ]),
482
512
  default: u(() => [
483
- W((n(), w("div", null, [
484
- y(e.$slots, "dialog-form-content", {
513
+ H((n(), w("div", null, [
514
+ b(t.$slots, "dialog-form-content", {
485
515
  formData: a.data,
486
516
  mode: a.mode
487
517
  }, () => [
488
- t.dialogFormConfig.length > 0 ? (n(), p(pe, {
518
+ e.dialogFormConfig.length > 0 ? (n(), p(pe, {
489
519
  key: 0,
490
- "form-config": G.value,
520
+ "form-config": J.value,
491
521
  modelValue: a.data,
492
522
  "onUpdate:modelValue": o[3] || (o[3] = (i) => a.data = i),
493
523
  ref: (i) => a.formRef = i,
494
- rules: t.dialogFormRules,
524
+ rules: e.dialogFormRules,
495
525
  "label-width": "80px"
496
526
  }, null, 8, ["form-config", "modelValue", "rules"])) : m("", !0)
497
527
  ])
@@ -506,5 +536,5 @@ const fe = {
506
536
  }
507
537
  });
508
538
  export {
509
- _e as CrudTable
539
+ Se as CrudTable
510
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,o)=>{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},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},showNewBtn:{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,o=c,w=e.computed(()=>["crud-table-wrapper",`theme-${o.theme}`,o.customClass]),N=e.computed(()=>o.theme==="large-screen"?"large-screen-dialog":""),u=(t,l)=>t?!0:(h.ElMessage.error(`${l} prop is required.`),!1),V=async(t,l)=>{try{let a={...l};if(o.onBeforeSubmit&&(a=await o.onBeforeSubmit(a)),r.submitting=!0,t==="add"){if(!u(o.apiUrlCreate,"apiUrlCreate"))return;await g.post(o.apiUrlCreate,a),h.ElMessage.success("新增成功")}else{if(!u(o.apiUrlUpdate,"apiUrlUpdate"))return;await g.put(o.apiUrlUpdate,a),h.ElMessage.success("更新成功")}return o.onAfterSubmit&&o.onAfterSubmit(t,a),s("submit",{mode:t,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,...o.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 o.dialogFormConfig.filter(l=>l.prop!=="id");const t=[...o.dialogFormConfig.filter(l=>l.prop!=="id")];return t.some(l=>l.prop==="id")||t.unshift({type:"input-disabled",prop:"id",label:"用户ID"}),t}),B=async()=>{if(u(o.apiUrlQuery,"apiUrlQuery")){n.value=!0;try{let t={...p};o.onBeforeQuery&&(t=await o.onBeforeQuery(t));const l=await g.get(o.apiUrlQuery,{params:t});if(l&&Array.isArray(l.data.rows)&&typeof l.data.total=="number"){let a=l.data.rows;o.onAfterQuery&&(a=await o.onAfterQuery(a)),C.value=a,k.value=l.data.total}else console.warn("API response is not in the expected { data: [], total: 0 } format."),C.value=[],k.value=0}catch(t){console.error("Fetch data failed:",t)}finally{n.value=!1}}},S=()=>{p.pageNum=1,B()},L=()=>{const{pageNum:t,pageSize:l,...a}=o.initialSearchForm;Object.keys(p).forEach(m=>{m!=="pageNum"&&m!=="pageSize"&&delete p[m]}),Object.assign(p,a),S()},M=t=>{d.value=t},D=async(t,l)=>{let a;if(t==="add"?a=l?{...l}:{role:"user"}:a={...l},o.onBeforeOpenDialog){const m=await o.onBeforeOpenDialog(t,a);m&&(a=m)}if(r.mode=t,r.visible=!0,t==="edit"){if(!u(o.apiUrlDetail,"apiUrlDetail"))return;r.loading=!0;try{const m=await g.get(o.apiUrlDetail,{params:{id:a.id}});r.data=m.data}finally{r.loading=!1,o.onAfterOpenDialog&&o.onAfterOpenDialog(t,r.data),s("open-dialog",{mode:t,data:r.data})}}else r.data=a,o.onAfterOpenDialog&&o.onAfterOpenDialog(t,r.data),s("open-dialog",{mode:t,data:r.data})},I=async()=>{try{r.formRef&&await r.formRef.validate(),await V(r.mode,r.data)}catch(t){console.log("Validation failed:",t)}},U=async t=>{if(u(o.apiUrlDelete,"apiUrlDelete"))try{if(o.onBeforeDelete&&await o.onBeforeDelete(t)===!1)return;const l=t.join(",");await g.delete(o.apiUrlDelete+"/"+l.toString()),h.ElMessage.success("删除成功"),o.onAfterDelete&&o.onAfterDelete(t),s("delete",t),C.value.length===t.length&&p.pageNum>1&&p.pageNum--,B()}catch(l){console.error("Delete failed",l)}},W=t=>{p.pageSize=t,S()},H=t=>{p.pageNum=t,B()};return e.onMounted(B),y({refresh:B,search:S,handleDelete:U,openDialog:D,submit:V}),(t,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(t.$slots,"header"),o.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(t.$slots,"query-conditions",{searchForm:p}),e.createVNode(m,{class:"!mr-0 flex-shrink-0"},{default:e.withCtx(()=>[e.createElementVNode("div",z,[e.renderSlot(t.$slots,"query-left"),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]}),e.renderSlot(t.$slots,"query-right")])]),_:3})]),_:3},8,["model"]),e.createElementVNode("div",P,[e.renderSlot(t.$slots,"action-left",{selections:d.value}),e.renderSlot(t.$slots,"add-button-content",{},()=>[o.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(t.$slots,"action-right")])])):e.createCommentVNode("",!0),e.withDirectives((e.openBlock(),e.createBlock(J,e.mergeProps({data:C.value,onSelectionChange:M},t.$attrs,{style:{width:"100%","margin-bottom":"1.5rem"}}),{default:e.withCtx(()=>[o.showSelectionColumn?(e.openBlock(),e.createBlock(_,{key:0,type:"selection",width:"55",fixed:""})):e.createCommentVNode("",!0),o.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(o.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(t.$slots,i.slot,{row:x.row})]),key:"0"}:void 0]),1040,["prop","label","width","sortable"]))),128)),o.showActionsColumn?(e.openBlock(),e.createBlock(_,{key:2,label:"操作",width:c.actionsColumnWidth},{default:e.withCtx(i=>[i.row?(e.openBlock(),e.createElementBlock("div",O,[t.$slots.actions?e.renderSlot(t.$slots,"actions",{key:0,row:i.row}):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.renderSlot(t.$slots,"action-before-edit",{row:i.row}),o.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),o.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(t.$slots,"action-after-delete",{row:i.row})],64))])):e.createCommentVNode("",!0)]),_:3},8,["width"])):e.createCommentVNode("",!0)]),_:3},16,["data"])),[[F,n.value]]),o.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":o.pageSizes,layout:o.paginationLayout,total:k.value,background:o.paginationBackground,small:o.paginationSmall,"hide-on-single-page":o.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:o.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(t.$slots,"dialog-form-content",{formData:r.data,mode:r.mode},()=>[o.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:o.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.22",
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": [