yd-admin 0.1.4 → 0.1.5

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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Fragment, Teleport, Transition, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, h, inject, isRef, mergeProps, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, reactive, ref, renderList, renderSlot, resolveComponent, resolveDynamicComponent, toDisplayString, unref, useSlots, vModelCheckbox, vModelDynamic, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
1
+ import { Fragment, Teleport, Transition, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, getCurrentInstance, h, inject, isRef, mergeProps, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, reactive, ref, renderList, renderSlot, resolveComponent, resolveDynamicComponent, toDisplayString, unref, useCssVars, useSlots, vModelCheckbox, vModelDynamic, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
2
2
  import AsyncValidator from "async-validator";
3
3
  import { createI18n } from "vue-i18n";
4
4
  //#region \0rolldown/runtime.js
@@ -160,6 +160,213 @@ var SecureStorage = class {
160
160
  const secureLocal = new SecureStorage("local");
161
161
  const secureSession = new SecureStorage("session");
162
162
  //#endregion
163
+ //#region src/utils/router.ts
164
+ /**
165
+ * 动态路由管理器
166
+ */
167
+ var DynamicRouter = class {
168
+ routes = [];
169
+ routeMap = /* @__PURE__ */ new Map();
170
+ /**
171
+ * 设置路由列表
172
+ */
173
+ setRoutes(routes) {
174
+ this.routes = routes;
175
+ this.buildRouteMap();
176
+ }
177
+ /**
178
+ * 获取路由列表
179
+ */
180
+ getRoutes() {
181
+ return this.routes;
182
+ }
183
+ /**
184
+ * 构建路由映射
185
+ */
186
+ buildRouteMap() {
187
+ this.routeMap.clear();
188
+ const buildMap = (routeList) => {
189
+ for (const route of routeList) {
190
+ this.routeMap.set(route.path, route);
191
+ if (route.children) buildMap(route.children);
192
+ }
193
+ };
194
+ buildMap(this.routes);
195
+ }
196
+ /**
197
+ * 根据路径获取路由
198
+ */
199
+ getRoute(path) {
200
+ return this.routeMap.get(path);
201
+ }
202
+ /**
203
+ * 检查路由是否存在
204
+ */
205
+ hasRoute(path) {
206
+ return this.routeMap.has(path);
207
+ }
208
+ /**
209
+ * 添加路由
210
+ */
211
+ addRoute(route, parentPath = "") {
212
+ const fullPath = parentPath ? `${parentPath}/${route.path}` : route.path;
213
+ const newRoute = {
214
+ ...route,
215
+ path: fullPath
216
+ };
217
+ this.routes.push(newRoute);
218
+ this.routeMap.set(fullPath, newRoute);
219
+ }
220
+ /**
221
+ * 移除路由
222
+ */
223
+ removeRoute(path) {
224
+ const route = this.routeMap.get(path);
225
+ if (!route) return false;
226
+ const index = this.routes.indexOf(route);
227
+ if (index > -1) {
228
+ this.routes.splice(index, 1);
229
+ this.routeMap.delete(path);
230
+ return true;
231
+ }
232
+ return false;
233
+ }
234
+ /**
235
+ * 获取可见路由(根据 meta.hidden)
236
+ */
237
+ getVisibleRoutes() {
238
+ const filterVisible = (list) => {
239
+ return list.filter((r) => !r.meta?.hidden).map((r) => ({
240
+ ...r,
241
+ children: r.children ? filterVisible(r.children) : void 0
242
+ }));
243
+ };
244
+ return filterVisible(this.routes);
245
+ }
246
+ /**
247
+ * 根据权限过滤路由
248
+ */
249
+ filterByRoles(roles) {
250
+ const filterRoles = (list) => {
251
+ return list.filter((r) => {
252
+ const routeRoles = r.meta?.roles;
253
+ if (!routeRoles || routeRoles.length === 0) return true;
254
+ return routeRoles.some((role) => roles.includes(role));
255
+ }).map((r) => ({
256
+ ...r,
257
+ children: r.children ? filterRoles(r.children) : void 0
258
+ }));
259
+ };
260
+ return filterRoles(this.routes);
261
+ }
262
+ /**
263
+ * 扁平化路由
264
+ */
265
+ flattenRoutes(routes = this.routes) {
266
+ const result = [];
267
+ const flatten = (list) => {
268
+ for (const r of list) {
269
+ result.push(r);
270
+ if (r.children && r.children.length > 0) flatten(r.children);
271
+ }
272
+ };
273
+ flatten(routes);
274
+ return result;
275
+ }
276
+ /**
277
+ * 路径匹配
278
+ */
279
+ matchPath(path, pattern) {
280
+ if (typeof pattern === "string") return path === pattern || path.startsWith(pattern + "/");
281
+ return pattern.test(path);
282
+ }
283
+ /**
284
+ * 查找路由名称
285
+ */
286
+ findRouteByName(name) {
287
+ for (const route of this.routeMap.values()) if (route.name === name) return route;
288
+ }
289
+ /**
290
+ * 查找路由路径
291
+ */
292
+ findPathByName(name) {
293
+ return this.findRouteByName(name)?.path ?? null;
294
+ }
295
+ };
296
+ /**
297
+ * 路由工具单例
298
+ */
299
+ const dynamicRouter = new DynamicRouter();
300
+ /**
301
+ * 路径规范化
302
+ */
303
+ function normalizePath(path) {
304
+ return path.replace(/\/+/g, "/").replace(/\/$/, "") || "/";
305
+ }
306
+ /**
307
+ * 路径拼接
308
+ */
309
+ function joinPath(...parts) {
310
+ return normalizePath(parts.filter(Boolean).join("/"));
311
+ }
312
+ /**
313
+ * 路径匹配检查
314
+ */
315
+ function isPathMatch(path, pattern) {
316
+ if (typeof pattern === "string") return path === pattern || path.startsWith(pattern + "/");
317
+ return pattern.test(path);
318
+ }
319
+ /**
320
+ * 路由权限检查
321
+ */
322
+ function checkRoutePermission(route, userRoles) {
323
+ if (!route?.meta?.roles || route.meta.roles.length === 0) return true;
324
+ return route.meta.roles.some((role) => userRoles.includes(role));
325
+ }
326
+ /**
327
+ * 路由标题生成器
328
+ */
329
+ function generateRouteTitle(title, prefix = "") {
330
+ return prefix ? `${prefix} - ${title}` : title;
331
+ }
332
+ /**
333
+ * 构建面包屑
334
+ */
335
+ function buildBreadcrumb(path, routes = dynamicRouter.getRoutes()) {
336
+ const breadcrumb = [];
337
+ const findPath = (list, target) => {
338
+ for (const route of list) {
339
+ if (route.path === target) {
340
+ breadcrumb.push(route);
341
+ return true;
342
+ }
343
+ if (route.children) {
344
+ breadcrumb.push(route);
345
+ if (findPath(route.children, target)) return true;
346
+ breadcrumb.pop();
347
+ }
348
+ }
349
+ return false;
350
+ };
351
+ findPath(routes, path);
352
+ return breadcrumb;
353
+ }
354
+ /**
355
+ * 路由记录类型转换
356
+ */
357
+ function convertToSimpleRoute(route) {
358
+ const simpleRedirect = route.redirect;
359
+ const redirectValue = typeof simpleRedirect === "string" ? simpleRedirect : typeof simpleRedirect === "object" && simpleRedirect !== null ? simpleRedirect.path : void 0;
360
+ return {
361
+ path: route.path,
362
+ name: route.name,
363
+ component: route.component,
364
+ children: route.children?.map(convertToSimpleRoute),
365
+ redirect: redirectValue,
366
+ meta: route.meta
367
+ };
368
+ }
369
+ //#endregion
163
370
  //#region src/utils/index.ts
164
371
  /**
165
372
  * Utility functions
@@ -257,12 +464,12 @@ var export_helper_default = (sfc, props) => {
257
464
  };
258
465
  //#endregion
259
466
  //#region src/components/base/button/button.vue
260
- const _hoisted_1$42 = ["disabled", "type"];
261
- const _hoisted_2$23 = {
467
+ const _hoisted_1$44 = ["disabled", "type"];
468
+ const _hoisted_2$26 = {
262
469
  key: 0,
263
470
  class: "yd-button__loading"
264
471
  };
265
- const _hoisted_3$15 = { class: "yd-button__content" };
472
+ const _hoisted_3$17 = { class: "yd-button__content" };
266
473
  var button_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
267
474
  name: "YdButton",
268
475
  __name: "button",
@@ -307,7 +514,7 @@ var button_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
307
514
  disabled: __props.disabled || __props.loading,
308
515
  type: __props.nativeType,
309
516
  onClick: handleClick
310
- }, [__props.loading ? (openBlock(), createElementBlock("span", _hoisted_2$23, [..._cache[0] || (_cache[0] = [createElementVNode("svg", {
517
+ }, [__props.loading ? (openBlock(), createElementBlock("span", _hoisted_2$26, [..._cache[0] || (_cache[0] = [createElementVNode("svg", {
311
518
  class: "yd-button__spinner",
312
519
  viewBox: "0 0 24 24"
313
520
  }, [createElementVNode("circle", {
@@ -319,13 +526,13 @@ var button_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
319
526
  "stroke-width": "3",
320
527
  "stroke-dasharray": "31.4 31.4",
321
528
  "stroke-linecap": "round"
322
- })], -1)])])) : createCommentVNode("v-if", true), createElementVNode("span", _hoisted_3$15, [renderSlot(_ctx.$slots, "default", {}, void 0, true)])], 10, _hoisted_1$42);
529
+ })], -1)])])) : createCommentVNode("v-if", true), createElementVNode("span", _hoisted_3$17, [renderSlot(_ctx.$slots, "default", {}, void 0, true)])], 10, _hoisted_1$44);
323
530
  };
324
531
  }
325
- }), [["__scopeId", "data-v-7c52cbce"]]);
532
+ }), [["__scopeId", "data-v-6f15c079"]]);
326
533
  //#endregion
327
534
  //#region src/components/base/input/input.vue
328
- const _hoisted_1$41 = [
535
+ const _hoisted_1$43 = [
329
536
  "type",
330
537
  "value",
331
538
  "placeholder",
@@ -434,7 +641,7 @@ var input_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
434
641
  onFocus: handleFocus,
435
642
  onBlur: handleBlur,
436
643
  onKeydown: handleKeydown
437
- }, null, 42, _hoisted_1$41),
644
+ }, null, 42, _hoisted_1$43),
438
645
  __props.clearable && __props.modelValue && !__props.disabled ? (openBlock(), createElementBlock("span", {
439
646
  key: 1,
440
647
  class: normalizeClass(e("clear")),
@@ -474,7 +681,7 @@ var input_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
474
681
  }), [["__scopeId", "data-v-9f5a78f3"]]);
475
682
  //#endregion
476
683
  //#region src/components/base/textarea/textarea.vue
477
- const _hoisted_1$40 = [
684
+ const _hoisted_1$42 = [
478
685
  "value",
479
686
  "placeholder",
480
687
  "disabled",
@@ -568,7 +775,7 @@ var textarea_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
568
775
  onChange: handleChange,
569
776
  onFocus: handleFocus,
570
777
  onBlur: handleBlur
571
- }, null, 42, _hoisted_1$40), __props.showWordLimit && __props.maxlength ? (openBlock(), createElementBlock("span", {
778
+ }, null, 42, _hoisted_1$42), __props.showWordLimit && __props.maxlength ? (openBlock(), createElementBlock("span", {
572
779
  key: 0,
573
780
  class: normalizeClass(e("word-limit"))
574
781
  }, toDisplayString(String(__props.modelValue).length) + "/" + toDisplayString(__props.maxlength), 3)) : createCommentVNode("v-if", true)], 2);
@@ -577,9 +784,9 @@ var textarea_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
577
784
  }), [["__scopeId", "data-v-13af2da6"]]);
578
785
  //#endregion
579
786
  //#region src/components/base/input-number/input-number.vue
580
- const _hoisted_1$39 = ["disabled"];
581
- const _hoisted_2$22 = ["value", "disabled"];
582
- const _hoisted_3$14 = ["disabled"];
787
+ const _hoisted_1$41 = ["disabled"];
788
+ const _hoisted_2$25 = ["value", "disabled"];
789
+ const _hoisted_3$16 = ["disabled"];
583
790
  var input_number_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
584
791
  name: "YdInputNumber",
585
792
  __name: "input-number",
@@ -674,7 +881,7 @@ var input_number_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
674
881
  y1: "12",
675
882
  x2: "19",
676
883
  y2: "12"
677
- })], -1)])], 10, _hoisted_1$39),
884
+ })], -1)])], 10, _hoisted_1$41),
678
885
  createElementVNode("input", {
679
886
  ref_key: "inputRef",
680
887
  ref: inputRef,
@@ -685,7 +892,7 @@ var input_number_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
685
892
  onInput: handleInput,
686
893
  onBlur: handleBlur,
687
894
  onKeydown: handleKeydown
688
- }, null, 42, _hoisted_2$22),
895
+ }, null, 42, _hoisted_2$25),
689
896
  createElementVNode("button", {
690
897
  class: normalizeClass(e("btn")),
691
898
  disabled: __props.disabled || __props.modelValue >= __props.max,
@@ -710,7 +917,7 @@ var input_number_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
710
917
  y1: "12",
711
918
  x2: "19",
712
919
  y2: "12"
713
- })], -1)])], 10, _hoisted_3$14)
920
+ })], -1)])], 10, _hoisted_3$16)
714
921
  ], 2)], 2);
715
922
  };
716
923
  }
@@ -762,13 +969,13 @@ var empty_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
762
969
  }), [["__scopeId", "data-v-ed413d74"]]);
763
970
  //#endregion
764
971
  //#region src/components/base/select/select.vue
765
- const _hoisted_1$38 = [
972
+ const _hoisted_1$40 = [
766
973
  "value",
767
974
  "placeholder",
768
975
  "disabled"
769
976
  ];
770
- const _hoisted_2$21 = ["onClick"];
771
- const _hoisted_3$13 = ["onClick"];
977
+ const _hoisted_2$24 = ["onClick"];
978
+ const _hoisted_3$15 = ["onClick"];
772
979
  var select_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
773
980
  name: "YdSelect",
774
981
  inheritAttrs: false,
@@ -995,7 +1202,7 @@ var select_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
995
1202
  onFocus: handleFocus,
996
1203
  onBlur: handleBlur,
997
1204
  onKeydown: _cache[0] || (_cache[0] = withModifiers(() => {}, ["stop"]))
998
- }, null, 42, _hoisted_1$38)) : (openBlock(), createElementBlock("div", {
1205
+ }, null, 42, _hoisted_1$40)) : (openBlock(), createElementBlock("div", {
999
1206
  key: 1,
1000
1207
  class: normalizeClass([e("display"), { [e("display--placeholder")]: !selectedLabel.value }])
1001
1208
  }, toDisplayString(selectedLabel.value || __props.placeholder), 3)),
@@ -1072,7 +1279,7 @@ var select_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
1072
1279
  }, [createElementVNode("span", null, toDisplayString(opt.label), 1), isSelected(opt.value) ? (openBlock(), createElementBlock("span", {
1073
1280
  key: 0,
1074
1281
  class: normalizeClass(e("check"))
1075
- }, "✓", 2)) : createCommentVNode("v-if", true)], 10, _hoisted_2$21);
1282
+ }, "✓", 2)) : createCommentVNode("v-if", true)], 10, _hoisted_2$24);
1076
1283
  }), 128))], 2)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Option "), createElementVNode("div", {
1077
1284
  class: normalizeClass([e("option"), {
1078
1285
  [e("option--active")]: isSelected(option.value),
@@ -1082,7 +1289,7 @@ var select_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
1082
1289
  }, [createElementVNode("span", null, toDisplayString(option.label), 1), isSelected(option.value) ? (openBlock(), createElementBlock("span", {
1083
1290
  key: 0,
1084
1291
  class: normalizeClass(e("check"))
1085
- }, "✓", 2)) : createCommentVNode("v-if", true)], 10, _hoisted_3$13)], 2112))], 64);
1292
+ }, "✓", 2)) : createCommentVNode("v-if", true)], 10, _hoisted_3$15)], 2112))], 64);
1086
1293
  }), 128))], 6))], 6)) : createCommentVNode("v-if", true)]),
1087
1294
  _: 1
1088
1295
  })]))
@@ -1092,7 +1299,7 @@ var select_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
1092
1299
  }), [["__scopeId", "data-v-bea52552"]]);
1093
1300
  //#endregion
1094
1301
  //#region src/components/base/switch/switch.vue
1095
- const _hoisted_1$37 = ["aria-checked", "disabled"];
1302
+ const _hoisted_1$39 = ["aria-checked", "disabled"];
1096
1303
  var switch_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
1097
1304
  name: "YdSwitch",
1098
1305
  __name: "switch",
@@ -1128,13 +1335,13 @@ var switch_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
1128
1335
  class: normalizeClass(switchClasses.value),
1129
1336
  disabled: __props.disabled,
1130
1337
  onClick: toggle
1131
- }, [createElementVNode("span", { class: normalizeClass(e("thumb")) }, null, 2)], 10, _hoisted_1$37);
1338
+ }, [createElementVNode("span", { class: normalizeClass(e("thumb")) }, null, 2)], 10, _hoisted_1$39);
1132
1339
  };
1133
1340
  }
1134
- }), [["__scopeId", "data-v-3f00ad5e"]]);
1341
+ }), [["__scopeId", "data-v-178da0de"]]);
1135
1342
  //#endregion
1136
1343
  //#region src/components/base/checkbox/checkbox.vue
1137
- const _hoisted_1$36 = [
1344
+ const _hoisted_1$38 = [
1138
1345
  "checked",
1139
1346
  "disabled",
1140
1347
  "value"
@@ -1187,7 +1394,7 @@ var checkbox_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
1187
1394
  disabled: __props.disabled,
1188
1395
  value: __props.value,
1189
1396
  onChange: handleChange
1190
- }, null, 42, _hoisted_1$36),
1397
+ }, null, 42, _hoisted_1$38),
1191
1398
  createElementVNode("span", { class: normalizeClass(e("box")) }, [__props.modelValue ? (openBlock(), createElementBlock("svg", {
1192
1399
  key: 0,
1193
1400
  class: normalizeClass(e("icon")),
@@ -1208,7 +1415,7 @@ var checkbox_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
1208
1415
  ], 2);
1209
1416
  };
1210
1417
  }
1211
- }), [["__scopeId", "data-v-161dff57"]]);
1418
+ }), [["__scopeId", "data-v-85b4197e"]]);
1212
1419
  var checkbox_group_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
1213
1420
  name: "YdCheckboxGroup",
1214
1421
  __name: "checkbox-group",
@@ -1254,7 +1461,7 @@ var checkbox_group_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
1254
1461
  }), [["__scopeId", "data-v-3dce3e2c"]]);
1255
1462
  //#endregion
1256
1463
  //#region src/components/base/radio/radio.vue
1257
- const _hoisted_1$35 = [
1464
+ const _hoisted_1$37 = [
1258
1465
  "checked",
1259
1466
  "disabled",
1260
1467
  "value",
@@ -1310,7 +1517,7 @@ var radio_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
1310
1517
  value: __props.value,
1311
1518
  name: __props.name,
1312
1519
  onChange: handleChange
1313
- }, null, 42, _hoisted_1$35),
1520
+ }, null, 42, _hoisted_1$37),
1314
1521
  createElementVNode("span", { class: normalizeClass(e("dot")) }, null, 2),
1315
1522
  _ctx.$slots.default || __props.label ? (openBlock(), createElementBlock("span", {
1316
1523
  key: 0,
@@ -1427,10 +1634,10 @@ var tag_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineCo
1427
1634
  })], -1)])], 2)) : createCommentVNode("v-if", true)], 2);
1428
1635
  };
1429
1636
  }
1430
- }), [["__scopeId", "data-v-68856db4"]]);
1637
+ }), [["__scopeId", "data-v-ae4235fd"]]);
1431
1638
  //#endregion
1432
1639
  //#region src/components/base/avatar/avatar.vue
1433
- const _hoisted_1$34 = ["src", "alt"];
1640
+ const _hoisted_1$36 = ["src", "alt"];
1434
1641
  var avatar_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
1435
1642
  name: "YdAvatar",
1436
1643
  __name: "avatar",
@@ -1458,7 +1665,7 @@ var avatar_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
1458
1665
  src: __props.src,
1459
1666
  alt: __props.alt,
1460
1667
  onError: handleError
1461
- }, null, 40, _hoisted_1$34)) : _ctx.$slots.default ? (openBlock(), createElementBlock("span", {
1668
+ }, null, 40, _hoisted_1$36)) : _ctx.$slots.default ? (openBlock(), createElementBlock("span", {
1462
1669
  key: 1,
1463
1670
  class: normalizeClass(e("text"))
1464
1671
  }, [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 2)) : (openBlock(), createElementBlock("span", {
@@ -1515,10 +1722,10 @@ var badge_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
1515
1722
  }, [showNumber.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(displayValue.value), 1)], 64)) : createCommentVNode("v-if", true)], 6)) : createCommentVNode("v-if", true)], 2);
1516
1723
  };
1517
1724
  }
1518
- }), [["__scopeId", "data-v-bb44e78d"]]);
1725
+ }), [["__scopeId", "data-v-9b63f1ae"]]);
1519
1726
  //#endregion
1520
1727
  //#region src/components/base/rate/rate.vue
1521
- const _hoisted_1$33 = ["onClick", "onMouseenter"];
1728
+ const _hoisted_1$35 = ["onClick", "onMouseenter"];
1522
1729
  var rate_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
1523
1730
  name: "YdRate",
1524
1731
  __name: "rate",
@@ -1583,14 +1790,14 @@ var rate_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineC
1583
1790
  viewBox: "0 0 24 24",
1584
1791
  fill: "currentColor",
1585
1792
  stroke: "none"
1586
- }, [..._cache[1] || (_cache[1] = [createElementVNode("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" }, null, -1)])], 2))], 42, _hoisted_1$33);
1793
+ }, [..._cache[1] || (_cache[1] = [createElementVNode("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" }, null, -1)])], 2))], 42, _hoisted_1$35);
1587
1794
  }), 128)), __props.showText ? (openBlock(), createElementBlock("span", {
1588
1795
  key: 0,
1589
1796
  class: normalizeClass(e("text"))
1590
1797
  }, toDisplayString(__props.texts[Math.ceil(__props.modelValue) - 1] || `${__props.modelValue}分`), 3)) : createCommentVNode("v-if", true)], 2);
1591
1798
  };
1592
1799
  }
1593
- }), [["__scopeId", "data-v-82987348"]]);
1800
+ }), [["__scopeId", "data-v-52b27a1b"]]);
1594
1801
  var slider_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
1595
1802
  name: "YdSlider",
1596
1803
  __name: "slider",
@@ -1669,17 +1876,17 @@ var slider_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
1669
1876
  }, toDisplayString(__props.modelValue), 7)) : createCommentVNode("v-if", true)], 2);
1670
1877
  };
1671
1878
  }
1672
- }), [["__scopeId", "data-v-ad53f18b"]]);
1879
+ }), [["__scopeId", "data-v-51e82523"]]);
1673
1880
  //#endregion
1674
1881
  //#region src/components/base/date-picker/date-picker.vue
1675
- const _hoisted_1$32 = [
1882
+ const _hoisted_1$34 = [
1676
1883
  "value",
1677
1884
  "placeholder",
1678
1885
  "disabled"
1679
1886
  ];
1680
- const _hoisted_2$20 = ["onClick"];
1681
- const _hoisted_3$12 = ["onClick"];
1682
- const _hoisted_4$11 = ["disabled", "onClick"];
1887
+ const _hoisted_2$23 = ["onClick"];
1888
+ const _hoisted_3$14 = ["onClick"];
1889
+ const _hoisted_4$13 = ["disabled", "onClick"];
1683
1890
  var date_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
1684
1891
  name: "YdDatePicker",
1685
1892
  __name: "date-picker",
@@ -1730,7 +1937,6 @@ var date_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
1730
1937
  });
1731
1938
  const panelStyle = computed(() => {
1732
1939
  if (!triggerRef.value) return {};
1733
- positionKey.value;
1734
1940
  const rect = triggerRef.value.getBoundingClientRect();
1735
1941
  return {
1736
1942
  position: "fixed",
@@ -1884,7 +2090,7 @@ var date_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
1884
2090
  disabled: __props.disabled,
1885
2091
  readonly: "",
1886
2092
  onClick: withModifiers(togglePicker, ["stop"])
1887
- }, null, 10, _hoisted_1$32),
2093
+ }, null, 10, _hoisted_1$34),
1888
2094
  createElementVNode("span", {
1889
2095
  class: normalizeClass(e("icon")),
1890
2096
  onClick: withModifiers(togglePicker, ["stop"])
@@ -1908,13 +2114,13 @@ var date_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
1908
2114
  key: y,
1909
2115
  class: normalizeClass([e("year"), { [e("year--selected")]: selectedYear.value === y }]),
1910
2116
  onClick: withModifiers(($event) => selectYear(y), ["stop"])
1911
- }, toDisplayString(y), 11, _hoisted_2$20);
2117
+ }, toDisplayString(y), 11, _hoisted_2$23);
1912
2118
  }), 128))], 2)], 2)) : view.value === "month" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Month selection "), createElementVNode("div", { class: normalizeClass(e("view")) }, [createElementVNode("div", { class: normalizeClass(e("view-header")) }, [createElementVNode("button", { onClick: _cache[0] || (_cache[0] = withModifiers(($event) => view.value = "year", ["stop"])) }, toDisplayString(selectedYear.value), 1)], 2), createElementVNode("div", { class: normalizeClass(e("months")) }, [(openBlock(), createElementBlock(Fragment, null, renderList(months, (m, i) => {
1913
2119
  return createElementVNode("button", {
1914
2120
  key: i,
1915
2121
  class: normalizeClass([e("month"), { [e("month--selected")]: selectedMonth.value === i }]),
1916
2122
  onClick: withModifiers(($event) => selectMonth(i), ["stop"])
1917
- }, toDisplayString(m), 11, _hoisted_3$12);
2123
+ }, toDisplayString(m), 11, _hoisted_3$14);
1918
2124
  }), 64))], 2)], 2)], 2112)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [createCommentVNode(" Date selection "), createElementVNode("div", { class: normalizeClass(e("view")) }, [
1919
2125
  createElementVNode("div", { class: normalizeClass(e("header")) }, [
1920
2126
  createElementVNode("button", { onClick: withModifiers(prevMonth, ["stop"]) }, "‹"),
@@ -1945,21 +2151,21 @@ var date_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
1945
2151
  }]),
1946
2152
  disabled: !day.current,
1947
2153
  onClick: withModifiers(($event) => selectDate(day), ["stop"])
1948
- }, toDisplayString(day.date.getDate()), 11, _hoisted_4$11);
2154
+ }, toDisplayString(day.date.getDate()), 11, _hoisted_4$13);
1949
2155
  }), 128))], 2)
1950
2156
  ], 2)], 2112))], 38)) : createCommentVNode("v-if", true)]))
1951
2157
  ], 2);
1952
2158
  };
1953
2159
  }
1954
- }), [["__scopeId", "data-v-7cec74da"]]);
2160
+ }), [["__scopeId", "data-v-6e664fd9"]]);
1955
2161
  //#endregion
1956
2162
  //#region src/components/base/date-picker/date-range-picker.vue
1957
- const _hoisted_1$31 = [
2163
+ const _hoisted_1$33 = [
1958
2164
  "value",
1959
2165
  "placeholder",
1960
2166
  "disabled"
1961
2167
  ];
1962
- const _hoisted_2$19 = [
2168
+ const _hoisted_2$22 = [
1963
2169
  "disabled",
1964
2170
  "onClick",
1965
2171
  "onMouseenter"
@@ -2125,7 +2331,7 @@ var date_range_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE
2125
2331
  placeholder: __props.placeholder,
2126
2332
  disabled: __props.disabled,
2127
2333
  readonly: ""
2128
- }, null, 10, _hoisted_1$31),
2334
+ }, null, 10, _hoisted_1$33),
2129
2335
  createElementVNode("span", { class: normalizeClass(e("icon")) }, "📅", 2),
2130
2336
  (openBlock(), createBlock(Teleport, { to: "body" }, [visible.value ? (openBlock(), createElementBlock("div", {
2131
2337
  key: 0,
@@ -2163,23 +2369,23 @@ var date_range_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE
2163
2369
  onClick: withModifiers(($event) => selectDate(day), ["stop"]),
2164
2370
  onMouseenter: ($event) => hoverDate.value = formatDate(day.date),
2165
2371
  onMouseleave: _cache[0] || (_cache[0] = ($event) => hoverDate.value = "")
2166
- }, toDisplayString(day.date.getDate()), 43, _hoisted_2$19);
2372
+ }, toDisplayString(day.date.getDate()), 43, _hoisted_2$22);
2167
2373
  }), 128))], 2)
2168
2374
  ], 6)) : createCommentVNode("v-if", true)]))
2169
2375
  ], 2);
2170
2376
  };
2171
2377
  }
2172
- }), [["__scopeId", "data-v-3a1246c0"]]);
2378
+ }), [["__scopeId", "data-v-c307df48"]]);
2173
2379
  //#endregion
2174
2380
  //#region src/components/base/time-picker/time-picker.vue
2175
- const _hoisted_1$30 = [
2381
+ const _hoisted_1$32 = [
2176
2382
  "value",
2177
2383
  "placeholder",
2178
2384
  "disabled"
2179
2385
  ];
2180
- const _hoisted_2$18 = ["onClick"];
2181
- const _hoisted_3$11 = ["onClick"];
2182
- const _hoisted_4$10 = ["onClick"];
2386
+ const _hoisted_2$21 = ["onClick"];
2387
+ const _hoisted_3$13 = ["onClick"];
2388
+ const _hoisted_4$12 = ["onClick"];
2183
2389
  var time_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
2184
2390
  name: "YdTimePicker",
2185
2391
  __name: "time-picker",
@@ -2256,7 +2462,7 @@ var time_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
2256
2462
  placeholder: __props.placeholder,
2257
2463
  disabled: __props.disabled,
2258
2464
  readonly: ""
2259
- }, null, 10, _hoisted_1$30), (openBlock(), createBlock(Teleport, { to: "body" }, [visible.value ? (openBlock(), createElementBlock("div", {
2465
+ }, null, 10, _hoisted_1$32), (openBlock(), createBlock(Teleport, { to: "body" }, [visible.value ? (openBlock(), createElementBlock("div", {
2260
2466
  key: 0,
2261
2467
  class: normalizeClass(e("panel")),
2262
2468
  style: normalizeStyle(panelStyle.value)
@@ -2266,14 +2472,14 @@ var time_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
2266
2472
  key: h - 1,
2267
2473
  class: normalizeClass([e("item"), { [e("item--active")]: selectedHour.value === h - 1 }]),
2268
2474
  onClick: ($event) => selectHour(h - 1)
2269
- }, toDisplayString(String(h - 1).padStart(2, "0")), 11, _hoisted_2$18);
2475
+ }, toDisplayString(String(h - 1).padStart(2, "0")), 11, _hoisted_2$21);
2270
2476
  }), 64))], 2),
2271
2477
  createElementVNode("div", { class: normalizeClass(e("column")) }, [(openBlock(), createElementBlock(Fragment, null, renderList(60, (m) => {
2272
2478
  return createElementVNode("div", {
2273
2479
  key: m - 1,
2274
2480
  class: normalizeClass([e("item"), { [e("item--active")]: selectedMinute.value === m - 1 }]),
2275
2481
  onClick: ($event) => selectMinute(m - 1)
2276
- }, toDisplayString(String(m - 1).padStart(2, "0")), 11, _hoisted_3$11);
2482
+ }, toDisplayString(String(m - 1).padStart(2, "0")), 11, _hoisted_3$13);
2277
2483
  }), 64))], 2),
2278
2484
  __props.showSeconds ? (openBlock(), createElementBlock("div", {
2279
2485
  key: 0,
@@ -2283,23 +2489,23 @@ var time_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */
2283
2489
  key: s - 1,
2284
2490
  class: normalizeClass([e("item"), { [e("item--active")]: selectedSecond.value === s - 1 }]),
2285
2491
  onClick: ($event) => selectSecond(s - 1)
2286
- }, toDisplayString(String(s - 1).padStart(2, "0")), 11, _hoisted_4$10);
2492
+ }, toDisplayString(String(s - 1).padStart(2, "0")), 11, _hoisted_4$12);
2287
2493
  }), 64))], 2)) : createCommentVNode("v-if", true)
2288
2494
  ], 2)], 6)) : createCommentVNode("v-if", true)]))], 2);
2289
2495
  };
2290
2496
  }
2291
- }), [["__scopeId", "data-v-71c12ad9"]]);
2497
+ }), [["__scopeId", "data-v-a6fe401a"]]);
2292
2498
  //#endregion
2293
2499
  //#region src/components/base/cascader/cascader.vue
2294
- const _hoisted_1$29 = [
2500
+ const _hoisted_1$31 = [
2295
2501
  "value",
2296
2502
  "placeholder",
2297
2503
  "disabled",
2298
2504
  "readonly"
2299
2505
  ];
2300
- const _hoisted_2$17 = ["onClick"];
2301
- const _hoisted_3$10 = ["onClick"];
2302
- const _hoisted_4$9 = ["onClick"];
2506
+ const _hoisted_2$20 = ["onClick"];
2507
+ const _hoisted_3$12 = ["onClick"];
2508
+ const _hoisted_4$11 = ["onClick"];
2303
2509
  var cascader_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
2304
2510
  name: "YdCascader",
2305
2511
  __name: "cascader",
@@ -2363,7 +2569,6 @@ var cascader_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
2363
2569
  });
2364
2570
  const dropdownStyle = computed(() => {
2365
2571
  if (!triggerRef.value) return {};
2366
- positionKey.value;
2367
2572
  const rect = triggerRef.value.getBoundingClientRect();
2368
2573
  return {
2369
2574
  position: "fixed",
@@ -2513,7 +2718,7 @@ var cascader_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
2513
2718
  onInput: handleSearch,
2514
2719
  onFocus: handleFocus,
2515
2720
  onBlur: handleBlur
2516
- }, null, 42, _hoisted_1$29), (openBlock(), createBlock(Teleport, { to: "body" }, [visible.value ? (openBlock(), createElementBlock("div", {
2721
+ }, null, 42, _hoisted_1$31), (openBlock(), createBlock(Teleport, { to: "body" }, [visible.value ? (openBlock(), createElementBlock("div", {
2517
2722
  key: 0,
2518
2723
  class: normalizeClass(e("dropdown")),
2519
2724
  style: normalizeStyle(dropdownStyle.value),
@@ -2536,7 +2741,7 @@ var cascader_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
2536
2741
  }), 128)), __props.multiple ? (openBlock(), createElementBlock("span", {
2537
2742
  key: 0,
2538
2743
  class: normalizeClass(e("checkmark"))
2539
- }, toDisplayString(isPathSelected(item.path) ? "✓" : ""), 3)) : createCommentVNode("v-if", true)], 10, _hoisted_2$17);
2744
+ }, toDisplayString(isPathSelected(item.path) ? "✓" : ""), 3)) : createCommentVNode("v-if", true)], 10, _hoisted_2$20);
2540
2745
  }), 128)), searchResults.value.length === 0 ? (openBlock(), createElementBlock("div", {
2541
2746
  key: 0,
2542
2747
  class: normalizeClass(e("empty"))
@@ -2548,7 +2753,7 @@ var cascader_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
2548
2753
  }, [createTextVNode(toDisplayString(option.label) + " ", 1), option.children?.length ? (openBlock(), createElementBlock("span", {
2549
2754
  key: 0,
2550
2755
  class: normalizeClass(e("arrow"))
2551
- }, "›", 2)) : createCommentVNode("v-if", true)], 10, _hoisted_3$10);
2756
+ }, "›", 2)) : createCommentVNode("v-if", true)], 10, _hoisted_3$12);
2552
2757
  }), 128))], 2), (openBlock(true), createElementBlock(Fragment, null, renderList(activePath.value.length, (level) => {
2553
2758
  return openBlock(), createElementBlock(Fragment, { key: level }, [activePath.value[level - 1]?.children?.length ? (openBlock(), createElementBlock("div", {
2554
2759
  key: 0,
@@ -2561,7 +2766,7 @@ var cascader_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
2561
2766
  }, [createTextVNode(toDisplayString(option.label) + " ", 1), option.children?.length ? (openBlock(), createElementBlock("span", {
2562
2767
  key: 0,
2563
2768
  class: normalizeClass(e("arrow"))
2564
- }, "›", 2)) : createCommentVNode("v-if", true)], 10, _hoisted_4$9);
2769
+ }, "›", 2)) : createCommentVNode("v-if", true)], 10, _hoisted_4$11);
2565
2770
  }), 128))], 2)) : createCommentVNode("v-if", true)], 64);
2566
2771
  }), 128))], 2)], 2112))], 38)) : createCommentVNode("v-if", true)]))], 2);
2567
2772
  };
@@ -2569,7 +2774,7 @@ var cascader_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
2569
2774
  }), [["__scopeId", "data-v-01225c10"]]);
2570
2775
  //#endregion
2571
2776
  //#region src/components/base/auto-complete/auto-complete.vue
2572
- const _hoisted_1$28 = ["onClick", "onMouseenter"];
2777
+ const _hoisted_1$30 = ["onClick", "onMouseenter"];
2573
2778
  var auto_complete_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
2574
2779
  name: "YdAutoComplete",
2575
2780
  __name: "auto-complete",
@@ -2653,15 +2858,15 @@ var auto_complete_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ *
2653
2858
  class: normalizeClass([e("option"), { [e("option--active")]: index === activeIndex.value }]),
2654
2859
  onClick: ($event) => selectOption(option),
2655
2860
  onMouseenter: ($event) => activeIndex.value = index
2656
- }, toDisplayString(option.label), 43, _hoisted_1$28);
2861
+ }, toDisplayString(option.label), 43, _hoisted_1$30);
2657
2862
  }), 128))], 6)) : createCommentVNode("v-if", true)]))], 2);
2658
2863
  };
2659
2864
  }
2660
2865
  }), [["__scopeId", "data-v-0251e526"]]);
2661
2866
  //#endregion
2662
2867
  //#region src/components/base/transfer/transfer.vue
2663
- const _hoisted_1$27 = ["onClick"];
2664
- const _hoisted_2$16 = ["onClick"];
2868
+ const _hoisted_1$29 = ["onClick"];
2869
+ const _hoisted_2$19 = ["onClick"];
2665
2870
  var transfer_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
2666
2871
  name: "YdTransfer",
2667
2872
  __name: "transfer",
@@ -2736,7 +2941,7 @@ var transfer_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
2736
2941
  "model-value",
2737
2942
  "disabled",
2738
2943
  "onChange"
2739
- ])], 10, _hoisted_1$27);
2944
+ ])], 10, _hoisted_1$29);
2740
2945
  }), 128)), sourceOptions.value.length === 0 ? (openBlock(), createBlock(empty_default, {
2741
2946
  key: 0,
2742
2947
  description: "暂无数据"
@@ -2784,7 +2989,7 @@ var transfer_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
2784
2989
  "model-value",
2785
2990
  "disabled",
2786
2991
  "onChange"
2787
- ])], 10, _hoisted_2$16);
2992
+ ])], 10, _hoisted_2$19);
2788
2993
  }), 128)), targetOptions.value.length === 0 ? (openBlock(), createBlock(empty_default, {
2789
2994
  key: 0,
2790
2995
  description: "暂无数据"
@@ -2795,7 +3000,7 @@ var transfer_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
2795
3000
  }), [["__scopeId", "data-v-a2e1ecd2"]]);
2796
3001
  //#endregion
2797
3002
  //#region src/components/feedback/spin/spin.vue
2798
- const _hoisted_1$26 = ["width", "height"];
3003
+ const _hoisted_1$28 = ["width", "height"];
2799
3004
  var spin_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
2800
3005
  name: "YdSpin",
2801
3006
  __name: "spin",
@@ -2833,7 +3038,7 @@ var spin_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineC
2833
3038
  "stroke-width": "2",
2834
3039
  "stroke-linecap": "round",
2835
3040
  "stroke-linejoin": "round"
2836
- }, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }, null, -1)])], 8, _hoisted_1$26))], true)], 6), _ctx.$slots.default || __props.tip ? (openBlock(), createElementBlock("div", {
3041
+ }, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }, null, -1)])], 8, _hoisted_1$28))], true)], 6), _ctx.$slots.default || __props.tip ? (openBlock(), createElementBlock("div", {
2837
3042
  key: 0,
2838
3043
  class: normalizeClass(e("text"))
2839
3044
  }, [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.tip), 1)], true)], 2)) : createCommentVNode("v-if", true)], 2);
@@ -2842,8 +3047,8 @@ var spin_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineC
2842
3047
  }), [["__scopeId", "data-v-f72fb3d9"]]);
2843
3048
  //#endregion
2844
3049
  //#region src/components/base/upload/upload.vue
2845
- const _hoisted_1$25 = ["onClick"];
2846
- const _hoisted_2$15 = [
3050
+ const _hoisted_1$27 = ["onClick"];
3051
+ const _hoisted_2$18 = [
2847
3052
  "multiple",
2848
3053
  "accept",
2849
3054
  "disabled"
@@ -2882,7 +3087,6 @@ var upload_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
2882
3087
  return `yd-upload__${element}`;
2883
3088
  }
2884
3089
  function getFileIcon(name) {
2885
- const ext = name.split(".").pop()?.toLowerCase();
2886
3090
  return {
2887
3091
  jpg: "🖼️",
2888
3092
  jpeg: "🖼️",
@@ -2905,7 +3109,7 @@ var upload_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
2905
3109
  mov: "🎬",
2906
3110
  mp3: "🎵",
2907
3111
  wav: "🎵"
2908
- }[ext || ""] || "📎";
3112
+ }[name.split(".").pop()?.toLowerCase() || ""] || "📎";
2909
3113
  }
2910
3114
  function formatSize(bytes) {
2911
3115
  if (bytes < 1024) return `${bytes} B`;
@@ -2976,7 +3180,7 @@ var upload_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
2976
3180
  key: 3,
2977
3181
  class: normalizeClass(e("file-remove")),
2978
3182
  onClick: ($event) => handleRemove(index)
2979
- }, "✕", 10, _hoisted_1$25)) : createCommentVNode("v-if", true)
3183
+ }, "✕", 10, _hoisted_1$27)) : createCommentVNode("v-if", true)
2980
3184
  ], 2);
2981
3185
  }), 128))], 2),
2982
3186
  createElementVNode("div", {
@@ -2997,7 +3201,7 @@ var upload_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
2997
3201
  disabled: __props.disabled,
2998
3202
  hidden: "",
2999
3203
  onChange: handleFileChange
3000
- }, null, 40, _hoisted_2$15), renderSlot(_ctx.$slots, "default", {}, () => [createElementVNode("div", { class: normalizeClass(e("trigger-content")) }, [_cache[2] || (_cache[2] = createElementVNode("svg", {
3204
+ }, null, 40, _hoisted_2$18), renderSlot(_ctx.$slots, "default", {}, () => [createElementVNode("div", { class: normalizeClass(e("trigger-content")) }, [_cache[2] || (_cache[2] = createElementVNode("svg", {
3001
3205
  xmlns: "http://www.w3.org/2000/svg",
3002
3206
  width: "32",
3003
3207
  height: "32",
@@ -3027,7 +3231,13 @@ var upload_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
3027
3231
  }), [["__scopeId", "data-v-30cb3c39"]]);
3028
3232
  //#endregion
3029
3233
  //#region src/components/base/captcha/captcha.vue
3030
- const _hoisted_1$24 = ["width", "height"];
3234
+ const _hoisted_1$26 = ["width", "height"];
3235
+ const _hoisted_2$17 = [
3236
+ "src",
3237
+ "alt",
3238
+ "width",
3239
+ "height"
3240
+ ];
3031
3241
  var captcha_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
3032
3242
  name: "YdCaptcha",
3033
3243
  __name: "captcha",
@@ -3036,7 +3246,10 @@ var captcha_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defi
3036
3246
  width: { default: 120 },
3037
3247
  height: { default: 40 },
3038
3248
  fontSize: { default: 24 },
3039
- bgColor: { default: "#f5f5f5" }
3249
+ bgColor: { default: "#f5f5f5" },
3250
+ src: { default: "" },
3251
+ code: { default: "" },
3252
+ mode: { default: "client" }
3040
3253
  },
3041
3254
  emits: ["change"],
3042
3255
  setup(__props, { expose: __expose, emit: __emit }) {
@@ -3046,7 +3259,7 @@ var captcha_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defi
3046
3259
  return `yd-captcha__${element}`;
3047
3260
  }
3048
3261
  const canvasRef = ref();
3049
- const code = ref("");
3262
+ const generatedCode = ref("");
3050
3263
  function randomColor(min, max) {
3051
3264
  return `rgb(${Math.floor(Math.random() * (max - min) + min)},${Math.floor(Math.random() * (max - min) + min)},${Math.floor(Math.random() * (max - min) + min)})`;
3052
3265
  }
@@ -3063,7 +3276,8 @@ var captcha_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defi
3063
3276
  if (!ctx) return;
3064
3277
  const w = props.width;
3065
3278
  const h = props.height;
3066
- code.value = generateCode();
3279
+ const currentCode = props.code || generateCode();
3280
+ generatedCode.value = currentCode;
3067
3281
  ctx.fillStyle = props.bgColor;
3068
3282
  ctx.fillRect(0, 0, w, h);
3069
3283
  for (let i = 0; i < 5; i++) {
@@ -3081,7 +3295,7 @@ var captcha_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defi
3081
3295
  ctx.fill();
3082
3296
  }
3083
3297
  const charWidth = w / (props.length + 1);
3084
- for (let i = 0; i < code.value.length; i++) {
3298
+ for (let i = 0; i < currentCode.length; i++) {
3085
3299
  ctx.save();
3086
3300
  ctx.font = `${props.fontSize}px Arial`;
3087
3301
  ctx.fillStyle = randomColor(50, 120);
@@ -3091,16 +3305,16 @@ var captcha_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defi
3091
3305
  const angle = (Math.random() - .5) * .4;
3092
3306
  ctx.translate(x, y);
3093
3307
  ctx.rotate(angle);
3094
- ctx.fillText(code.value[i], 0, 0);
3308
+ ctx.fillText(currentCode[i], 0, 0);
3095
3309
  ctx.restore();
3096
3310
  }
3097
- emit("change", code.value);
3311
+ emit("change", currentCode);
3098
3312
  }
3099
3313
  function refresh() {
3100
- draw();
3314
+ if (!props.src) draw();
3101
3315
  }
3102
3316
  __expose({
3103
- code,
3317
+ code: generatedCode,
3104
3318
  refresh
3105
3319
  });
3106
3320
  onMounted(() => {
@@ -3110,34 +3324,54 @@ var captcha_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defi
3110
3324
  props.length,
3111
3325
  props.width,
3112
3326
  props.height,
3113
- props.fontSize
3114
- ], draw);
3327
+ props.fontSize,
3328
+ props.src,
3329
+ props.code,
3330
+ props.mode
3331
+ ], () => {
3332
+ if (props.mode === "server") {
3333
+ generatedCode.value = "";
3334
+ return;
3335
+ }
3336
+ if (!props.src) draw();
3337
+ else {
3338
+ generatedCode.value = props.code || "";
3339
+ emit("change", generatedCode.value);
3340
+ }
3341
+ });
3115
3342
  return (_ctx, _cache) => {
3116
3343
  return openBlock(), createElementBlock("div", {
3117
3344
  class: normalizeClass(unref(cn)("yd-captcha")),
3118
3345
  onClick: refresh
3119
- }, [createElementVNode("canvas", {
3346
+ }, [createCommentVNode(" 客户端生成验证码 "), !__props.src ? (openBlock(), createElementBlock("canvas", {
3347
+ key: 0,
3120
3348
  ref_key: "canvasRef",
3121
3349
  ref: canvasRef,
3122
3350
  class: normalizeClass(e("canvas")),
3123
3351
  width: __props.width,
3124
3352
  height: __props.height
3125
- }, null, 10, _hoisted_1$24)], 2);
3353
+ }, null, 10, _hoisted_1$26)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" 后端提供的图片验证码 "), createElementVNode("img", {
3354
+ class: normalizeClass(e("image")),
3355
+ src: __props.src,
3356
+ alt: __props.code || "验证码",
3357
+ width: __props.width,
3358
+ height: __props.height
3359
+ }, null, 10, _hoisted_2$17)], 2112))], 2);
3126
3360
  };
3127
3361
  }
3128
- }), [["__scopeId", "data-v-90356070"]]);
3362
+ }), [["__scopeId", "data-v-0ad64f93"]]);
3129
3363
  //#endregion
3130
3364
  //#region src/components/base/login/login.vue
3131
- const _hoisted_1$23 = ["onClick"];
3132
- const _hoisted_2$14 = ["placeholder"];
3133
- const _hoisted_3$9 = ["type", "placeholder"];
3134
- const _hoisted_4$8 = ["placeholder"];
3135
- const _hoisted_5$5 = ["placeholder"];
3136
- const _hoisted_6$5 = ["placeholder"];
3137
- const _hoisted_7$4 = ["disabled"];
3138
- const _hoisted_8$4 = ["placeholder"];
3139
- const _hoisted_9$4 = ["disabled"];
3140
- const _hoisted_10$4 = ["title", "onClick"];
3365
+ const _hoisted_1$25 = ["onClick"];
3366
+ const _hoisted_2$16 = ["placeholder"];
3367
+ const _hoisted_3$11 = ["type", "placeholder"];
3368
+ const _hoisted_4$10 = ["placeholder"];
3369
+ const _hoisted_5$7 = ["placeholder"];
3370
+ const _hoisted_6$7 = ["placeholder"];
3371
+ const _hoisted_7$6 = ["disabled"];
3372
+ const _hoisted_8$6 = ["placeholder"];
3373
+ const _hoisted_9$6 = ["disabled"];
3374
+ const _hoisted_10$5 = ["title", "onClick"];
3141
3375
  var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
3142
3376
  name: "YdLogin",
3143
3377
  __name: "login",
@@ -3211,7 +3445,30 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3211
3445
  type: Boolean,
3212
3446
  default: true
3213
3447
  },
3214
- captchaPlaceholder: { default: "请输入验证码" }
3448
+ captchaPlaceholder: { default: "请输入验证码" },
3449
+ showOptions: {
3450
+ type: Boolean,
3451
+ default: true
3452
+ },
3453
+ showRemember: {
3454
+ type: Boolean,
3455
+ default: true
3456
+ },
3457
+ showForgot: {
3458
+ type: Boolean,
3459
+ default: true
3460
+ },
3461
+ showAccountLogin: {
3462
+ type: Boolean,
3463
+ default: true
3464
+ },
3465
+ showPhoneLogin: {
3466
+ type: Boolean,
3467
+ default: true
3468
+ },
3469
+ captchaSrc: { default: "" },
3470
+ captchaCode: { default: "" },
3471
+ captchaMode: { default: "client" }
3215
3472
  },
3216
3473
  emits: [
3217
3474
  "submit",
@@ -3226,6 +3483,19 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3226
3483
  function e(element) {
3227
3484
  return `yd-login__${element}`;
3228
3485
  }
3486
+ const availableTabs = computed(() => {
3487
+ return (props.tabs || []).filter((tab) => {
3488
+ if (tab.key === "account") return props.showAccountLogin;
3489
+ if (tab.key === "phone") return props.showPhoneLogin;
3490
+ return true;
3491
+ });
3492
+ });
3493
+ const activeTab = ref(props.tabs?.[0]?.key || "account");
3494
+ watch(() => [props.showAccountLogin, props.showPhoneLogin], () => {
3495
+ const currentAvailable = availableTabs.value;
3496
+ if (currentAvailable.length === 0) return;
3497
+ if (!currentAvailable.find((t) => t.key === activeTab.value)) activeTab.value = currentAvailable[0].key;
3498
+ }, { immediate: true });
3229
3499
  const formData = reactive({
3230
3500
  username: "",
3231
3501
  password: "",
@@ -3235,7 +3505,6 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3235
3505
  remember: false
3236
3506
  });
3237
3507
  const showPassword = ref(false);
3238
- const activeTab = ref(props.tabs?.[0]?.key || "account");
3239
3508
  const errorMsg = ref(props.error);
3240
3509
  const countdown = ref(0);
3241
3510
  const captchaKey = ref(0);
@@ -3263,14 +3532,22 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3263
3532
  }
3264
3533
  function handleSubmit() {
3265
3534
  errorMsg.value = "";
3266
- if (props.showCaptcha && !formData.captchaCode) {
3267
- errorMsg.value = "请输入图片验证码";
3268
- return;
3269
- }
3270
- if (props.showCaptcha && formData.captchaCode.toUpperCase() !== captchaCode.value.toUpperCase()) {
3271
- errorMsg.value = "图片验证码错误";
3272
- captchaKey.value++;
3273
- return;
3535
+ if (props.captchaMode === "server") {
3536
+ if (props.showCaptcha && !formData.captchaCode) {
3537
+ errorMsg.value = "请输入图片验证码";
3538
+ return;
3539
+ }
3540
+ } else {
3541
+ if (props.showCaptcha && !formData.captchaCode) {
3542
+ errorMsg.value = "请输入图片验证码";
3543
+ return;
3544
+ }
3545
+ const expectedCode = props.captchaCode || captchaCode.value;
3546
+ if (props.showCaptcha && formData.captchaCode.toUpperCase() !== expectedCode.toUpperCase()) {
3547
+ errorMsg.value = "图片验证码错误";
3548
+ captchaKey.value++;
3549
+ return;
3550
+ }
3274
3551
  }
3275
3552
  if (activeTab.value === "account") {
3276
3553
  if (!formData.username) {
@@ -3316,28 +3593,28 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3316
3593
  }), 128))], 2)
3317
3594
  ], 2)], 2), createElementVNode("div", { class: normalizeClass(e("form-section")) }, [createElementVNode("div", { class: normalizeClass(e("form-card")) }, [
3318
3595
  createElementVNode("h2", { class: normalizeClass(e("form-title")) }, toDisplayString(__props.formTitle), 3),
3319
- __props.showTabs ? (openBlock(), createElementBlock("div", {
3596
+ __props.showTabs && availableTabs.value.length > 1 ? (openBlock(), createElementBlock("div", {
3320
3597
  key: 0,
3321
3598
  class: normalizeClass(e("tabs"))
3322
- }, [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.tabList, (tab) => {
3599
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(availableTabs.value, (tab) => {
3323
3600
  return openBlock(), createElementBlock("button", {
3324
3601
  key: tab.key,
3325
3602
  class: normalizeClass([e("tab"), { [e("tab--active")]: activeTab.value === tab.key }]),
3326
3603
  onClick: ($event) => activeTab.value = tab.key
3327
- }, toDisplayString(tab.label), 11, _hoisted_1$23);
3604
+ }, toDisplayString(tab.label), 11, _hoisted_1$25);
3328
3605
  }), 128))], 2)) : createCommentVNode("v-if", true),
3329
3606
  createElementVNode("form", {
3330
3607
  class: normalizeClass(e("form")),
3331
3608
  onSubmit: withModifiers(handleSubmit, ["prevent"])
3332
3609
  }, [
3333
3610
  createCommentVNode(" Account login "),
3334
- activeTab.value === "account" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
3611
+ __props.showAccountLogin && activeTab.value === "account" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
3335
3612
  createElementVNode("div", { class: normalizeClass(e("field")) }, [createElementVNode("div", { class: normalizeClass(e("input-wrapper")) }, [createElementVNode("span", { class: normalizeClass(e("input-icon")) }, "👤", 2), withDirectives(createElementVNode("input", {
3336
3613
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => formData.username = $event),
3337
3614
  class: normalizeClass(e("input")),
3338
3615
  placeholder: __props.usernamePlaceholder,
3339
3616
  autocomplete: "username"
3340
- }, null, 10, _hoisted_2$14), [[vModelText, formData.username]])], 2)], 2),
3617
+ }, null, 10, _hoisted_2$16), [[vModelText, formData.username]])], 2)], 2),
3341
3618
  createElementVNode("div", { class: normalizeClass(e("field")) }, [createElementVNode("div", { class: normalizeClass(e("input-wrapper")) }, [
3342
3619
  createElementVNode("span", { class: normalizeClass(e("input-icon")) }, "🔒", 2),
3343
3620
  withDirectives(createElementVNode("input", {
@@ -3346,7 +3623,7 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3346
3623
  class: normalizeClass(e("input")),
3347
3624
  placeholder: __props.passwordPlaceholder,
3348
3625
  autocomplete: "current-password"
3349
- }, null, 10, _hoisted_3$9), [[vModelDynamic, formData.password]]),
3626
+ }, null, 10, _hoisted_3$11), [[vModelDynamic, formData.password]]),
3350
3627
  createElementVNode("button", {
3351
3628
  type: "button",
3352
3629
  class: normalizeClass(e("toggle-pwd")),
@@ -3366,22 +3643,37 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3366
3643
  type: "text",
3367
3644
  maxlength: "4",
3368
3645
  autocomplete: "off"
3369
- }, null, 10, _hoisted_4$8), [[vModelText, formData.captchaCode]])], 2), (openBlock(), createBlock(captcha_default, {
3646
+ }, null, 10, _hoisted_4$10), [[vModelText, formData.captchaCode]])], 2), (openBlock(), createBlock(captcha_default, {
3370
3647
  class: normalizeClass(e("captcha-img")),
3648
+ src: __props.captchaSrc,
3649
+ code: captchaCode.value,
3650
+ mode: __props.captchaMode,
3371
3651
  key: captchaKey.value,
3372
3652
  onChange: handleCaptchaChange
3373
- }, null, 8, ["class"]))], 2)], 2)) : createCommentVNode("v-if", true),
3374
- createElementVNode("div", { class: normalizeClass(e("options")) }, [createElementVNode("label", { class: normalizeClass(e("remember")) }, [withDirectives(createElementVNode("input", {
3653
+ }, null, 8, [
3654
+ "class",
3655
+ "src",
3656
+ "code",
3657
+ "mode"
3658
+ ]))], 2)], 2)) : createCommentVNode("v-if", true),
3659
+ __props.showOptions ? (openBlock(), createElementBlock("div", {
3660
+ key: 1,
3661
+ class: normalizeClass(e("options"))
3662
+ }, [__props.showRemember ? (openBlock(), createElementBlock("label", {
3663
+ key: 0,
3664
+ class: normalizeClass(e("remember"))
3665
+ }, [withDirectives(createElementVNode("input", {
3375
3666
  type: "checkbox",
3376
3667
  "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => formData.remember = $event)
3377
- }, null, 512), [[vModelCheckbox, formData.remember]]), createElementVNode("span", null, toDisplayString(__props.rememberText), 1)], 2), createElementVNode("a", {
3668
+ }, null, 512), [[vModelCheckbox, formData.remember]]), createElementVNode("span", null, toDisplayString(__props.rememberText), 1)], 2)) : createCommentVNode("v-if", true), __props.showForgot ? (openBlock(), createElementBlock("a", {
3669
+ key: 1,
3378
3670
  class: normalizeClass(e("forgot")),
3379
3671
  href: "javascript:void(0)",
3380
3672
  onClick: _cache[5] || (_cache[5] = ($event) => _ctx.$emit("forgot-password"))
3381
- }, toDisplayString(__props.forgotText), 3)], 2)
3673
+ }, toDisplayString(__props.forgotText), 3)) : createCommentVNode("v-if", true)], 2)) : createCommentVNode("v-if", true)
3382
3674
  ], 64)) : createCommentVNode("v-if", true),
3383
3675
  createCommentVNode(" Phone login "),
3384
- activeTab.value === "phone" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
3676
+ __props.showPhoneLogin && activeTab.value === "phone" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
3385
3677
  createElementVNode("div", { class: normalizeClass(e("field")) }, [createElementVNode("div", { class: normalizeClass(e("input-wrapper")) }, [createElementVNode("span", { class: normalizeClass(e("input-icon")) }, "📱", 2), withDirectives(createElementVNode("input", {
3386
3678
  "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => formData.phone = $event),
3387
3679
  class: normalizeClass(e("input")),
@@ -3389,7 +3681,7 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3389
3681
  type: "tel",
3390
3682
  maxlength: "11",
3391
3683
  autocomplete: "tel"
3392
- }, null, 10, _hoisted_5$5), [[vModelText, formData.phone]])], 2)], 2),
3684
+ }, null, 10, _hoisted_5$7), [[vModelText, formData.phone]])], 2)], 2),
3393
3685
  createElementVNode("div", { class: normalizeClass(e("field")) }, [createElementVNode("div", { class: normalizeClass(e("input-wrapper")) }, [
3394
3686
  createElementVNode("span", { class: normalizeClass(e("input-icon")) }, "🔑", 2),
3395
3687
  withDirectives(createElementVNode("input", {
@@ -3399,13 +3691,13 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3399
3691
  type: "text",
3400
3692
  maxlength: "6",
3401
3693
  autocomplete: "one-time-code"
3402
- }, null, 10, _hoisted_6$5), [[vModelText, formData.code]]),
3694
+ }, null, 10, _hoisted_6$7), [[vModelText, formData.code]]),
3403
3695
  createElementVNode("button", {
3404
3696
  type: "button",
3405
3697
  class: normalizeClass([e("send-code"), { [e("send-code--disabled")]: countdown.value > 0 }]),
3406
3698
  disabled: countdown.value > 0,
3407
3699
  onClick: handleSendCode
3408
- }, toDisplayString(countdown.value > 0 ? `${countdown.value}s` : __props.sendCodeText), 11, _hoisted_7$4)
3700
+ }, toDisplayString(countdown.value > 0 ? `${countdown.value}s` : __props.sendCodeText), 11, _hoisted_7$6)
3409
3701
  ], 2)], 2),
3410
3702
  __props.showCaptcha ? (openBlock(), createElementBlock("div", {
3411
3703
  key: 0,
@@ -3420,19 +3712,34 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3420
3712
  type: "text",
3421
3713
  maxlength: "4",
3422
3714
  autocomplete: "off"
3423
- }, null, 10, _hoisted_8$4), [[vModelText, formData.captchaCode]])], 2), (openBlock(), createBlock(captcha_default, {
3715
+ }, null, 10, _hoisted_8$6), [[vModelText, formData.captchaCode]])], 2), (openBlock(), createBlock(captcha_default, {
3424
3716
  class: normalizeClass(e("captcha-img")),
3717
+ src: __props.captchaSrc,
3718
+ code: captchaCode.value,
3719
+ mode: __props.captchaMode,
3425
3720
  key: captchaKey.value,
3426
3721
  onChange: handleCaptchaChange
3427
- }, null, 8, ["class"]))], 2)], 2)) : createCommentVNode("v-if", true),
3428
- createElementVNode("div", { class: normalizeClass(e("options")) }, [createElementVNode("label", { class: normalizeClass(e("remember")) }, [withDirectives(createElementVNode("input", {
3722
+ }, null, 8, [
3723
+ "class",
3724
+ "src",
3725
+ "code",
3726
+ "mode"
3727
+ ]))], 2)], 2)) : createCommentVNode("v-if", true),
3728
+ __props.showOptions ? (openBlock(), createElementBlock("div", {
3729
+ key: 1,
3730
+ class: normalizeClass(e("options"))
3731
+ }, [__props.showRemember ? (openBlock(), createElementBlock("label", {
3732
+ key: 0,
3733
+ class: normalizeClass(e("remember"))
3734
+ }, [withDirectives(createElementVNode("input", {
3429
3735
  type: "checkbox",
3430
3736
  "onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => formData.remember = $event)
3431
- }, null, 512), [[vModelCheckbox, formData.remember]]), createElementVNode("span", null, toDisplayString(__props.rememberText), 1)], 2), createElementVNode("a", {
3737
+ }, null, 512), [[vModelCheckbox, formData.remember]]), createElementVNode("span", null, toDisplayString(__props.rememberText), 1)], 2)) : createCommentVNode("v-if", true), __props.showForgot ? (openBlock(), createElementBlock("a", {
3738
+ key: 1,
3432
3739
  class: normalizeClass(e("forgot")),
3433
3740
  href: "javascript:void(0)",
3434
3741
  onClick: _cache[10] || (_cache[10] = ($event) => _ctx.$emit("forgot-password"))
3435
- }, toDisplayString(__props.forgotText), 3)], 2)
3742
+ }, toDisplayString(__props.forgotText), 3)) : createCommentVNode("v-if", true)], 2)) : createCommentVNode("v-if", true)
3436
3743
  ], 64)) : createCommentVNode("v-if", true),
3437
3744
  errorMsg.value ? (openBlock(), createElementBlock("div", {
3438
3745
  key: 2,
@@ -3445,7 +3752,7 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3445
3752
  }, [__props.loading ? (openBlock(), createElementBlock("span", {
3446
3753
  key: 0,
3447
3754
  class: normalizeClass(e("spinner"))
3448
- }, null, 2)) : createCommentVNode("v-if", true), createTextVNode(" " + toDisplayString(__props.loading ? __props.loadingText : __props.submitText), 1)], 10, _hoisted_9$4)
3755
+ }, null, 2)) : createCommentVNode("v-if", true), createTextVNode(" " + toDisplayString(__props.loading ? __props.loadingText : __props.submitText), 1)], 10, _hoisted_9$6)
3449
3756
  ], 34),
3450
3757
  __props.showSocial ? (openBlock(), createElementBlock("div", {
3451
3758
  key: 1,
@@ -3460,20 +3767,20 @@ var login_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
3460
3767
  class: normalizeClass(e("social-btn")),
3461
3768
  title: social.label,
3462
3769
  onClick: ($event) => _ctx.$emit("social-login", social.key)
3463
- }, toDisplayString(social.icon), 11, _hoisted_10$4);
3770
+ }, toDisplayString(social.icon), 11, _hoisted_10$5);
3464
3771
  }), 128))], 2)) : createCommentVNode("v-if", true),
3465
3772
  createElementVNode("div", { class: normalizeClass(e("footer-links")) }, [renderSlot(_ctx.$slots, "footer", {}, () => [createElementVNode("span", null, toDisplayString(__props.footerText), 1)], true)], 2)
3466
3773
  ], 2)], 2)], 2)], 2);
3467
3774
  };
3468
3775
  }
3469
- }), [["__scopeId", "data-v-4d9537f6"]]);
3776
+ }), [["__scopeId", "data-v-bea2a0a0"]]);
3470
3777
  //#endregion
3471
3778
  //#region src/components/base/login/login-centered.vue
3472
- const _hoisted_1$22 = ["fill"];
3473
- const _hoisted_2$13 = ["onClick"];
3474
- const _hoisted_3$8 = ["placeholder"];
3475
- const _hoisted_4$7 = ["type", "placeholder"];
3476
- const _hoisted_5$4 = {
3779
+ const _hoisted_1$24 = ["fill"];
3780
+ const _hoisted_2$15 = ["onClick"];
3781
+ const _hoisted_3$10 = ["placeholder"];
3782
+ const _hoisted_4$9 = ["type", "placeholder"];
3783
+ const _hoisted_5$6 = {
3477
3784
  key: 0,
3478
3785
  width: "18",
3479
3786
  height: "18",
@@ -3482,7 +3789,7 @@ const _hoisted_5$4 = {
3482
3789
  stroke: "currentColor",
3483
3790
  "stroke-width": "2"
3484
3791
  };
3485
- const _hoisted_6$4 = {
3792
+ const _hoisted_6$6 = {
3486
3793
  key: 1,
3487
3794
  width: "18",
3488
3795
  height: "18",
@@ -3491,12 +3798,12 @@ const _hoisted_6$4 = {
3491
3798
  stroke: "currentColor",
3492
3799
  "stroke-width": "2"
3493
3800
  };
3494
- const _hoisted_7$3 = ["placeholder"];
3495
- const _hoisted_8$3 = ["placeholder"];
3496
- const _hoisted_9$3 = ["disabled"];
3497
- const _hoisted_10$3 = ["placeholder"];
3498
- const _hoisted_11$3 = ["disabled"];
3499
- const _hoisted_12$3 = ["title", "onClick"];
3801
+ const _hoisted_7$5 = ["placeholder"];
3802
+ const _hoisted_8$5 = ["placeholder"];
3803
+ const _hoisted_9$5 = ["disabled"];
3804
+ const _hoisted_10$4 = ["placeholder"];
3805
+ const _hoisted_11$4 = ["disabled"];
3806
+ const _hoisted_12$4 = ["title", "onClick"];
3500
3807
  var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
3501
3808
  name: "YdLoginCentered",
3502
3809
  __name: "login-centered",
@@ -3710,7 +4017,7 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3710
4017
  height: "40",
3711
4018
  rx: "8",
3712
4019
  fill: __props.theme === "dark" ? "#6366f1" : "#4f46e5"
3713
- }, null, 8, _hoisted_1$22), _cache[8] || (_cache[8] = createElementVNode("path", {
4020
+ }, null, 8, _hoisted_1$24), _cache[8] || (_cache[8] = createElementVNode("path", {
3714
4021
  d: "M12 20L18 26L28 14",
3715
4022
  stroke: "#fff",
3716
4023
  "stroke-width": "3",
@@ -3728,7 +4035,7 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3728
4035
  key: tab.key,
3729
4036
  class: normalizeClass([e("tab"), { [e("tab--active")]: activeTab.value === tab.key }]),
3730
4037
  onClick: ($event) => activeTab.value = tab.key
3731
- }, toDisplayString(tab.label), 11, _hoisted_2$13);
4038
+ }, toDisplayString(tab.label), 11, _hoisted_2$15);
3732
4039
  }), 128))], 2)) : createCommentVNode("v-if", true),
3733
4040
  createElementVNode("form", {
3734
4041
  class: normalizeClass(e("form")),
@@ -3751,7 +4058,7 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3751
4058
  class: normalizeClass(e("input")),
3752
4059
  placeholder: __props.usernamePlaceholder,
3753
4060
  autocomplete: "username"
3754
- }, null, 10, _hoisted_3$8), [[vModelText, formData.username]])], 2)], 2), createElementVNode("div", { class: normalizeClass(e("field")) }, [createElementVNode("label", { class: normalizeClass(e("label")) }, toDisplayString(__props.passwordLabel), 3), createElementVNode("div", { class: normalizeClass(e("input-group")) }, [
4061
+ }, null, 10, _hoisted_3$10), [[vModelText, formData.username]])], 2)], 2), createElementVNode("div", { class: normalizeClass(e("field")) }, [createElementVNode("label", { class: normalizeClass(e("label")) }, toDisplayString(__props.passwordLabel), 3), createElementVNode("div", { class: normalizeClass(e("input-group")) }, [
3755
4062
  createElementVNode("span", { class: normalizeClass(e("input-prefix")) }, [..._cache[10] || (_cache[10] = [createElementVNode("svg", {
3756
4063
  width: "18",
3757
4064
  height: "18",
@@ -3773,16 +4080,16 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3773
4080
  class: normalizeClass(e("input")),
3774
4081
  placeholder: __props.passwordPlaceholder,
3775
4082
  autocomplete: "current-password"
3776
- }, null, 10, _hoisted_4$7), [[vModelDynamic, formData.password]]),
4083
+ }, null, 10, _hoisted_4$9), [[vModelDynamic, formData.password]]),
3777
4084
  createElementVNode("button", {
3778
4085
  type: "button",
3779
4086
  class: normalizeClass(e("input-suffix")),
3780
4087
  onClick: _cache[2] || (_cache[2] = ($event) => showPassword.value = !showPassword.value)
3781
- }, [!showPassword.value ? (openBlock(), createElementBlock("svg", _hoisted_5$4, [..._cache[11] || (_cache[11] = [createElementVNode("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }, null, -1), createElementVNode("circle", {
4088
+ }, [!showPassword.value ? (openBlock(), createElementBlock("svg", _hoisted_5$6, [..._cache[11] || (_cache[11] = [createElementVNode("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }, null, -1), createElementVNode("circle", {
3782
4089
  cx: "12",
3783
4090
  cy: "12",
3784
4091
  r: "3"
3785
- }, null, -1)])])) : (openBlock(), createElementBlock("svg", _hoisted_6$4, [..._cache[12] || (_cache[12] = [createElementVNode("path", { d: "M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" }, null, -1), createElementVNode("line", {
4092
+ }, null, -1)])])) : (openBlock(), createElementBlock("svg", _hoisted_6$6, [..._cache[12] || (_cache[12] = [createElementVNode("path", { d: "M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" }, null, -1), createElementVNode("line", {
3786
4093
  x1: "1",
3787
4094
  y1: "1",
3788
4095
  x2: "23",
@@ -3816,7 +4123,7 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3816
4123
  type: "tel",
3817
4124
  maxlength: "11",
3818
4125
  autocomplete: "tel"
3819
- }, null, 10, _hoisted_7$3), [[vModelText, formData.phone]])], 2)], 2), createElementVNode("div", { class: normalizeClass(e("field")) }, [createElementVNode("label", { class: normalizeClass(e("label")) }, toDisplayString(__props.codeLabel), 3), createElementVNode("div", { class: normalizeClass(e("input-group")) }, [
4126
+ }, null, 10, _hoisted_7$5), [[vModelText, formData.phone]])], 2)], 2), createElementVNode("div", { class: normalizeClass(e("field")) }, [createElementVNode("label", { class: normalizeClass(e("label")) }, toDisplayString(__props.codeLabel), 3), createElementVNode("div", { class: normalizeClass(e("input-group")) }, [
3820
4127
  createElementVNode("span", { class: normalizeClass(e("input-prefix")) }, [..._cache[14] || (_cache[14] = [createElementVNode("svg", {
3821
4128
  width: "18",
3822
4129
  height: "18",
@@ -3839,13 +4146,13 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3839
4146
  type: "text",
3840
4147
  maxlength: "6",
3841
4148
  autocomplete: "one-time-code"
3842
- }, null, 10, _hoisted_8$3), [[vModelText, formData.code]]),
4149
+ }, null, 10, _hoisted_8$5), [[vModelText, formData.code]]),
3843
4150
  createElementVNode("button", {
3844
4151
  type: "button",
3845
4152
  class: normalizeClass([e("send-code"), { [e("send-code--disabled")]: countdown.value > 0 }]),
3846
4153
  disabled: countdown.value > 0,
3847
4154
  onClick: handleSendCode
3848
- }, toDisplayString(countdown.value > 0 ? `${countdown.value}s` : __props.sendCodeText), 11, _hoisted_9$3)
4155
+ }, toDisplayString(countdown.value > 0 ? `${countdown.value}s` : __props.sendCodeText), 11, _hoisted_9$5)
3849
4156
  ], 2)], 2)], 64)) : createCommentVNode("v-if", true),
3850
4157
  createCommentVNode(" Captcha (shared) "),
3851
4158
  __props.showCaptcha ? (openBlock(), createElementBlock("div", {
@@ -3867,7 +4174,7 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3867
4174
  type: "text",
3868
4175
  maxlength: "4",
3869
4176
  autocomplete: "off"
3870
- }, null, 10, _hoisted_10$3), [[vModelText, formData.captchaCode]]),
4177
+ }, null, 10, _hoisted_10$4), [[vModelText, formData.captchaCode]]),
3871
4178
  (openBlock(), createBlock(captcha_default, {
3872
4179
  class: normalizeClass(e("captcha-img")),
3873
4180
  key: captchaKey.value,
@@ -3919,7 +4226,7 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3919
4226
  }, [__props.loading ? (openBlock(), createElementBlock("span", {
3920
4227
  key: 0,
3921
4228
  class: normalizeClass(e("spinner"))
3922
- }, null, 2)) : createCommentVNode("v-if", true), createTextVNode(" " + toDisplayString(__props.loading ? __props.loadingText : __props.submitText), 1)], 10, _hoisted_11$3)
4229
+ }, null, 2)) : createCommentVNode("v-if", true), createTextVNode(" " + toDisplayString(__props.loading ? __props.loadingText : __props.submitText), 1)], 10, _hoisted_11$4)
3923
4230
  ], 34),
3924
4231
  __props.showSocial ? (openBlock(), createElementBlock("div", {
3925
4232
  key: 1,
@@ -3930,7 +4237,7 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3930
4237
  class: normalizeClass(e("social-icon")),
3931
4238
  title: social.label,
3932
4239
  onClick: ($event) => _ctx.$emit("social-login", social.key)
3933
- }, [(openBlock(), createBlock(resolveDynamicComponent(social.icon)))], 10, _hoisted_12$3);
4240
+ }, [(openBlock(), createBlock(resolveDynamicComponent(social.icon)))], 10, _hoisted_12$4);
3934
4241
  }), 128))], 2)], 2)) : createCommentVNode("v-if", true),
3935
4242
  createElementVNode("div", { class: normalizeClass(e("footer-text")) }, [renderSlot(_ctx.$slots, "footer", {}, () => [createTextVNode(toDisplayString(__props.footerText), 1)], true)], 2)
3936
4243
  ], 2)], 2);
@@ -3939,7 +4246,7 @@ var login_centered_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
3939
4246
  }), [["__scopeId", "data-v-51d3fc32"]]);
3940
4247
  //#endregion
3941
4248
  //#region src/components/base/pin-input/pin-input.vue
3942
- const _hoisted_1$21 = [
4249
+ const _hoisted_1$23 = [
3943
4250
  "value",
3944
4251
  "disabled",
3945
4252
  "onInput",
@@ -4049,7 +4356,7 @@ var pin_input_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ de
4049
4356
  onFocus: ($event) => focusedIndex.value = i - 1,
4050
4357
  onBlur: _cache[0] || (_cache[0] = ($event) => focusedIndex.value = -1),
4051
4358
  onPaste: handlePaste
4052
- }, null, 42, _hoisted_1$21);
4359
+ }, null, 42, _hoisted_1$23);
4053
4360
  }), 128))], 2), __props.error ? (openBlock(), createElementBlock("div", {
4054
4361
  key: 0,
4055
4362
  class: normalizeClass(e("error"))
@@ -4058,101 +4365,1199 @@ var pin_input_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ de
4058
4365
  }
4059
4366
  }), [["__scopeId", "data-v-fd187d50"]]);
4060
4367
  //#endregion
4061
- //#region src/composables/use-form-validate.ts
4062
- /**
4063
- * 获取 AsyncValidator 构造函数
4064
- * 处理 ES Module default export 和 CommonJS 两种导出方式
4065
- */
4066
- function getAsyncValidatorSchema() {
4067
- if (typeof AsyncValidator === "object" && AsyncValidator !== null && "default" in AsyncValidator) return AsyncValidator.default;
4068
- return AsyncValidator;
4069
- }
4070
- const Schema = getAsyncValidatorSchema();
4071
- /**
4072
- * 表单校验 composable
4073
- */
4074
- function useFormValidate(rules, model) {
4075
- const errors = reactive({});
4076
- const items = ref([]);
4077
- /**
4078
- * 校验单个字段
4079
- */
4080
- async function validateField(prop) {
4081
- const rulesForField = (isRef(rules) ? rules.value : rules)[prop];
4082
- if (!rulesForField) return null;
4083
- const value = (isRef(model) ? model.value : model)[prop];
4084
- const validator = new Schema({ [prop]: rulesForField });
4085
- try {
4086
- await validator.validate({ [prop]: value });
4087
- errors[prop] = [];
4088
- return null;
4089
- } catch (err) {
4090
- const fieldErrors = err.errors.map((e) => ({
4091
- message: e.message,
4092
- field: prop
4093
- }));
4094
- errors[prop] = fieldErrors;
4095
- return fieldErrors[0];
4096
- }
4097
- }
4098
- /**
4099
- * 校验整个表单
4100
- */
4101
- async function validate() {
4102
- const allErrors = [];
4103
- const validationPromises = items.value.map((item) => item.validate(item.modelValue));
4104
- const results = await Promise.all(validationPromises);
4105
- for (const result of results) if (result) allErrors.push(result);
4106
- return {
4107
- valid: allErrors.length === 0,
4108
- errors: allErrors
4109
- };
4110
- }
4111
- /**
4112
- * 重置所有字段
4113
- */
4114
- function resetFields() {
4115
- items.value.forEach((item) => item.resetField());
4116
- }
4117
- /**
4118
- * 清除校验错误
4119
- */
4120
- function clearValidate(fields) {
4121
- if (fields) for (const field of fields) {
4122
- errors[field] = [];
4123
- items.value.find((i) => i.prop === field)?.clearValidate();
4124
- }
4125
- else {
4126
- for (const key in errors) errors[key] = [];
4127
- items.value.forEach((item) => item.clearValidate());
4128
- }
4129
- }
4130
- /**
4131
- * 注册表单项
4132
- */
4133
- function registerItem(item) {
4134
- if (!items.value.includes(item)) items.value.push(item);
4135
- }
4136
- /**
4137
- * 注销表单项
4138
- */
4139
- function unregisterItem(item) {
4140
- const index = items.value.indexOf(item);
4141
- if (index > -1) items.value.splice(index, 1);
4142
- }
4143
- return {
4144
- errors,
4145
- items,
4146
- validate,
4147
- validateField,
4148
- resetFields,
4149
- clearValidate,
4150
- registerItem,
4151
- unregisterItem
4152
- };
4153
- }
4154
- var form_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
4155
- name: "YdForm",
4368
+ //#region src/components/base/tree-select/tree-select.vue
4369
+ const _hoisted_1$22 = [
4370
+ "value",
4371
+ "placeholder",
4372
+ "disabled"
4373
+ ];
4374
+ const _hoisted_2$14 = ["onClick"];
4375
+ const _hoisted_3$9 = ["onClick"];
4376
+ const _hoisted_4$8 = ["onClick"];
4377
+ const _hoisted_5$5 = [
4378
+ "checked",
4379
+ "indeterminate",
4380
+ "disabled"
4381
+ ];
4382
+ const _hoisted_6$5 = ["onClick"];
4383
+ const _hoisted_7$4 = ["onClick"];
4384
+ const _hoisted_8$4 = ["onClick"];
4385
+ const _hoisted_9$4 = [
4386
+ "checked",
4387
+ "indeterminate",
4388
+ "disabled"
4389
+ ];
4390
+ const _hoisted_10$3 = ["onClick"];
4391
+ const _hoisted_11$3 = ["onClick"];
4392
+ const _hoisted_12$3 = ["onClick"];
4393
+ const _hoisted_13$2 = [
4394
+ "checked",
4395
+ "indeterminate",
4396
+ "disabled"
4397
+ ];
4398
+ var tree_select_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
4399
+ name: "YdTreeSelect",
4400
+ inheritAttrs: false,
4401
+ __name: "tree-select",
4402
+ props: {
4403
+ modelValue: { default: "" },
4404
+ placeholder: { default: "请选择" },
4405
+ disabled: {
4406
+ type: Boolean,
4407
+ default: false
4408
+ },
4409
+ multiple: {
4410
+ type: Boolean,
4411
+ default: false
4412
+ },
4413
+ size: { default: "md" },
4414
+ variant: { default: "default" },
4415
+ label: { default: "" },
4416
+ required: {
4417
+ type: Boolean,
4418
+ default: false
4419
+ },
4420
+ error: { default: "" },
4421
+ hint: { default: "" },
4422
+ treeData: { default: () => [] },
4423
+ defaultExpandedKeys: { default: () => [] },
4424
+ defaultCheckedKeys: { default: () => [] },
4425
+ checkable: {
4426
+ type: Boolean,
4427
+ default: false
4428
+ },
4429
+ filterable: {
4430
+ type: Boolean,
4431
+ default: false
4432
+ },
4433
+ clearable: {
4434
+ type: Boolean,
4435
+ default: false
4436
+ },
4437
+ dropdownHeight: { default: 240 },
4438
+ virtualScroll: {
4439
+ type: Boolean,
4440
+ default: false
4441
+ },
4442
+ rowHeight: { default: 32 },
4443
+ overscan: { default: 5 }
4444
+ },
4445
+ emits: [
4446
+ "update:modelValue",
4447
+ "change",
4448
+ "focus",
4449
+ "blur",
4450
+ "check"
4451
+ ],
4452
+ setup(__props, { emit: __emit }) {
4453
+ useCssVars((_ctx) => ({ "v23cc09d6": _ctx.dropdownHeight + "px" }));
4454
+ const props = __props;
4455
+ const emit = __emit;
4456
+ const selectRef = ref();
4457
+ const visible = ref(false);
4458
+ const searchText = ref("");
4459
+ const expandedKeys = ref(props.defaultExpandedKeys);
4460
+ const checkedKeys = ref([...props.defaultCheckedKeys]);
4461
+ const indeterminateKeys = ref([]);
4462
+ const scrollTop = ref(0);
4463
+ const cachedDropdownStyle = ref({});
4464
+ function updateDropdownPosition() {
4465
+ if (!selectRef.value || !visible.value) return;
4466
+ const rect = selectRef.value.getBoundingClientRect();
4467
+ cachedDropdownStyle.value = {
4468
+ position: "fixed",
4469
+ top: `${rect.bottom + 4}px`,
4470
+ left: `${rect.left}px`,
4471
+ width: `${rect.width}px`,
4472
+ zIndex: "2000",
4473
+ willChange: "transform"
4474
+ };
4475
+ }
4476
+ function handleWindowScroll() {
4477
+ if (visible.value) updateDropdownPosition();
4478
+ }
4479
+ function handleWindowResize() {
4480
+ if (visible.value) updateDropdownPosition();
4481
+ }
4482
+ const flattenTree = (nodes, level = 0) => {
4483
+ const result = [];
4484
+ for (const node of nodes) {
4485
+ result.push({
4486
+ ...node,
4487
+ level
4488
+ });
4489
+ if (node.children && expandedKeys.value.includes(node.key)) result.push(...flattenTree(node.children, level + 1));
4490
+ }
4491
+ return result;
4492
+ };
4493
+ const flatNodes = computed(() => flattenTree(props.treeData));
4494
+ const totalHeight = computed(() => flatNodes.value.length * props.rowHeight);
4495
+ const startIndex = computed(() => {
4496
+ if (!props.virtualScroll) return 0;
4497
+ return Math.max(0, Math.floor(scrollTop.value / props.rowHeight) - props.overscan);
4498
+ });
4499
+ const visibleCount = computed(() => {
4500
+ if (!props.virtualScroll) return flatNodes.value.length;
4501
+ return Math.ceil(props.dropdownHeight / props.rowHeight) + props.overscan * 2;
4502
+ });
4503
+ const visibleNodes = computed(() => {
4504
+ if (!props.virtualScroll) return flatNodes.value;
4505
+ return flatNodes.value.slice(startIndex.value, startIndex.value + visibleCount.value);
4506
+ });
4507
+ function handleScroll(e) {
4508
+ scrollTop.value = e.target.scrollTop;
4509
+ }
4510
+ const virtualHeight = computed(() => `${props.dropdownHeight}px`);
4511
+ const wrapperClasses = computed(() => cn("yd-tree-select-wrapper", `yd-tree-select-wrapper--${props.size}`, `yd-tree-select-wrapper--${props.variant}`, props.disabled && "yd-tree-select-wrapper--disabled", props.error && "yd-tree-select-wrapper--error"));
4512
+ const dropdownStyle = computed(() => cachedDropdownStyle.value);
4513
+ const displayPlaceholder = computed(() => {
4514
+ if (props.multiple) return selectedTitles.value.length > 0 ? selectedTitles.value.join(", ") : props.placeholder;
4515
+ return selectedTitle.value || props.placeholder;
4516
+ });
4517
+ const hasValue = computed(() => {
4518
+ if (props.multiple) return Array.isArray(props.modelValue) && props.modelValue.length > 0;
4519
+ return props.modelValue !== "" && props.modelValue !== void 0;
4520
+ });
4521
+ const selectedTitle = computed(() => {
4522
+ if (props.multiple) return "";
4523
+ return findNodeTitle(props.treeData, String(props.modelValue));
4524
+ });
4525
+ const selectedTitles = computed(() => {
4526
+ if (!props.multiple || !Array.isArray(props.modelValue)) return [];
4527
+ return props.modelValue.map((v) => findNodeTitle(props.treeData, String(v)));
4528
+ });
4529
+ function findNodeTitle(nodes, key) {
4530
+ for (const node of nodes) {
4531
+ if (node.key === key) return node.title;
4532
+ if (node.children) {
4533
+ const found = findNodeTitle(node.children, key);
4534
+ if (found) return found;
4535
+ }
4536
+ }
4537
+ return "";
4538
+ }
4539
+ const filteredNodes = computed(() => {
4540
+ if (!props.filterable || !searchText.value) return props.treeData;
4541
+ const query = searchText.value.toLowerCase();
4542
+ return filterNodes(props.treeData, query);
4543
+ });
4544
+ function filterNodes(nodes, query) {
4545
+ const result = [];
4546
+ for (const node of nodes) {
4547
+ const titleMatch = node.title.toLowerCase().includes(query);
4548
+ const children = node.children ? filterNodes(node.children, query) : [];
4549
+ if (titleMatch || children.length > 0) result.push({
4550
+ ...node,
4551
+ children: children.length > 0 ? children : node.children
4552
+ });
4553
+ }
4554
+ return result;
4555
+ }
4556
+ function e(element) {
4557
+ return `yd-tree-select__${element}`;
4558
+ }
4559
+ function hasChildren(node) {
4560
+ return !!(node.children && node.children.length > 0) && node.isLeaf !== true;
4561
+ }
4562
+ function nodeClasses(node) {
4563
+ const isSelected = props.multiple ? Array.isArray(props.modelValue) && props.modelValue.includes(node.key) : props.modelValue === node.key;
4564
+ return [e("node"), {
4565
+ [e("node--selected")]: isSelected,
4566
+ [e("node--disabled")]: node.disabled
4567
+ }];
4568
+ }
4569
+ function handleNodeClick(node) {
4570
+ if (node.disabled) return;
4571
+ if (props.checkable) {
4572
+ handleCheck(node);
4573
+ return;
4574
+ }
4575
+ if (props.multiple) {
4576
+ const current = Array.isArray(props.modelValue) ? [...props.modelValue] : [];
4577
+ const idx = current.indexOf(node.key);
4578
+ if (idx > -1) current.splice(idx, 1);
4579
+ else current.push(node.key);
4580
+ emit("update:modelValue", current);
4581
+ emit("change", current);
4582
+ } else {
4583
+ emit("update:modelValue", node.key);
4584
+ emit("change", node.key);
4585
+ visible.value = false;
4586
+ searchText.value = "";
4587
+ }
4588
+ }
4589
+ function handleToggle(node) {
4590
+ const idx = expandedKeys.value.indexOf(node.key);
4591
+ if (idx > -1) expandedKeys.value.splice(idx, 1);
4592
+ else expandedKeys.value.push(node.key);
4593
+ }
4594
+ function handleCheck(node) {
4595
+ if (node.disabled) return;
4596
+ const idx = checkedKeys.value.indexOf(node.key);
4597
+ if (idx > -1) {
4598
+ checkedKeys.value.splice(idx, 1);
4599
+ uncheckDescendants(node);
4600
+ } else {
4601
+ checkedKeys.value.push(node.key);
4602
+ checkDescendants(node);
4603
+ }
4604
+ updateParentCheckState();
4605
+ emit("update:modelValue", props.multiple ? [...checkedKeys.value] : checkedKeys.value[0] || "");
4606
+ emit("change", props.multiple ? [...checkedKeys.value] : checkedKeys.value[0] || "");
4607
+ emit("check", [...checkedKeys.value]);
4608
+ }
4609
+ function checkDescendants(node) {
4610
+ if (!node.children) return;
4611
+ for (const child of node.children) {
4612
+ if (!checkedKeys.value.includes(child.key)) checkedKeys.value.push(child.key);
4613
+ checkDescendants(child);
4614
+ }
4615
+ }
4616
+ function uncheckDescendants(node) {
4617
+ if (!node.children) return;
4618
+ for (const child of node.children) {
4619
+ const idx = checkedKeys.value.indexOf(child.key);
4620
+ if (idx > -1) checkedKeys.value.splice(idx, 1);
4621
+ uncheckDescendants(child);
4622
+ }
4623
+ }
4624
+ function updateParentCheckState() {
4625
+ indeterminateKeys.value = [];
4626
+ }
4627
+ function handleClear() {
4628
+ if (props.multiple) {
4629
+ emit("update:modelValue", []);
4630
+ emit("change", []);
4631
+ } else {
4632
+ emit("update:modelValue", "");
4633
+ emit("change", "");
4634
+ }
4635
+ checkedKeys.value = [];
4636
+ searchText.value = "";
4637
+ }
4638
+ function toggleDropdown() {
4639
+ if (props.disabled) return;
4640
+ visible.value = !visible.value;
4641
+ if (visible.value) {
4642
+ searchText.value = "";
4643
+ if (!props.multiple && expandedKeys.value.length === 0) expandedKeys.value = props.treeData.map((n) => n.key);
4644
+ nextTick(() => {
4645
+ updateDropdownPosition();
4646
+ selectRef.value?.querySelector("input")?.focus();
4647
+ });
4648
+ }
4649
+ }
4650
+ const debouncedFilter = debounce(() => {}, 300);
4651
+ function handleSearch(event) {
4652
+ searchText.value = event.target.value;
4653
+ debouncedFilter();
4654
+ if (!visible.value) visible.value = true;
4655
+ }
4656
+ function handleFocus(event) {
4657
+ emit("focus", event);
4658
+ }
4659
+ function handleBlur(event) {
4660
+ if (props.multiple) return;
4661
+ setTimeout(() => {
4662
+ visible.value = false;
4663
+ }, 200);
4664
+ emit("blur", event);
4665
+ }
4666
+ function handleClickOutside(event) {
4667
+ if (selectRef.value && !selectRef.value.contains(event.target)) visible.value = false;
4668
+ }
4669
+ onMounted(() => {
4670
+ document.addEventListener("click", handleClickOutside);
4671
+ window.addEventListener("scroll", handleWindowScroll, true);
4672
+ window.addEventListener("resize", handleWindowResize);
4673
+ });
4674
+ onUnmounted(() => {
4675
+ document.removeEventListener("click", handleClickOutside);
4676
+ window.removeEventListener("scroll", handleWindowScroll, true);
4677
+ window.removeEventListener("resize", handleWindowResize);
4678
+ });
4679
+ return (_ctx, _cache) => {
4680
+ return openBlock(), createElementBlock("div", {
4681
+ ref_key: "selectRef",
4682
+ ref: selectRef,
4683
+ class: normalizeClass(wrapperClasses.value),
4684
+ onClick: toggleDropdown
4685
+ }, [
4686
+ __props.label ? (openBlock(), createElementBlock("div", {
4687
+ key: 0,
4688
+ class: normalizeClass(e("label"))
4689
+ }, [createElementVNode("label", null, toDisplayString(__props.label), 1), __props.required ? (openBlock(), createElementBlock("span", {
4690
+ key: 0,
4691
+ class: normalizeClass(e("required"))
4692
+ }, "*", 2)) : createCommentVNode("v-if", true)], 2)) : createCommentVNode("v-if", true),
4693
+ createElementVNode("div", { class: normalizeClass(e("control")) }, [
4694
+ __props.filterable ? (openBlock(), createElementBlock("input", {
4695
+ key: 0,
4696
+ class: normalizeClass(e("input")),
4697
+ value: searchText.value,
4698
+ placeholder: displayPlaceholder.value,
4699
+ disabled: __props.disabled,
4700
+ onInput: handleSearch,
4701
+ onFocus: handleFocus,
4702
+ onBlur: handleBlur,
4703
+ onKeydown: _cache[0] || (_cache[0] = withModifiers(() => {}, ["stop"]))
4704
+ }, null, 42, _hoisted_1$22)) : (openBlock(), createElementBlock("div", {
4705
+ key: 1,
4706
+ class: normalizeClass([e("display"), { [e("display--placeholder")]: !selectedTitle.value }])
4707
+ }, toDisplayString(selectedTitle.value || __props.placeholder), 3)),
4708
+ __props.clearable && hasValue.value && !__props.disabled ? (openBlock(), createElementBlock("span", {
4709
+ key: 2,
4710
+ class: normalizeClass(e("clear")),
4711
+ onClick: withModifiers(handleClear, ["stop"])
4712
+ }, [..._cache[2] || (_cache[2] = [createElementVNode("svg", {
4713
+ xmlns: "http://www.w3.org/2000/svg",
4714
+ width: "14",
4715
+ height: "14",
4716
+ viewBox: "0 0 24 24",
4717
+ fill: "none",
4718
+ stroke: "currentColor",
4719
+ "stroke-width": "2",
4720
+ "stroke-linecap": "round",
4721
+ "stroke-linejoin": "round"
4722
+ }, [createElementVNode("line", {
4723
+ x1: "18",
4724
+ y1: "6",
4725
+ x2: "6",
4726
+ y2: "18"
4727
+ }), createElementVNode("line", {
4728
+ x1: "6",
4729
+ y1: "6",
4730
+ x2: "18",
4731
+ y2: "18"
4732
+ })], -1)])], 2)) : createCommentVNode("v-if", true),
4733
+ createElementVNode("span", { class: normalizeClass(e("arrow")) }, [..._cache[3] || (_cache[3] = [createElementVNode("svg", {
4734
+ xmlns: "http://www.w3.org/2000/svg",
4735
+ width: "12",
4736
+ height: "12",
4737
+ viewBox: "0 0 24 24",
4738
+ fill: "none",
4739
+ stroke: "currentColor",
4740
+ "stroke-width": "2",
4741
+ "stroke-linecap": "round",
4742
+ "stroke-linejoin": "round"
4743
+ }, [createElementVNode("polyline", { points: "6 9 12 15 18 9" })], -1)])], 2)
4744
+ ], 2),
4745
+ __props.error || __props.hint ? (openBlock(), createElementBlock("div", {
4746
+ key: 1,
4747
+ class: normalizeClass([e("message"), { [e("message--error")]: __props.error }])
4748
+ }, toDisplayString(__props.error || __props.hint), 3)) : createCommentVNode("v-if", true),
4749
+ createCommentVNode(" Dropdown "),
4750
+ (openBlock(), createBlock(Teleport, { to: "body" }, [createVNode(Transition, { name: "yd-tree-select-dropdown" }, {
4751
+ default: withCtx(() => [visible.value ? (openBlock(), createElementBlock("div", {
4752
+ key: 0,
4753
+ class: normalizeClass(e("dropdown")),
4754
+ style: normalizeStyle(dropdownStyle.value),
4755
+ onClick: _cache[1] || (_cache[1] = withModifiers(() => {}, ["stop"]))
4756
+ }, [createCommentVNode(" Virtual scroll wrapper "), __props.virtualScroll ? (openBlock(), createElementBlock("div", {
4757
+ key: 0,
4758
+ class: normalizeClass(e("virtual-wrapper")),
4759
+ style: normalizeStyle({ height: virtualHeight.value })
4760
+ }, [createElementVNode("div", {
4761
+ class: normalizeClass(e("tree-container")),
4762
+ style: normalizeStyle({ height: `${totalHeight.value}px` }),
4763
+ onScroll: handleScroll
4764
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleNodes.value, (node, index) => {
4765
+ return openBlock(), createElementBlock("div", {
4766
+ key: node.key,
4767
+ class: normalizeClass(nodeClasses(node)),
4768
+ style: normalizeStyle({
4769
+ position: "absolute",
4770
+ top: `${index * __props.rowHeight}px`,
4771
+ height: `${__props.rowHeight}px`,
4772
+ paddingLeft: `${node.level * 20 + 8}px`
4773
+ }),
4774
+ onClick: withModifiers(($event) => handleNodeClick(node), ["stop"])
4775
+ }, [
4776
+ hasChildren(node) ? (openBlock(), createElementBlock("span", {
4777
+ key: 0,
4778
+ class: normalizeClass(e("node-toggle")),
4779
+ onClick: withModifiers(($event) => handleToggle(node), ["stop"])
4780
+ }, toDisplayString(expandedKeys.value.includes(node.key) ? "▾" : "▸"), 11, _hoisted_3$9)) : (openBlock(), createElementBlock("span", {
4781
+ key: 1,
4782
+ class: normalizeClass(e("node-leaf"))
4783
+ }, "•", 2)),
4784
+ __props.checkable ? (openBlock(), createElementBlock("span", {
4785
+ key: 2,
4786
+ class: normalizeClass(e("node-checkbox")),
4787
+ onClick: withModifiers(($event) => handleCheck(node), ["stop"])
4788
+ }, [createElementVNode("input", {
4789
+ type: "checkbox",
4790
+ checked: checkedKeys.value.includes(node.key),
4791
+ indeterminate: indeterminateKeys.value.includes(node.key),
4792
+ disabled: node.disabled
4793
+ }, null, 8, _hoisted_5$5)], 10, _hoisted_4$8)) : createCommentVNode("v-if", true),
4794
+ createElementVNode("span", { class: normalizeClass(e("node-title")) }, toDisplayString(node.title), 3)
4795
+ ], 14, _hoisted_2$14);
4796
+ }), 128))], 38)], 6)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Normal mode "), createElementVNode("div", { class: normalizeClass(e("tree-container")) }, [(openBlock(true), createElementBlock(Fragment, null, renderList(filteredNodes.value, (node) => {
4797
+ return openBlock(), createElementBlock("div", {
4798
+ key: node.key,
4799
+ class: normalizeClass(nodeClasses(node)),
4800
+ onClick: withModifiers(($event) => handleNodeClick(node), ["stop"])
4801
+ }, [
4802
+ hasChildren(node) ? (openBlock(), createElementBlock("span", {
4803
+ key: 0,
4804
+ class: normalizeClass(e("node-toggle")),
4805
+ onClick: withModifiers(($event) => handleToggle(node), ["stop"])
4806
+ }, toDisplayString(expandedKeys.value.includes(node.key) ? "▾" : "▸"), 11, _hoisted_7$4)) : (openBlock(), createElementBlock("span", {
4807
+ key: 1,
4808
+ class: normalizeClass(e("node-leaf"))
4809
+ }, "•", 2)),
4810
+ __props.checkable ? (openBlock(), createElementBlock("span", {
4811
+ key: 2,
4812
+ class: normalizeClass(e("node-checkbox")),
4813
+ onClick: withModifiers(($event) => handleCheck(node), ["stop"])
4814
+ }, [createElementVNode("input", {
4815
+ type: "checkbox",
4816
+ checked: checkedKeys.value.includes(node.key),
4817
+ indeterminate: indeterminateKeys.value.includes(node.key),
4818
+ disabled: node.disabled
4819
+ }, null, 8, _hoisted_9$4)], 10, _hoisted_8$4)) : createCommentVNode("v-if", true),
4820
+ createElementVNode("span", { class: normalizeClass(e("node-title")) }, toDisplayString(node.title), 3),
4821
+ hasChildren(node) && expandedKeys.value.includes(node.key) ? (openBlock(), createElementBlock("div", {
4822
+ key: 3,
4823
+ class: normalizeClass(e("node-children"))
4824
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(node.children, (child) => {
4825
+ return openBlock(), createElementBlock("div", {
4826
+ key: child.key,
4827
+ class: normalizeClass(nodeClasses(child)),
4828
+ onClick: withModifiers(($event) => handleNodeClick(child), ["stop"])
4829
+ }, [
4830
+ hasChildren(child) ? (openBlock(), createElementBlock("span", {
4831
+ key: 0,
4832
+ class: normalizeClass(e("node-toggle")),
4833
+ onClick: withModifiers(($event) => handleToggle(child), ["stop"])
4834
+ }, toDisplayString(expandedKeys.value.includes(child.key) ? "▾" : "▸"), 11, _hoisted_11$3)) : (openBlock(), createElementBlock("span", {
4835
+ key: 1,
4836
+ class: normalizeClass(e("node-leaf"))
4837
+ }, "•", 2)),
4838
+ __props.checkable ? (openBlock(), createElementBlock("span", {
4839
+ key: 2,
4840
+ class: normalizeClass(e("node-checkbox")),
4841
+ onClick: withModifiers(($event) => handleCheck(child), ["stop"])
4842
+ }, [createElementVNode("input", {
4843
+ type: "checkbox",
4844
+ checked: checkedKeys.value.includes(child.key),
4845
+ indeterminate: indeterminateKeys.value.includes(child.key),
4846
+ disabled: child.disabled
4847
+ }, null, 8, _hoisted_13$2)], 10, _hoisted_12$3)) : createCommentVNode("v-if", true),
4848
+ createElementVNode("span", { class: normalizeClass(e("node-title")) }, toDisplayString(child.title), 3)
4849
+ ], 10, _hoisted_10$3);
4850
+ }), 128))], 2)) : createCommentVNode("v-if", true)
4851
+ ], 10, _hoisted_6$5);
4852
+ }), 128)), filteredNodes.value.length === 0 ? (openBlock(), createBlock(empty_default, {
4853
+ key: 0,
4854
+ description: "暂无数据"
4855
+ })) : createCommentVNode("v-if", true)], 2)], 2112))], 6)) : createCommentVNode("v-if", true)]),
4856
+ _: 1
4857
+ })]))
4858
+ ], 2);
4859
+ };
4860
+ }
4861
+ }), [["__scopeId", "data-v-f36bc312"]]);
4862
+ //#endregion
4863
+ //#region src/components/base/color-picker/color-picker.vue
4864
+ const _hoisted_1$21 = [
4865
+ "value",
4866
+ "placeholder",
4867
+ "disabled"
4868
+ ];
4869
+ const _hoisted_2$13 = {
4870
+ xmlns: "http://www.w3.org/2000/svg",
4871
+ width: "14",
4872
+ height: "14",
4873
+ viewBox: "0 0 24 24",
4874
+ fill: "none",
4875
+ stroke: "currentColor",
4876
+ "stroke-width": "2"
4877
+ };
4878
+ const _hoisted_3$8 = ["fill"];
4879
+ const _hoisted_4$7 = ["value"];
4880
+ const _hoisted_5$4 = ["value"];
4881
+ const _hoisted_6$4 = ["value"];
4882
+ const _hoisted_7$3 = ["value"];
4883
+ const _hoisted_8$3 = ["value"];
4884
+ const _hoisted_9$3 = ["onClick"];
4885
+ var color_picker_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
4886
+ name: "YdColorPicker",
4887
+ inheritAttrs: false,
4888
+ __name: "color-picker",
4889
+ props: {
4890
+ modelValue: { default: "" },
4891
+ placeholder: { default: "#ffffff" },
4892
+ disabled: {
4893
+ type: Boolean,
4894
+ default: false
4895
+ },
4896
+ size: { default: "md" },
4897
+ variant: { default: "default" },
4898
+ label: { default: "" },
4899
+ required: {
4900
+ type: Boolean,
4901
+ default: false
4902
+ },
4903
+ error: { default: "" },
4904
+ hint: { default: "" },
4905
+ showAlpha: {
4906
+ type: Boolean,
4907
+ default: false
4908
+ },
4909
+ showPreset: {
4910
+ type: Boolean,
4911
+ default: true
4912
+ },
4913
+ showPreview: {
4914
+ type: Boolean,
4915
+ default: true
4916
+ },
4917
+ editable: {
4918
+ type: Boolean,
4919
+ default: true
4920
+ },
4921
+ clearable: {
4922
+ type: Boolean,
4923
+ default: true
4924
+ },
4925
+ presetColors: { default: () => [
4926
+ "#ffffff",
4927
+ "#000000",
4928
+ "#FF4500",
4929
+ "#FF8C00",
4930
+ "#FFD700",
4931
+ "#9ACD32",
4932
+ "#00FF00",
4933
+ "#00CED1",
4934
+ "#1E90FF",
4935
+ "#0000FF",
4936
+ "#8B008B",
4937
+ "#FF1493"
4938
+ ] }
4939
+ },
4940
+ emits: [
4941
+ "update:modelValue",
4942
+ "change",
4943
+ "focus",
4944
+ "blur"
4945
+ ],
4946
+ setup(__props, { emit: __emit }) {
4947
+ const props = __props;
4948
+ const emit = __emit;
4949
+ const pickerRef = ref();
4950
+ const saturationRef = ref();
4951
+ const hueRef = ref();
4952
+ const alphaRef = ref();
4953
+ const visible = ref(false);
4954
+ const hueValue = ref(0);
4955
+ const saturationValue = ref(100);
4956
+ const brightnessValue = ref(100);
4957
+ const alphaValue = ref(1);
4958
+ const cachedDropdownStyle = ref({});
4959
+ watch(() => props.modelValue, (val) => {
4960
+ if (val) {
4961
+ const parsed = parseColor(val);
4962
+ if (parsed) {
4963
+ hueValue.value = parsed.h;
4964
+ saturationValue.value = parsed.s;
4965
+ brightnessValue.value = parsed.b;
4966
+ alphaValue.value = parsed.a;
4967
+ }
4968
+ }
4969
+ }, { immediate: true });
4970
+ function parseColor(color) {
4971
+ if (!color) return null;
4972
+ if (color.startsWith("#")) {
4973
+ const hex = color.slice(1);
4974
+ let r, g, b, a = 1;
4975
+ if (hex.length === 3) {
4976
+ r = parseInt(hex[0] + hex[0], 16);
4977
+ g = parseInt(hex[1] + hex[1], 16);
4978
+ b = parseInt(hex[2] + hex[2], 16);
4979
+ } else if (hex.length === 6) {
4980
+ r = parseInt(hex.slice(0, 2), 16);
4981
+ g = parseInt(hex.slice(2, 4), 16);
4982
+ b = parseInt(hex.slice(4, 6), 16);
4983
+ } else if (hex.length === 8) {
4984
+ r = parseInt(hex.slice(0, 2), 16);
4985
+ g = parseInt(hex.slice(2, 4), 16);
4986
+ b = parseInt(hex.slice(4, 6), 16);
4987
+ a = parseInt(hex.slice(6, 8), 16) / 255;
4988
+ } else return null;
4989
+ const [h, s, v] = rgbToHsv(r, g, b);
4990
+ return {
4991
+ h,
4992
+ s: s * 100,
4993
+ b: v * 100,
4994
+ a
4995
+ };
4996
+ }
4997
+ return null;
4998
+ }
4999
+ function rgbToHsv(r, g, b) {
5000
+ r /= 255;
5001
+ g /= 255;
5002
+ b /= 255;
5003
+ const max = Math.max(r, g, b);
5004
+ const min = Math.min(r, g, b);
5005
+ const d = max - min;
5006
+ let h = 0;
5007
+ const s = max === 0 ? 0 : d / max;
5008
+ const v = max;
5009
+ if (max !== min) {
5010
+ switch (max) {
5011
+ case r:
5012
+ h = (g - b) / d + (g < b ? 6 : 0);
5013
+ break;
5014
+ case g:
5015
+ h = (b - r) / d + 2;
5016
+ break;
5017
+ case b:
5018
+ h = (r - g) / d + 4;
5019
+ break;
5020
+ }
5021
+ h /= 6;
5022
+ }
5023
+ return [
5024
+ h * 360,
5025
+ s,
5026
+ v
5027
+ ];
5028
+ }
5029
+ function hsvToRgb(h, s, v) {
5030
+ h /= 360;
5031
+ s /= 100;
5032
+ v /= 100;
5033
+ let r = 0, g = 0, b = 0;
5034
+ const i = Math.floor(h * 6);
5035
+ const f = h * 6 - i;
5036
+ const p = v * (1 - s);
5037
+ const q = v * (1 - f * s);
5038
+ const t = v * (1 - (1 - f) * s);
5039
+ switch (i % 6) {
5040
+ case 0:
5041
+ r = v;
5042
+ g = t;
5043
+ b = p;
5044
+ break;
5045
+ case 1:
5046
+ r = q;
5047
+ g = v;
5048
+ b = p;
5049
+ break;
5050
+ case 2:
5051
+ r = p;
5052
+ g = v;
5053
+ b = t;
5054
+ break;
5055
+ case 3:
5056
+ r = p;
5057
+ g = q;
5058
+ b = v;
5059
+ break;
5060
+ case 4:
5061
+ r = t;
5062
+ g = p;
5063
+ b = v;
5064
+ break;
5065
+ case 5:
5066
+ r = v;
5067
+ g = p;
5068
+ b = q;
5069
+ break;
5070
+ }
5071
+ return [
5072
+ Math.round(r * 255),
5073
+ Math.round(g * 255),
5074
+ Math.round(b * 255)
5075
+ ];
5076
+ }
5077
+ const hexValue = computed(() => {
5078
+ const [r, g, b] = hsvToRgb(hueValue.value, saturationValue.value, brightnessValue.value);
5079
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`.toUpperCase();
5080
+ });
5081
+ const rgbValue = computed(() => {
5082
+ const [r, g, b] = hsvToRgb(hueValue.value, saturationValue.value, brightnessValue.value);
5083
+ return {
5084
+ r,
5085
+ g,
5086
+ b
5087
+ };
5088
+ });
5089
+ const displayValue = computed(() => {
5090
+ const hex = hexValue.value;
5091
+ if (props.showAlpha && alphaValue.value < 1) return `rgba(${parseInt(hex.slice(1, 3), 16)}, ${parseInt(hex.slice(3, 5), 16)}, ${parseInt(hex.slice(5, 7), 16)}, ${alphaValue.value})`;
5092
+ return hex;
5093
+ });
5094
+ const hueColor = computed(() => {
5095
+ return `hsl(${hueValue.value}, 100%, 50%)`;
5096
+ });
5097
+ const saturationPosition = computed(() => ({
5098
+ x: saturationValue.value,
5099
+ y: 100 - brightnessValue.value
5100
+ }));
5101
+ function updateDropdownPosition() {
5102
+ if (!pickerRef.value || !visible.value) return;
5103
+ const rect = pickerRef.value.getBoundingClientRect();
5104
+ cachedDropdownStyle.value = {
5105
+ position: "fixed",
5106
+ top: `${rect.bottom + 4}px`,
5107
+ left: `${rect.left}px`,
5108
+ zIndex: "2000"
5109
+ };
5110
+ }
5111
+ function handleWindowScroll() {
5112
+ if (visible.value) updateDropdownPosition();
5113
+ }
5114
+ function handleWindowResize() {
5115
+ if (visible.value) updateDropdownPosition();
5116
+ }
5117
+ const wrapperClasses = computed(() => cn("yd-color-picker-wrapper", `yd-color-picker-wrapper--${props.size}`, `yd-color-picker-wrapper--${props.variant}`, props.disabled && "yd-color-picker-wrapper--disabled", props.error && "yd-color-picker-wrapper--error"));
5118
+ const dropdownStyle = computed(() => cachedDropdownStyle.value);
5119
+ function e(element) {
5120
+ return `yd-color-picker__${element}`;
5121
+ }
5122
+ function emitColor() {
5123
+ let color = hexValue.value;
5124
+ if (props.showAlpha && alphaValue.value < 1) {
5125
+ const r = parseInt(color.slice(1, 3), 16);
5126
+ const g = parseInt(color.slice(3, 5), 16);
5127
+ const b = parseInt(color.slice(5, 7), 16);
5128
+ const a = Math.round(alphaValue.value * 255).toString(16).padStart(2, "0");
5129
+ color = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}${a}`;
5130
+ }
5131
+ emit("update:modelValue", color);
5132
+ emit("change", color);
5133
+ }
5134
+ function handleInput(event) {
5135
+ const value = event.target.value;
5136
+ const parsed = parseColor(value);
5137
+ if (parsed) {
5138
+ hueValue.value = parsed.h;
5139
+ saturationValue.value = parsed.s;
5140
+ brightnessValue.value = parsed.b;
5141
+ emitColor();
5142
+ }
5143
+ }
5144
+ function handleHexInput(event) {
5145
+ const value = event.target.value;
5146
+ const parsed = parseColor(value);
5147
+ if (parsed) {
5148
+ hueValue.value = parsed.h;
5149
+ saturationValue.value = parsed.s;
5150
+ brightnessValue.value = parsed.b;
5151
+ emitColor();
5152
+ }
5153
+ }
5154
+ function handleRgbInput(channel, event) {
5155
+ const value = parseInt(event.target.value) || 0;
5156
+ const newRgb = {
5157
+ ...rgbValue.value,
5158
+ [channel]: Math.min(255, Math.max(0, value))
5159
+ };
5160
+ const [h, s, v] = rgbToHsv(newRgb.r, newRgb.g, newRgb.b);
5161
+ hueValue.value = h;
5162
+ saturationValue.value = s * 100;
5163
+ brightnessValue.value = v * 100;
5164
+ emitColor();
5165
+ }
5166
+ function handleAlphaInput(event) {
5167
+ alphaValue.value = Math.min(100, Math.max(0, parseInt(event.target.value) || 0)) / 100;
5168
+ emitColor();
5169
+ }
5170
+ function handlePresetClick(color) {
5171
+ const parsed = parseColor(color);
5172
+ if (parsed) {
5173
+ hueValue.value = parsed.h;
5174
+ saturationValue.value = parsed.s;
5175
+ brightnessValue.value = parsed.b;
5176
+ alphaValue.value = parsed.a;
5177
+ emitColor();
5178
+ }
5179
+ }
5180
+ function handleClear() {
5181
+ emit("update:modelValue", "");
5182
+ emit("change", "");
5183
+ }
5184
+ function togglePicker() {
5185
+ if (props.disabled) return;
5186
+ visible.value = !visible.value;
5187
+ if (visible.value) nextTick(() => updateDropdownPosition());
5188
+ }
5189
+ function handleFocus(event) {
5190
+ emit("focus", event);
5191
+ }
5192
+ function handleBlur(event) {
5193
+ emit("blur", event);
5194
+ }
5195
+ let isDraggingSaturation = false;
5196
+ function handleSaturationStart(e) {
5197
+ isDraggingSaturation = true;
5198
+ updateSaturation(e);
5199
+ document.addEventListener("mousemove", handleSaturationMove);
5200
+ document.addEventListener("mouseup", handleSaturationEnd);
5201
+ }
5202
+ function handleSaturationMove(e) {
5203
+ if (isDraggingSaturation) updateSaturation(e);
5204
+ }
5205
+ function handleSaturationEnd() {
5206
+ isDraggingSaturation = false;
5207
+ document.removeEventListener("mousemove", handleSaturationMove);
5208
+ document.removeEventListener("mouseup", handleSaturationEnd);
5209
+ }
5210
+ function updateSaturation(e) {
5211
+ if (!saturationRef.value) return;
5212
+ const rect = saturationRef.value.getBoundingClientRect();
5213
+ const x = Math.min(100, Math.max(0, (e.clientX - rect.left) / rect.width * 100));
5214
+ const y = Math.min(100, Math.max(0, (e.clientY - rect.top) / rect.height * 100));
5215
+ saturationValue.value = x;
5216
+ brightnessValue.value = 100 - y;
5217
+ emitColor();
5218
+ }
5219
+ let isDraggingHue = false;
5220
+ function handleHueStart(e) {
5221
+ isDraggingHue = true;
5222
+ updateHue(e);
5223
+ document.addEventListener("mousemove", handleHueMove);
5224
+ document.addEventListener("mouseup", handleHueEnd);
5225
+ }
5226
+ function handleHueMove(e) {
5227
+ if (isDraggingHue) updateHue(e);
5228
+ }
5229
+ function handleHueEnd() {
5230
+ isDraggingHue = false;
5231
+ document.removeEventListener("mousemove", handleHueMove);
5232
+ document.removeEventListener("mouseup", handleHueEnd);
5233
+ }
5234
+ function updateHue(e) {
5235
+ if (!hueRef.value) return;
5236
+ const rect = hueRef.value.getBoundingClientRect();
5237
+ hueValue.value = Math.min(100, Math.max(0, (e.clientX - rect.left) / rect.width * 100)) * 3.6;
5238
+ emitColor();
5239
+ }
5240
+ let isDraggingAlpha = false;
5241
+ function handleAlphaStart(e) {
5242
+ isDraggingAlpha = true;
5243
+ updateAlpha(e);
5244
+ document.addEventListener("mousemove", handleAlphaMove);
5245
+ document.addEventListener("mouseup", handleAlphaEnd);
5246
+ }
5247
+ function handleAlphaMove(e) {
5248
+ if (isDraggingAlpha) updateAlpha(e);
5249
+ }
5250
+ function handleAlphaEnd() {
5251
+ isDraggingAlpha = false;
5252
+ document.removeEventListener("mousemove", handleAlphaMove);
5253
+ document.removeEventListener("mouseup", handleAlphaEnd);
5254
+ }
5255
+ function updateAlpha(e) {
5256
+ if (!alphaRef.value) return;
5257
+ const rect = alphaRef.value.getBoundingClientRect();
5258
+ alphaValue.value = Math.min(100, Math.max(0, (e.clientX - rect.left) / rect.width * 100)) / 100;
5259
+ emitColor();
5260
+ }
5261
+ function handleClickOutside(event) {
5262
+ if (pickerRef.value && !pickerRef.value.contains(event.target)) visible.value = false;
5263
+ }
5264
+ onMounted(() => {
5265
+ document.addEventListener("click", handleClickOutside);
5266
+ window.addEventListener("scroll", handleWindowScroll, true);
5267
+ window.addEventListener("resize", handleWindowResize);
5268
+ });
5269
+ onUnmounted(() => {
5270
+ document.removeEventListener("click", handleClickOutside);
5271
+ window.removeEventListener("scroll", handleWindowScroll, true);
5272
+ window.removeEventListener("resize", handleWindowResize);
5273
+ });
5274
+ return (_ctx, _cache) => {
5275
+ return openBlock(), createElementBlock("div", {
5276
+ ref_key: "pickerRef",
5277
+ ref: pickerRef,
5278
+ class: normalizeClass(wrapperClasses.value),
5279
+ onClick: togglePicker
5280
+ }, [
5281
+ __props.label ? (openBlock(), createElementBlock("div", {
5282
+ key: 0,
5283
+ class: normalizeClass(e("label"))
5284
+ }, [createElementVNode("label", null, toDisplayString(__props.label), 1), __props.required ? (openBlock(), createElementBlock("span", {
5285
+ key: 0,
5286
+ class: normalizeClass(e("required"))
5287
+ }, "*", 2)) : createCommentVNode("v-if", true)], 2)) : createCommentVNode("v-if", true),
5288
+ createElementVNode("div", { class: normalizeClass(e("control")) }, [
5289
+ createCommentVNode(" Color preview "),
5290
+ __props.showPreview ? (openBlock(), createElementBlock("div", {
5291
+ key: 0,
5292
+ class: normalizeClass(e("preview")),
5293
+ style: normalizeStyle({ backgroundColor: displayValue.value })
5294
+ }, null, 6)) : createCommentVNode("v-if", true),
5295
+ createCommentVNode(" Input "),
5296
+ __props.editable ? (openBlock(), createElementBlock("input", {
5297
+ key: 1,
5298
+ class: normalizeClass(e("input")),
5299
+ value: __props.modelValue,
5300
+ placeholder: __props.placeholder,
5301
+ disabled: __props.disabled,
5302
+ onInput: handleInput,
5303
+ onFocus: handleFocus,
5304
+ onBlur: handleBlur
5305
+ }, null, 42, _hoisted_1$21)) : createCommentVNode("v-if", true),
5306
+ createCommentVNode(" Clear button "),
5307
+ __props.clearable && __props.modelValue && !__props.disabled ? (openBlock(), createElementBlock("span", {
5308
+ key: 2,
5309
+ class: normalizeClass(e("clear")),
5310
+ onClick: withModifiers(handleClear, ["stop"])
5311
+ }, [..._cache[4] || (_cache[4] = [createElementVNode("svg", {
5312
+ xmlns: "http://www.w3.org/2000/svg",
5313
+ width: "14",
5314
+ height: "14",
5315
+ viewBox: "0 0 24 24",
5316
+ fill: "none",
5317
+ stroke: "currentColor",
5318
+ "stroke-width": "2",
5319
+ "stroke-linecap": "round",
5320
+ "stroke-linejoin": "round"
5321
+ }, [createElementVNode("line", {
5322
+ x1: "18",
5323
+ y1: "6",
5324
+ x2: "6",
5325
+ y2: "18"
5326
+ }), createElementVNode("line", {
5327
+ x1: "6",
5328
+ y1: "6",
5329
+ x2: "18",
5330
+ y2: "18"
5331
+ })], -1)])], 2)) : createCommentVNode("v-if", true),
5332
+ createCommentVNode(" Trigger button "),
5333
+ createElementVNode("span", { class: normalizeClass(e("trigger")) }, [(openBlock(), createElementBlock("svg", _hoisted_2$13, [_cache[5] || (_cache[5] = createElementVNode("circle", {
5334
+ cx: "12",
5335
+ cy: "12",
5336
+ r: "10"
5337
+ }, null, -1)), createElementVNode("path", {
5338
+ d: "M12 2a10 10 0 0 1 0 20",
5339
+ fill: __props.modelValue || "#ffffff"
5340
+ }, null, 8, _hoisted_3$8)]))], 2)
5341
+ ], 2),
5342
+ __props.error || __props.hint ? (openBlock(), createElementBlock("div", {
5343
+ key: 1,
5344
+ class: normalizeClass([e("message"), { [e("message--error")]: __props.error }])
5345
+ }, toDisplayString(__props.error || __props.hint), 3)) : createCommentVNode("v-if", true),
5346
+ createCommentVNode(" Picker dropdown "),
5347
+ (openBlock(), createBlock(Teleport, { to: "body" }, [createVNode(Transition, { name: "yd-color-picker-dropdown" }, {
5348
+ default: withCtx(() => [visible.value ? (openBlock(), createElementBlock("div", {
5349
+ key: 0,
5350
+ class: normalizeClass(e("dropdown")),
5351
+ style: normalizeStyle(dropdownStyle.value),
5352
+ onClick: _cache[3] || (_cache[3] = withModifiers(() => {}, ["stop"]))
5353
+ }, [
5354
+ createCommentVNode(" Saturation/Brightness area "),
5355
+ createElementVNode("div", {
5356
+ ref_key: "saturationRef",
5357
+ ref: saturationRef,
5358
+ class: normalizeClass(e("saturation")),
5359
+ style: normalizeStyle({ backgroundColor: hueColor.value }),
5360
+ onMousedown: handleSaturationStart
5361
+ }, [
5362
+ createElementVNode("div", { class: normalizeClass(e("saturation-white")) }, null, 2),
5363
+ createElementVNode("div", { class: normalizeClass(e("saturation-black")) }, null, 2),
5364
+ createElementVNode("div", {
5365
+ class: normalizeClass(e("saturation-cursor")),
5366
+ style: normalizeStyle({
5367
+ left: `${saturationPosition.value.x}%`,
5368
+ top: `${saturationPosition.value.y}%`
5369
+ })
5370
+ }, null, 6)
5371
+ ], 38),
5372
+ createCommentVNode(" Hue slider "),
5373
+ createElementVNode("div", {
5374
+ ref_key: "hueRef",
5375
+ ref: hueRef,
5376
+ class: normalizeClass(e("hue")),
5377
+ onMousedown: handleHueStart
5378
+ }, [createElementVNode("div", {
5379
+ class: normalizeClass(e("hue-cursor")),
5380
+ style: normalizeStyle({ left: `${hueValue.value / 360 * 100}%` })
5381
+ }, null, 6)], 34),
5382
+ createCommentVNode(" Alpha slider "),
5383
+ __props.showAlpha ? (openBlock(), createElementBlock("div", {
5384
+ key: 0,
5385
+ ref_key: "alphaRef",
5386
+ ref: alphaRef,
5387
+ class: normalizeClass(e("alpha")),
5388
+ onMousedown: handleAlphaStart
5389
+ }, [
5390
+ createElementVNode("div", { class: normalizeClass(e("alpha-bg")) }, null, 2),
5391
+ createElementVNode("div", {
5392
+ class: normalizeClass(e("alpha-fill")),
5393
+ style: normalizeStyle({
5394
+ width: `${alphaValue.value * 100}%`,
5395
+ backgroundColor: `hsl(${hueValue.value}, 100%, 50%)`
5396
+ })
5397
+ }, null, 6),
5398
+ createElementVNode("div", {
5399
+ class: normalizeClass(e("alpha-cursor")),
5400
+ style: normalizeStyle({ left: `${alphaValue.value * 100}%` })
5401
+ }, null, 6)
5402
+ ], 34)) : createCommentVNode("v-if", true),
5403
+ createCommentVNode(" Color values "),
5404
+ createElementVNode("div", { class: normalizeClass(e("values")) }, [
5405
+ createElementVNode("div", { class: normalizeClass(e("value-item")) }, [createElementVNode("span", { class: normalizeClass(e("value-label")) }, "HEX", 2), createElementVNode("input", {
5406
+ class: normalizeClass(e("value-input")),
5407
+ value: hexValue.value,
5408
+ onInput: handleHexInput
5409
+ }, null, 42, _hoisted_4$7)], 2),
5410
+ createElementVNode("div", { class: normalizeClass(e("value-item")) }, [createElementVNode("span", { class: normalizeClass(e("value-label")) }, "R", 2), createElementVNode("input", {
5411
+ class: normalizeClass(e("value-input")),
5412
+ type: "number",
5413
+ min: 0,
5414
+ max: 255,
5415
+ value: rgbValue.value.r,
5416
+ onInput: _cache[0] || (_cache[0] = (e) => handleRgbInput("r", e))
5417
+ }, null, 42, _hoisted_5$4)], 2),
5418
+ createElementVNode("div", { class: normalizeClass(e("value-item")) }, [createElementVNode("span", { class: normalizeClass(e("value-label")) }, "G", 2), createElementVNode("input", {
5419
+ class: normalizeClass(e("value-input")),
5420
+ type: "number",
5421
+ min: 0,
5422
+ max: 255,
5423
+ value: rgbValue.value.g,
5424
+ onInput: _cache[1] || (_cache[1] = (e) => handleRgbInput("g", e))
5425
+ }, null, 42, _hoisted_6$4)], 2),
5426
+ createElementVNode("div", { class: normalizeClass(e("value-item")) }, [createElementVNode("span", { class: normalizeClass(e("value-label")) }, "B", 2), createElementVNode("input", {
5427
+ class: normalizeClass(e("value-input")),
5428
+ type: "number",
5429
+ min: 0,
5430
+ max: 255,
5431
+ value: rgbValue.value.b,
5432
+ onInput: _cache[2] || (_cache[2] = (e) => handleRgbInput("b", e))
5433
+ }, null, 42, _hoisted_7$3)], 2),
5434
+ __props.showAlpha ? (openBlock(), createElementBlock("div", {
5435
+ key: 0,
5436
+ class: normalizeClass(e("value-item"))
5437
+ }, [createElementVNode("span", { class: normalizeClass(e("value-label")) }, "A", 2), createElementVNode("input", {
5438
+ class: normalizeClass(e("value-input")),
5439
+ type: "number",
5440
+ min: 0,
5441
+ max: 100,
5442
+ value: Math.round(alphaValue.value * 100),
5443
+ onInput: handleAlphaInput
5444
+ }, null, 42, _hoisted_8$3)], 2)) : createCommentVNode("v-if", true)
5445
+ ], 2),
5446
+ createCommentVNode(" Preset colors "),
5447
+ __props.showPreset ? (openBlock(), createElementBlock("div", {
5448
+ key: 1,
5449
+ class: normalizeClass(e("presets"))
5450
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.presetColors, (color, index) => {
5451
+ return openBlock(), createElementBlock("div", {
5452
+ key: index,
5453
+ class: normalizeClass(e("preset-item")),
5454
+ style: normalizeStyle({ backgroundColor: color }),
5455
+ onClick: ($event) => handlePresetClick(color)
5456
+ }, null, 14, _hoisted_9$3);
5457
+ }), 128))], 2)) : createCommentVNode("v-if", true)
5458
+ ], 6)) : createCommentVNode("v-if", true)]),
5459
+ _: 1
5460
+ })]))
5461
+ ], 2);
5462
+ };
5463
+ }
5464
+ }), [["__scopeId", "data-v-24772c45"]]);
5465
+ //#endregion
5466
+ //#region src/composables/use-form-validate.ts
5467
+ /**
5468
+ * 获取 AsyncValidator 构造函数
5469
+ * 处理 ES Module default export 和 CommonJS 两种导出方式
5470
+ */
5471
+ function getAsyncValidatorSchema() {
5472
+ if (typeof AsyncValidator === "object" && AsyncValidator !== null && "default" in AsyncValidator) return AsyncValidator.default;
5473
+ return AsyncValidator;
5474
+ }
5475
+ const Schema = getAsyncValidatorSchema();
5476
+ /**
5477
+ * 表单校验 composable
5478
+ */
5479
+ function useFormValidate(rules, model) {
5480
+ const errors = reactive({});
5481
+ const items = ref([]);
5482
+ /**
5483
+ * 校验单个字段
5484
+ */
5485
+ async function validateField(prop) {
5486
+ const rulesForField = (isRef(rules) ? rules.value : rules)[prop];
5487
+ if (!rulesForField) return null;
5488
+ const value = (isRef(model) ? model.value : model)[prop];
5489
+ const validator = new Schema({ [prop]: rulesForField });
5490
+ try {
5491
+ await validator.validate({ [prop]: value });
5492
+ errors[prop] = [];
5493
+ return null;
5494
+ } catch (err) {
5495
+ const fieldErrors = err.errors.map((e) => ({
5496
+ message: e.message,
5497
+ field: prop
5498
+ }));
5499
+ errors[prop] = fieldErrors;
5500
+ return fieldErrors[0];
5501
+ }
5502
+ }
5503
+ /**
5504
+ * 校验整个表单
5505
+ */
5506
+ async function validate() {
5507
+ const allErrors = [];
5508
+ const validationPromises = items.value.map((item) => item.validate(item.modelValue));
5509
+ const results = await Promise.all(validationPromises);
5510
+ for (const result of results) if (result) allErrors.push(result);
5511
+ return {
5512
+ valid: allErrors.length === 0,
5513
+ errors: allErrors
5514
+ };
5515
+ }
5516
+ /**
5517
+ * 重置所有字段
5518
+ */
5519
+ function resetFields() {
5520
+ items.value.forEach((item) => item.resetField());
5521
+ }
5522
+ /**
5523
+ * 清除校验错误
5524
+ */
5525
+ function clearValidate(fields) {
5526
+ if (fields) for (const field of fields) {
5527
+ errors[field] = [];
5528
+ items.value.find((i) => i.prop === field)?.clearValidate();
5529
+ }
5530
+ else {
5531
+ for (const key in errors) errors[key] = [];
5532
+ items.value.forEach((item) => item.clearValidate());
5533
+ }
5534
+ }
5535
+ /**
5536
+ * 注册表单项
5537
+ */
5538
+ function registerItem(item) {
5539
+ if (!items.value.includes(item)) items.value.push(item);
5540
+ }
5541
+ /**
5542
+ * 注销表单项
5543
+ */
5544
+ function unregisterItem(item) {
5545
+ const index = items.value.indexOf(item);
5546
+ if (index > -1) items.value.splice(index, 1);
5547
+ }
5548
+ return {
5549
+ errors,
5550
+ items,
5551
+ validate,
5552
+ validateField,
5553
+ resetFields,
5554
+ clearValidate,
5555
+ registerItem,
5556
+ unregisterItem
5557
+ };
5558
+ }
5559
+ var form_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
5560
+ name: "YdForm",
4156
5561
  __name: "form",
4157
5562
  props: {
4158
5563
  modelValue: { default: () => ({}) },
@@ -4213,68 +5618,412 @@ var form_item_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ de
4213
5618
  required: {
4214
5619
  type: Boolean,
4215
5620
  default: false
4216
- },
4217
- extra: { default: "" }
5621
+ },
5622
+ extra: { default: "" }
5623
+ },
5624
+ setup(__props) {
5625
+ const props = __props;
5626
+ const formContext = inject("ydForm", null);
5627
+ const errorMessage = ref("");
5628
+ const modelValue = ref("");
5629
+ const formItemClasses = computed(() => cn("yd-form-item", errorMessage.value && "yd-form-item--error"));
5630
+ const labelStyle = computed(() => {
5631
+ if (!formContext) return {};
5632
+ return { width: formContext.labelWidth?.value };
5633
+ });
5634
+ function e(element) {
5635
+ return `yd-form-item__${element}`;
5636
+ }
5637
+ const instance = {
5638
+ prop: props.prop,
5639
+ modelValue,
5640
+ validate: async (value) => {
5641
+ modelValue.value = value;
5642
+ if (!formContext || !props.prop) return null;
5643
+ const result = await formContext.validateField?.(props.prop);
5644
+ errorMessage.value = result?.message || "";
5645
+ return result;
5646
+ },
5647
+ resetField: () => {
5648
+ modelValue.value = "";
5649
+ errorMessage.value = "";
5650
+ },
5651
+ clearValidate: () => {
5652
+ errorMessage.value = "";
5653
+ }
5654
+ };
5655
+ onMounted(() => {
5656
+ formContext?.registerItem?.(instance);
5657
+ });
5658
+ onUnmounted(() => {
5659
+ formContext?.unregisterItem?.(instance);
5660
+ });
5661
+ return (_ctx, _cache) => {
5662
+ return openBlock(), createElementBlock("div", { class: normalizeClass(formItemClasses.value) }, [
5663
+ __props.label ? (openBlock(), createElementBlock("label", {
5664
+ key: 0,
5665
+ class: normalizeClass(e("label")),
5666
+ style: normalizeStyle(labelStyle.value)
5667
+ }, [createTextVNode(toDisplayString(__props.label) + " ", 1), __props.required ? (openBlock(), createElementBlock("span", {
5668
+ key: 0,
5669
+ class: normalizeClass(e("required"))
5670
+ }, "*", 2)) : createCommentVNode("v-if", true)], 6)) : createCommentVNode("v-if", true),
5671
+ createElementVNode("div", { class: normalizeClass(e("content")) }, [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 2),
5672
+ errorMessage.value ? (openBlock(), createElementBlock("div", {
5673
+ key: 1,
5674
+ class: normalizeClass(e("error"))
5675
+ }, toDisplayString(errorMessage.value), 3)) : __props.extra ? (openBlock(), createElementBlock("div", {
5676
+ key: 2,
5677
+ class: normalizeClass(e("extra"))
5678
+ }, toDisplayString(__props.extra), 3)) : createCommentVNode("v-if", true)
5679
+ ], 2);
5680
+ };
5681
+ }
5682
+ }), [["__scopeId", "data-v-cab13fdb"]]);
5683
+ //#endregion
5684
+ //#region src/components/form/useFormSchema.ts
5685
+ /**
5686
+ * 解析schema中的条件表达式
5687
+ */
5688
+ /**
5689
+ * 安全地解析条件表达式
5690
+ * 支持简单的比较和逻辑运算: a > 0, b === 'yes', a && b, a || !c
5691
+ * 使用 Function 构造函数是合理的,因为我们已经清理了表达式
5692
+ */
5693
+ function parseCondition(condition, values) {
5694
+ const ALLOWED_KEYWORDS = new Set([
5695
+ "true",
5696
+ "false",
5697
+ "null",
5698
+ "undefined"
5699
+ ]);
5700
+ try {
5701
+ const trimmed = condition.trim();
5702
+ if (trimmed === "true") return true;
5703
+ if (trimmed === "false") return false;
5704
+ function getValue(name) {
5705
+ if (ALLOWED_KEYWORDS.has(name)) return void 0;
5706
+ return values[name];
5707
+ }
5708
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed)) return !!getValue(trimmed);
5709
+ if (/^![a-zA-Z_][a-zA-Z0-9_]*$/.test(trimmed)) return !getValue(trimmed.slice(1));
5710
+ return new Function("values", "getValue", "undefined", `return !!( (${trimmed}) )`)(values, getValue, void 0);
5711
+ } catch {
5712
+ return true;
5713
+ }
5714
+ }
5715
+ function evalCondition(condition, values) {
5716
+ if (typeof condition === "function") return condition(values);
5717
+ return parseCondition(condition, values);
5718
+ }
5719
+ /**
5720
+ * 判断是否是GroupSchema
5721
+ */
5722
+ function isGroupSchema(item) {
5723
+ return "type" in item && item.type === "group";
5724
+ }
5725
+ /**
5726
+ * 判断是否是RowSchema
5727
+ */
5728
+ function isRowSchema(item) {
5729
+ return "type" in item && item.type === "row";
5730
+ }
5731
+ /**
5732
+ * 判断是否是SlotSchema
5733
+ */
5734
+ function isSlotSchema(item) {
5735
+ return "type" in item && item.type === "slot";
5736
+ }
5737
+ /**
5738
+ * 过滤字段 - 处理if和dependencies条件
5739
+ */
5740
+ function filterFields(schema, values) {
5741
+ const result = [];
5742
+ for (const item of schema) {
5743
+ if (isGroupSchema(item)) {
5744
+ const filteredChildren = filterFields(item.children, values);
5745
+ result.push({
5746
+ ...item,
5747
+ children: filteredChildren
5748
+ });
5749
+ continue;
5750
+ }
5751
+ if (isRowSchema(item)) {
5752
+ const filteredChildren = filterFields(item.children, values);
5753
+ result.push({
5754
+ ...item,
5755
+ children: filteredChildren
5756
+ });
5757
+ continue;
5758
+ }
5759
+ if (isSlotSchema(item)) {
5760
+ result.push(item);
5761
+ continue;
5762
+ }
5763
+ const field = item;
5764
+ if (field.if !== void 0) {
5765
+ if (field.dependencies?.length) {
5766
+ if (!field.dependencies.every((dep) => dep in values)) {
5767
+ result.push(field);
5768
+ continue;
5769
+ }
5770
+ }
5771
+ if (!evalCondition(field.if, values)) continue;
5772
+ }
5773
+ result.push(field);
5774
+ }
5775
+ return result;
5776
+ }
5777
+ /**
5778
+ * 构建默认初始值
5779
+ */
5780
+ function buildInitialValues(schema, initialValues) {
5781
+ const values = { ...initialValues };
5782
+ function traverse(items) {
5783
+ for (const item of items) {
5784
+ if (isGroupSchema(item) || isRowSchema(item)) {
5785
+ traverse(item.children);
5786
+ continue;
5787
+ }
5788
+ if (isSlotSchema(item)) continue;
5789
+ const field = item;
5790
+ if (field.name && field.defaultValue !== void 0 && !(field.name in values)) values[field.name] = field.defaultValue;
5791
+ }
5792
+ }
5793
+ traverse(schema);
5794
+ return values;
5795
+ }
5796
+ /**
5797
+ * useFormSchema - Schema驱动的表单生成
5798
+ */
5799
+ function useFormSchema(schema, initialValues) {
5800
+ const modelValue = buildInitialValues(schema, initialValues);
5801
+ let filteredSchema = filterFields(schema, modelValue);
5802
+ const actions = {
5803
+ getValues: () => ({ ...modelValue }),
5804
+ setFieldValue: (name, value) => {
5805
+ modelValue[name] = value;
5806
+ },
5807
+ resetFields: () => {
5808
+ const newValues = buildInitialValues(schema, initialValues);
5809
+ Object.keys(modelValue).forEach((key) => {
5810
+ if (key in newValues) modelValue[key] = newValues[key];
5811
+ else delete modelValue[key];
5812
+ });
5813
+ },
5814
+ validate: async () => {
5815
+ return {
5816
+ valid: true,
5817
+ errors: []
5818
+ };
5819
+ },
5820
+ scrollToField: (name) => {
5821
+ document.querySelector(`[data-field="${name}"]`)?.scrollIntoView({
5822
+ behavior: "smooth",
5823
+ block: "center"
5824
+ });
5825
+ },
5826
+ submit: async () => {
5827
+ await actions.validate();
5828
+ return actions.getValues();
5829
+ }
5830
+ };
5831
+ return {
5832
+ modelValue,
5833
+ schema: filteredSchema,
5834
+ actions
5835
+ };
5836
+ }
5837
+ var SchemaForm_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
5838
+ name: "YdSchemaForm",
5839
+ __name: "SchemaForm",
5840
+ props: {
5841
+ schema: {},
5842
+ modelValue: { default: () => ({}) },
5843
+ labelWidth: { default: "100px" },
5844
+ layout: { default: "vertical" },
5845
+ labelPosition: { default: "top" },
5846
+ disabled: {
5847
+ type: Boolean,
5848
+ default: false
5849
+ }
4218
5850
  },
4219
- setup(__props) {
5851
+ emits: [
5852
+ "update:modelValue",
5853
+ "change",
5854
+ "submit",
5855
+ "reset"
5856
+ ],
5857
+ setup(__props, { expose: __expose, emit: __emit }) {
4220
5858
  const props = __props;
4221
- const formContext = inject("ydForm", null);
4222
- const errorMessage = ref("");
4223
- const modelValue = ref("");
4224
- const formItemClasses = computed(() => cn("yd-form-item", errorMessage.value && "yd-form-item--error"));
4225
- const labelStyle = computed(() => {
4226
- if (!formContext) return {};
4227
- return { width: formContext.labelWidth?.value };
5859
+ const emit = __emit;
5860
+ const formRef = ref();
5861
+ const localModel = computed({
5862
+ get: () => ({ ...props.modelValue }),
5863
+ set: (val) => emit("update:modelValue", val)
5864
+ });
5865
+ const { modelValue, schema: computedSchema, actions } = useFormSchema(props.schema, props.modelValue);
5866
+ watch(() => props.schema, (newSchema) => {
5867
+ computedSchema.splice(0, computedSchema.length, ...newSchema);
4228
5868
  });
5869
+ const visibleFields = computed(() => computedSchema);
5870
+ const rules = computed(() => {
5871
+ const r = {};
5872
+ for (const field of computedSchema) if (isFieldSchema(field) && field.rules?.length) r[field.name] = field.rules;
5873
+ return r;
5874
+ });
5875
+ const componentMap = {
5876
+ Input: input_default,
5877
+ Textarea: textarea_default,
5878
+ Select: select_default,
5879
+ RadioGroup: radio_group_default,
5880
+ CheckboxGroup: checkbox_group_default,
5881
+ Switch: switch_default,
5882
+ DatePicker: date_picker_default
5883
+ };
5884
+ function isGroupSchema(item) {
5885
+ return "type" in item && item.type === "group";
5886
+ }
5887
+ function isRowSchema(item) {
5888
+ return "type" in item && item.type === "row";
5889
+ }
5890
+ function isSlotSchema(item) {
5891
+ return "type" in item && item.type === "slot";
5892
+ }
5893
+ function isFieldSchema(item) {
5894
+ return !("type" in item);
5895
+ }
5896
+ function getComponent(field) {
5897
+ return componentMap[field.component || "Input"];
5898
+ }
5899
+ function hasRequiredRule(field) {
5900
+ return field.rules?.some((r) => r.required);
5901
+ }
5902
+ function handleChange(name, value) {
5903
+ localModel.value = {
5904
+ ...localModel.value,
5905
+ [name]: value
5906
+ };
5907
+ emit("change", name, value);
5908
+ }
5909
+ function handleSubmit() {
5910
+ actions.submit().then((values) => {
5911
+ emit("submit", values);
5912
+ });
5913
+ }
4229
5914
  function e(element) {
4230
- return `yd-form-item__${element}`;
5915
+ return `yd-schema-form__${element}`;
4231
5916
  }
4232
- const instance = {
4233
- prop: props.prop,
4234
- modelValue,
4235
- validate: async (value) => {
4236
- modelValue.value = value;
4237
- if (!formContext || !props.prop) return null;
4238
- const result = await formContext.validateField?.(props.prop);
4239
- errorMessage.value = result?.message || "";
4240
- return result;
4241
- },
4242
- resetField: () => {
4243
- modelValue.value = "";
4244
- errorMessage.value = "";
4245
- },
4246
- clearValidate: () => {
4247
- errorMessage.value = "";
4248
- }
4249
- };
4250
- onMounted(() => {
4251
- formContext?.registerItem?.(instance);
4252
- });
4253
- onUnmounted(() => {
4254
- formContext?.unregisterItem?.(instance);
5917
+ __expose({
5918
+ validate: actions.validate,
5919
+ resetFields: actions.resetFields,
5920
+ scrollToField: actions.scrollToField
4255
5921
  });
4256
5922
  return (_ctx, _cache) => {
4257
- return openBlock(), createElementBlock("div", { class: normalizeClass(formItemClasses.value) }, [
4258
- __props.label ? (openBlock(), createElementBlock("label", {
4259
- key: 0,
4260
- class: normalizeClass(e("label")),
4261
- style: normalizeStyle(labelStyle.value)
4262
- }, [createTextVNode(toDisplayString(__props.label) + " ", 1), __props.required ? (openBlock(), createElementBlock("span", {
4263
- key: 0,
4264
- class: normalizeClass(e("required"))
4265
- }, "*", 2)) : createCommentVNode("v-if", true)], 6)) : createCommentVNode("v-if", true),
4266
- createElementVNode("div", { class: normalizeClass(e("content")) }, [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 2),
4267
- errorMessage.value ? (openBlock(), createElementBlock("div", {
4268
- key: 1,
4269
- class: normalizeClass(e("error"))
4270
- }, toDisplayString(errorMessage.value), 3)) : __props.extra ? (openBlock(), createElementBlock("div", {
4271
- key: 2,
4272
- class: normalizeClass(e("extra"))
4273
- }, toDisplayString(__props.extra), 3)) : createCommentVNode("v-if", true)
4274
- ], 2);
5923
+ return openBlock(), createBlock(form_default, {
5924
+ ref_key: "formRef",
5925
+ ref: formRef,
5926
+ modelValue: localModel.value,
5927
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => localModel.value = $event),
5928
+ rules: rules.value,
5929
+ layout: __props.layout,
5930
+ "label-width": __props.labelWidth,
5931
+ "label-position": __props.labelPosition,
5932
+ disabled: __props.disabled,
5933
+ onSubmit: handleSubmit
5934
+ }, {
5935
+ default: withCtx(() => [
5936
+ (openBlock(true), createElementBlock(Fragment, null, renderList(visibleFields.value, (field) => {
5937
+ return openBlock(), createElementBlock(Fragment, { key: field.name }, [createCommentVNode(" Group "), isGroupSchema(field) ? (openBlock(), createElementBlock("fieldset", {
5938
+ key: 0,
5939
+ class: normalizeClass(e("group"))
5940
+ }, [
5941
+ field.title ? (openBlock(), createElementBlock("legend", {
5942
+ key: 0,
5943
+ class: normalizeClass(e("group-title"))
5944
+ }, toDisplayString(field.title), 3)) : createCommentVNode("v-if", true),
5945
+ field.description ? (openBlock(), createElementBlock("p", {
5946
+ key: 1,
5947
+ class: normalizeClass(e("group-desc"))
5948
+ }, toDisplayString(field.description), 3)) : createCommentVNode("v-if", true),
5949
+ renderSlot(_ctx.$slots, `group-${field.title}`, {}, void 0, true)
5950
+ ], 2)) : isRowSchema(field) ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Row "), createElementVNode("div", {
5951
+ class: normalizeClass(e("row")),
5952
+ style: normalizeStyle({ gap: `${field.gutter || 16}px` })
5953
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(field.children, (child) => {
5954
+ return openBlock(), createElementBlock(Fragment, { key: child.name }, [isFieldSchema(child) ? (openBlock(), createBlock(form_item_default, {
5955
+ key: 0,
5956
+ prop: child.name,
5957
+ label: child.label,
5958
+ required: hasRequiredRule(child),
5959
+ "data-field": child.name
5960
+ }, {
5961
+ default: withCtx(() => [renderSlot(_ctx.$slots, child.name, {}, () => [(openBlock(), createBlock(resolveDynamicComponent(getComponent(child)), mergeProps({
5962
+ modelValue: localModel.value[child.name],
5963
+ "onUpdate:modelValue": ($event) => localModel.value[child.name] = $event
5964
+ }, { ref_for: true }, child.componentProps, {
5965
+ placeholder: child.placeholder,
5966
+ disabled: child.disabled,
5967
+ options: child.options,
5968
+ "onUpdate:modelValue": (v) => handleChange(child.name, v)
5969
+ }), null, 16, [
5970
+ "modelValue",
5971
+ "onUpdate:modelValue",
5972
+ "placeholder",
5973
+ "disabled",
5974
+ "options"
5975
+ ]))], true)]),
5976
+ _: 2
5977
+ }, 1032, [
5978
+ "prop",
5979
+ "label",
5980
+ "required",
5981
+ "data-field"
5982
+ ])) : createCommentVNode("v-if", true)], 64);
5983
+ }), 128))], 6)], 64)) : isSlotSchema(field) ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [createCommentVNode(" Slot "), renderSlot(_ctx.$slots, field.name, {}, void 0, true)], 64)) : isFieldSchema(field) ? (openBlock(), createElementBlock(Fragment, { key: 3 }, [createCommentVNode(" Field "), createVNode(form_item_default, {
5984
+ prop: field.name,
5985
+ label: field.label,
5986
+ required: hasRequiredRule(field),
5987
+ "data-field": field.name
5988
+ }, {
5989
+ default: withCtx(() => [renderSlot(_ctx.$slots, field.name, {}, () => [(openBlock(), createBlock(resolveDynamicComponent(getComponent(field)), mergeProps({
5990
+ modelValue: localModel.value[field.name],
5991
+ "onUpdate:modelValue": ($event) => localModel.value[field.name] = $event
5992
+ }, { ref_for: true }, field.componentProps, {
5993
+ placeholder: field.placeholder,
5994
+ disabled: field.disabled,
5995
+ options: field.options,
5996
+ "onUpdate:modelValue": (v) => handleChange(field.name, v)
5997
+ }), null, 16, [
5998
+ "modelValue",
5999
+ "onUpdate:modelValue",
6000
+ "placeholder",
6001
+ "disabled",
6002
+ "options"
6003
+ ]))], true)]),
6004
+ _: 2
6005
+ }, 1032, [
6006
+ "prop",
6007
+ "label",
6008
+ "required",
6009
+ "data-field"
6010
+ ])], 64)) : createCommentVNode("v-if", true)], 64);
6011
+ }), 128)),
6012
+ createCommentVNode(" Default slot for custom content "),
6013
+ renderSlot(_ctx.$slots, "default", {}, void 0, true)
6014
+ ]),
6015
+ _: 3
6016
+ }, 8, [
6017
+ "modelValue",
6018
+ "rules",
6019
+ "layout",
6020
+ "label-width",
6021
+ "label-position",
6022
+ "disabled"
6023
+ ]);
4275
6024
  };
4276
6025
  }
4277
- }), [["__scopeId", "data-v-cab13fdb"]]);
6026
+ }), [["__scopeId", "data-v-ec0612ee"]]);
4278
6027
  var space_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
4279
6028
  name: "YdSpace",
4280
6029
  __name: "space",
@@ -4330,14 +6079,13 @@ var divider_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defi
4330
6079
  const props = __props;
4331
6080
  const dividerClasses = computed(() => cn("yd-divider", `yd-divider--${props.direction}`, `yd-divider--${props.type}`, `yd-divider--${props.orientation}`, `yd-divider--${props.variant}`, props.dashed && "yd-divider--dashed"));
4332
6081
  const dividerStyle = computed(() => {
4333
- const colors = {
6082
+ return { "--divider-color": {
4334
6083
  default: "var(--yd-color-border)",
4335
6084
  primary: "var(--yd-color-primary-500)",
4336
6085
  success: "var(--yd-color-success)",
4337
6086
  warning: "var(--yd-color-warning)",
4338
6087
  error: "var(--yd-color-error)"
4339
- };
4340
- return { "--divider-color": colors[props.variant] };
6088
+ }[props.variant] };
4341
6089
  });
4342
6090
  function e(element) {
4343
6091
  return `yd-divider__${element}`;
@@ -4409,6 +6157,26 @@ var menu_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineC
4409
6157
  },
4410
6158
  emits: ["update:modelValue", "select"],
4411
6159
  setup(__props, { emit: __emit }) {
6160
+ const instance = getCurrentInstance();
6161
+ /**
6162
+ * 渲染图标 - 支持字符串图标和组件图标
6163
+ */
6164
+ function renderIcon(icon) {
6165
+ if (!icon) return null;
6166
+ if (typeof icon === "object" && "component" in icon) {
6167
+ const componentName = icon.component;
6168
+ const iconProps = icon.props || {};
6169
+ const globalComp = instance?.appContext.config.globalProperties.$[componentName];
6170
+ if (globalComp) return () => h(globalComp, iconProps);
6171
+ const app = instance?.appContext.app;
6172
+ if (app) {
6173
+ const comp = app.config.globalProperties[componentName];
6174
+ if (comp) return () => h(comp, iconProps);
6175
+ }
6176
+ return () => componentName;
6177
+ }
6178
+ return () => icon;
6179
+ }
4412
6180
  const props = __props;
4413
6181
  const emit = __emit;
4414
6182
  const activeSubmenu = ref(null);
@@ -4592,10 +6360,10 @@ var menu_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineC
4592
6360
  onClick: ($event) => toggleSubmenu(item.key),
4593
6361
  onKeydown: [withKeys(($event) => toggleSubmenu(item.key), ["enter"]), withKeys(($event) => handleSubmenuLeave(item.key), ["esc"])]
4594
6362
  }, [
4595
- item.icon ? (openBlock(), createElementBlock("span", {
6363
+ item.icon ? (openBlock(), createBlock(resolveDynamicComponent(renderIcon(item.icon)), {
4596
6364
  key: 0,
4597
6365
  class: normalizeClass(e("icon"))
4598
- }, toDisplayString(item.icon), 3)) : createCommentVNode("v-if", true),
6366
+ }, null, 8, ["class"])) : createCommentVNode("v-if", true),
4599
6367
  createElementVNode("span", { class: normalizeClass(e("label")) }, toDisplayString(item.label), 3),
4600
6368
  createElementVNode("span", {
4601
6369
  class: normalizeClass(e("arrow")),
@@ -4798,7 +6566,142 @@ var menu_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineC
4798
6566
  }), 128))], 10, _hoisted_1$20);
4799
6567
  };
4800
6568
  }
4801
- }), [["__scopeId", "data-v-78398467"]]);
6569
+ }), [["__scopeId", "data-v-9dfb9940"]]);
6570
+ //#endregion
6571
+ //#region src/composables/use-menu.ts
6572
+ /**
6573
+ * 检查用户是否有权限访问菜单项
6574
+ */
6575
+ function hasPermission(menuPermission, userPermissions) {
6576
+ if (!menuPermission) return true;
6577
+ const perms = Array.isArray(menuPermission) ? menuPermission : [menuPermission];
6578
+ const userPerms = userPermissions.permissions || [];
6579
+ return perms.some((p) => userPerms.includes(p));
6580
+ }
6581
+ /**
6582
+ * 检查用户是否有角色访问菜单项
6583
+ */
6584
+ function hasRole(menuRoles, userPermissions) {
6585
+ if (!menuRoles) return true;
6586
+ const roles = Array.isArray(menuRoles) ? menuRoles : [menuRoles];
6587
+ const userRoles = userPermissions.roles || [];
6588
+ return roles.some((r) => userRoles.includes(r));
6589
+ }
6590
+ /**
6591
+ * 过滤菜单项(根据权限和隐藏状态)
6592
+ */
6593
+ function filterMenuItems(items, userPermissions) {
6594
+ if (!items) return [];
6595
+ const result = [];
6596
+ for (const item of items) {
6597
+ if (item.hidden) continue;
6598
+ if (userPermissions) {
6599
+ if (!hasPermission(item.permission, userPermissions)) continue;
6600
+ if (!hasRole(item.roles, userPermissions)) continue;
6601
+ }
6602
+ const filteredChildren = item.children ? filterMenuItems(item.children, userPermissions) : void 0;
6603
+ if (!item.children || filteredChildren && filteredChildren.length > 0) result.push({
6604
+ ...item,
6605
+ children: filteredChildren
6606
+ });
6607
+ }
6608
+ return result;
6609
+ }
6610
+ /**
6611
+ * 根据菜单生成路由配置
6612
+ */
6613
+ function menuToRoutes(items, basePath = "") {
6614
+ const routes = [];
6615
+ for (const item of items) {
6616
+ if (item.hidden) continue;
6617
+ const routePath = item.path || item.key;
6618
+ const fullPath = basePath ? `${basePath}/${routePath}` : routePath;
6619
+ routes.push({
6620
+ path: fullPath,
6621
+ name: item.key,
6622
+ meta: {
6623
+ title: item.label,
6624
+ icon: item.icon,
6625
+ permission: item.permission,
6626
+ roles: item.roles,
6627
+ ...typeof item.route === "object" ? item.route : {}
6628
+ }
6629
+ });
6630
+ if (item.children && item.children.length > 0) routes.push(...menuToRoutes(item.children, fullPath));
6631
+ }
6632
+ return routes;
6633
+ }
6634
+ /**
6635
+ * 从当前激活菜单 key 获取面包屑路径
6636
+ */
6637
+ function getBreadcrumbPaths(items, activeKey, currentPath = []) {
6638
+ for (const item of items) {
6639
+ if (item.key === activeKey) return [...currentPath, item];
6640
+ if (item.children && item.children.length > 0) {
6641
+ const found = getBreadcrumbPaths(item.children, activeKey, [...currentPath, item]);
6642
+ if (found.length > 0) return found;
6643
+ }
6644
+ }
6645
+ return [];
6646
+ }
6647
+ /**
6648
+ * 从菜单 key 查找菜单项
6649
+ */
6650
+ function findMenuItem(items, key) {
6651
+ for (const item of items) {
6652
+ if (item.key === key) return item;
6653
+ if (item.children && item.children.length > 0) {
6654
+ const found = findMenuItem(item.children, key);
6655
+ if (found) return found;
6656
+ }
6657
+ }
6658
+ }
6659
+ /**
6660
+ * 查找菜单项的完整路径
6661
+ */
6662
+ function findMenuPath(items, key, parents = []) {
6663
+ for (const item of items) {
6664
+ if (item.key === key) return [...parents, item];
6665
+ if (item.children && item.children.length > 0) {
6666
+ const found = findMenuPath(item.children, key, [...parents, item]);
6667
+ if (found.length > 0) return found;
6668
+ }
6669
+ }
6670
+ return [];
6671
+ }
6672
+ /**
6673
+ * 搜索菜单项(模糊搜索,支持权限过滤)
6674
+ */
6675
+ function searchMenuItems(items, query, userPermissions) {
6676
+ if (!query || !query.trim()) return filterMenuItems(items, userPermissions);
6677
+ const searchTerm = query.trim().toLowerCase();
6678
+ const result = [];
6679
+ for (const item of items) {
6680
+ if (item.hidden) continue;
6681
+ if (userPermissions) {
6682
+ if (!hasPermission(item.permission, userPermissions)) continue;
6683
+ if (!hasRole(item.roles, userPermissions)) continue;
6684
+ }
6685
+ const labelMatch = item.label.toLowerCase().includes(searchTerm);
6686
+ const matchedChildren = item.children ? searchMenuItems(item.children, query, userPermissions) : [];
6687
+ if (labelMatch || matchedChildren.length > 0) result.push({
6688
+ ...item,
6689
+ children: matchedChildren.length > 0 ? matchedChildren : item.children
6690
+ });
6691
+ }
6692
+ return result;
6693
+ }
6694
+ /**
6695
+ * 获取菜单项的扁平化列表(用于搜索)
6696
+ */
6697
+ function flattenMenuItems(items) {
6698
+ const result = [];
6699
+ for (const item of items) {
6700
+ result.push(item);
6701
+ if (item.children && item.children.length > 0) result.push(...flattenMenuItems(item.children));
6702
+ }
6703
+ return result;
6704
+ }
4802
6705
  //#endregion
4803
6706
  //#region src/components/layout/layout/layout-sidebar.vue
4804
6707
  const _hoisted_1$19 = ["src", "alt"];
@@ -4829,12 +6732,18 @@ var layout_sidebar_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
4829
6732
  default: false
4830
6733
  },
4831
6734
  popupAlign: { default: "trigger" },
4832
- footerText: { default: "" }
6735
+ footerText: { default: "" },
6736
+ searchable: {
6737
+ type: Boolean,
6738
+ default: false
6739
+ },
6740
+ roles: { default: [] }
4833
6741
  },
4834
6742
  emits: [
4835
6743
  "collapse",
4836
6744
  "menu-click",
4837
- "width-change"
6745
+ "width-change",
6746
+ "path-change"
4838
6747
  ],
4839
6748
  setup(__props, { emit: __emit }) {
4840
6749
  const props = __props;
@@ -4869,6 +6778,38 @@ var layout_sidebar_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
4869
6778
  watch(() => props.expandedWidth, (val) => {
4870
6779
  if (val && val !== localWidth.value) localWidth.value = val;
4871
6780
  });
6781
+ const searchQuery = ref("");
6782
+ ref(null);
6783
+ function handleSearch() {}
6784
+ function clearSearch() {
6785
+ searchQuery.value = "";
6786
+ }
6787
+ function filterItemsByRole(items, roles) {
6788
+ if (!items || roles.length === 0) return items;
6789
+ const result = [];
6790
+ for (const item of items) {
6791
+ if (item.hidden) continue;
6792
+ if (item.roles && item.roles.length > 0) {
6793
+ if (!item.roles.some((r) => roles.includes(r))) continue;
6794
+ }
6795
+ const filteredChildren = item.children ? filterItemsByRole(item.children, roles) : void 0;
6796
+ if (!item.children || filteredChildren && filteredChildren.length > 0) result.push({
6797
+ ...item,
6798
+ children: filteredChildren
6799
+ });
6800
+ }
6801
+ return result;
6802
+ }
6803
+ const displayMenuItems = computed(() => {
6804
+ let items = props.menuItems || [];
6805
+ const userRoles = props.roles;
6806
+ if (userRoles && (Array.isArray(userRoles) ? userRoles.length > 0 : userRoles)) items = filterItemsByRole(items, Array.isArray(userRoles) ? userRoles : [userRoles]);
6807
+ if (!searchQuery.value || !searchQuery.value.trim()) return items;
6808
+ return searchMenuItems(items, searchQuery.value.trim());
6809
+ });
6810
+ watch(() => props.collapsed, () => {
6811
+ if (props.collapsed) searchQuery.value = "";
6812
+ });
4872
6813
  const isMobileExpanded = computed(() => props.isMobile && !props.collapsed);
4873
6814
  const sidebarClasses = computed(() => cn("yd-layout-sidebar", `yd-layout-sidebar--${props.theme}`, props.collapsed && "yd-layout-sidebar--collapsed", isMobileExpanded.value && "yd-layout-sidebar--fixed"));
4874
6815
  function el(name) {
@@ -4876,8 +6817,7 @@ var layout_sidebar_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
4876
6817
  }
4877
6818
  const sidebarStyle = computed(() => {
4878
6819
  const isMobileMode = props.isMobile && !props.collapsed;
4879
- const currentWidth = props.resizable && !props.collapsed && !isMobileMode ? localWidth.value : props.expandedWidth;
4880
- const width = props.collapsed ? `${props.collapsedWidth}px` : isMobileMode ? "100%" : `${currentWidth}px`;
6820
+ const width = props.collapsed ? `${props.collapsedWidth}px` : isMobileMode ? "100%" : `${props.resizable && !props.collapsed && !isMobileMode ? localWidth.value : props.expandedWidth}px`;
4881
6821
  const style = {
4882
6822
  width,
4883
6823
  flex: isMobileMode ? "none" : `0 0 ${width}`
@@ -4891,9 +6831,13 @@ var layout_sidebar_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
4891
6831
  }
4892
6832
  return style;
4893
6833
  });
4894
- function handleMenuClick(item) {
4895
- if (item.disabled) return;
4896
- emit("menu-click", item.key);
6834
+ function handleMenuClick(keyOrItem) {
6835
+ const key = typeof keyOrItem === "string" ? keyOrItem : keyOrItem.key;
6836
+ const item = typeof keyOrItem === "string" ? findMenuItem(props.menuItems || [], keyOrItem) : keyOrItem;
6837
+ if (!item || item.disabled) return;
6838
+ const pathLabels = findMenuPath(props.menuItems || [], key).map((p) => p.label);
6839
+ emit("menu-click", key, item);
6840
+ emit("path-change", pathLabels);
4897
6841
  }
4898
6842
  return (_ctx, _cache) => {
4899
6843
  return openBlock(), createElementBlock("aside", {
@@ -4912,7 +6856,7 @@ var layout_sidebar_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
4912
6856
  }, null, 10, _hoisted_1$19)) : (openBlock(), createElementBlock("div", {
4913
6857
  key: 1,
4914
6858
  class: normalizeClass(el("logo-icon").value)
4915
- }, [..._cache[1] || (_cache[1] = [createElementVNode("svg", {
6859
+ }, [..._cache[2] || (_cache[2] = [createElementVNode("svg", {
4916
6860
  xmlns: "http://www.w3.org/2000/svg",
4917
6861
  width: "28",
4918
6862
  height: "28",
@@ -4950,11 +6894,26 @@ var layout_sidebar_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
4950
6894
  }, toDisplayString(__props.title), 3)) : createCommentVNode("v-if", true)]),
4951
6895
  _: 1
4952
6896
  })], 2),
6897
+ createCommentVNode(" 搜索框 "),
6898
+ __props.searchable && !__props.collapsed ? (openBlock(), createElementBlock("div", {
6899
+ key: 0,
6900
+ class: normalizeClass(el("search").value)
6901
+ }, [withDirectives(createElementVNode("input", {
6902
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => searchQuery.value = $event),
6903
+ type: "text",
6904
+ class: normalizeClass(el("search-input").value),
6905
+ placeholder: "搜索菜单...",
6906
+ onInput: handleSearch
6907
+ }, null, 34), [[vModelText, searchQuery.value]]), searchQuery.value ? (openBlock(), createElementBlock("span", {
6908
+ key: 0,
6909
+ class: normalizeClass(el("search-clear").value),
6910
+ onClick: clearSearch
6911
+ }, "×", 2)) : createCommentVNode("v-if", true)], 2)) : createCommentVNode("v-if", true),
4953
6912
  createCommentVNode(" 菜单区域 "),
4954
- createElementVNode("div", { class: normalizeClass(el("menu-wrapper").value) }, [renderSlot(_ctx.$slots, "sider", {}, () => [__props.menuItems.length > 0 ? (openBlock(), createBlock(unref(menu_default), {
6913
+ createElementVNode("div", { class: normalizeClass(el("menu-wrapper").value) }, [renderSlot(_ctx.$slots, "sider", {}, () => [displayMenuItems.value.length > 0 ? (openBlock(), createBlock(unref(menu_default), {
4955
6914
  key: 0,
4956
6915
  "model-value": __props.activeKey,
4957
- items: __props.menuItems,
6916
+ items: displayMenuItems.value,
4958
6917
  mode: "vertical",
4959
6918
  collapsed: __props.collapsed,
4960
6919
  waterfall: __props.waterfall,
@@ -4968,22 +6927,25 @@ var layout_sidebar_default = /* @__PURE__ */ export_helper_default(/* @__PURE__
4968
6927
  "waterfall",
4969
6928
  "popup-align",
4970
6929
  "dropdown-theme"
4971
- ])) : createCommentVNode("v-if", true)], true)], 2),
6930
+ ])) : searchQuery.value && displayMenuItems.value.length === 0 ? (openBlock(), createElementBlock("div", {
6931
+ key: 1,
6932
+ class: normalizeClass(el("search-empty").value)
6933
+ }, " 无匹配结果 ", 2)) : createCommentVNode("v-if", true)], true)], 2),
4972
6934
  createCommentVNode(" 底部支持信息 "),
4973
6935
  __props.footerText && !__props.collapsed ? (openBlock(), createElementBlock("div", {
4974
- key: 0,
6936
+ key: 1,
4975
6937
  class: normalizeClass(el("footer").value)
4976
6938
  }, [createElementVNode("div", { class: normalizeClass(el("footer-content").value) }, toDisplayString(__props.footerText), 3)], 2)) : createCommentVNode("v-if", true),
4977
6939
  createCommentVNode(" 拖拽调整手柄 "),
4978
6940
  __props.resizable && !__props.collapsed && !__props.isMobile ? (openBlock(), createElementBlock("div", {
4979
- key: 1,
6941
+ key: 2,
4980
6942
  class: normalizeClass(el("resize-handle").value),
4981
6943
  onMousedown: handleDragStart
4982
6944
  }, null, 34)) : createCommentVNode("v-if", true)
4983
6945
  ], 6);
4984
6946
  };
4985
6947
  }
4986
- }), [["__scopeId", "data-v-11c3fb43"]]);
6948
+ }), [["__scopeId", "data-v-38d5b5bc"]]);
4987
6949
  //#endregion
4988
6950
  //#region src/components/navigation/tabs/tabs.vue
4989
6951
  const _hoisted_1$18 = [
@@ -5630,7 +7592,6 @@ var dropdown_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ def
5630
7592
  const positionKey = ref(0);
5631
7593
  const menuStyle = computed(() => {
5632
7594
  if (!triggerRef.value) return {};
5633
- positionKey.value;
5634
7595
  const rect = triggerRef.value.getBoundingClientRect();
5635
7596
  const menuRect = menuRef.value?.getBoundingClientRect();
5636
7597
  const menuHeight = menuRect?.height || 0;
@@ -6315,7 +8276,7 @@ var drawer_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defin
6315
8276
  })], 8, ["disabled"]);
6316
8277
  };
6317
8278
  }
6318
- }), [["__scopeId", "data-v-3cbd3e99"]]);
8279
+ }), [["__scopeId", "data-v-94becd9a"]]);
6319
8280
  //#endregion
6320
8281
  //#region src/components/layout/layout/layout-types.ts
6321
8282
  /** 默认尺寸 */
@@ -6906,29 +8867,43 @@ var tooltip_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defi
6906
8867
  //#endregion
6907
8868
  //#region src/components/data-display/table/table.vue
6908
8869
  const _hoisted_1$13 = { key: 0 };
6909
- const _hoisted_2$8 = ["onClick"];
8870
+ const _hoisted_2$8 = [
8871
+ "draggable",
8872
+ "onDragstart",
8873
+ "onDragover",
8874
+ "onDrop"
8875
+ ];
6910
8876
  const _hoisted_3$5 = ["onClick"];
6911
- const _hoisted_4$4 = ["onClick"];
6912
- const _hoisted_5$1 = [
8877
+ const _hoisted_4$4 = ["onMousedown"];
8878
+ const _hoisted_5$1 = ["onClick"];
8879
+ const _hoisted_6$1 = ["onClick"];
8880
+ const _hoisted_7 = [
6913
8881
  "title",
6914
8882
  "onMouseenter",
6915
8883
  "onMouseleave"
6916
8884
  ];
6917
- const _hoisted_6$1 = ["colspan"];
6918
- const _hoisted_7 = ["onClick"];
6919
- const _hoisted_8 = ["onClick"];
6920
- const _hoisted_9 = ["onClick"];
6921
- const _hoisted_10 = [
8885
+ const _hoisted_8 = ["colspan"];
8886
+ const _hoisted_9 = [
8887
+ "draggable",
8888
+ "onDragstart",
8889
+ "onDragover",
8890
+ "onDrop"
8891
+ ];
8892
+ const _hoisted_10 = ["onClick"];
8893
+ const _hoisted_11 = ["onMousedown"];
8894
+ const _hoisted_12 = ["onClick"];
8895
+ const _hoisted_13 = ["onClick"];
8896
+ const _hoisted_14 = [
6922
8897
  "title",
6923
8898
  "onMouseenter",
6924
8899
  "onMouseleave"
6925
8900
  ];
6926
- const _hoisted_11 = ["colspan"];
6927
- const _hoisted_12 = { key: 0 };
6928
- const _hoisted_13 = ["colspan"];
6929
- const _hoisted_14 = ["disabled"];
6930
- const _hoisted_15 = ["onClick"];
6931
- const _hoisted_16 = ["disabled"];
8901
+ const _hoisted_15 = ["colspan"];
8902
+ const _hoisted_16 = { key: 0 };
8903
+ const _hoisted_17 = ["colspan"];
8904
+ const _hoisted_18 = ["disabled"];
8905
+ const _hoisted_19 = ["onClick"];
8906
+ const _hoisted_20 = ["disabled"];
6932
8907
  var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineComponent({
6933
8908
  name: "YdTable",
6934
8909
  __name: "table",
@@ -6986,17 +8961,31 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
6986
8961
  type: Boolean,
6987
8962
  default: false
6988
8963
  },
6989
- exportFilename: { default: "table-data" }
8964
+ exportFilename: { default: "table-data" },
8965
+ remote: {
8966
+ type: Boolean,
8967
+ default: false
8968
+ },
8969
+ total: { default: 0 },
8970
+ loadMore: {
8971
+ type: Boolean,
8972
+ default: false
8973
+ }
6990
8974
  },
6991
8975
  emits: [
6992
8976
  "sort",
8977
+ "sort-change",
6993
8978
  "page-change",
6994
8979
  "row-click",
6995
- "expand"
8980
+ "expand",
8981
+ "scroll-end",
8982
+ "column-resize",
8983
+ "column-reorder"
6996
8984
  ],
6997
8985
  setup(__props, { expose: __expose, emit: __emit }) {
6998
8986
  const props = __props;
6999
8987
  const emit = __emit;
8988
+ const sortStates = ref([]);
7000
8989
  const sortKey = ref("");
7001
8990
  const sortOrder = ref("asc");
7002
8991
  const currentPage = ref(1);
@@ -7007,6 +8996,8 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7007
8996
  const tooltipVisible = ref(false);
7008
8997
  const tooltipStyle = ref({});
7009
8998
  let tooltipTimer = null;
8999
+ const draggedColumnIndex = ref(null);
9000
+ const draggedOverColumnIndex = ref(null);
7010
9001
  const throttledUpdateTooltip = throttle((event, content) => {
7011
9002
  const target = event.currentTarget;
7012
9003
  if (!target) return;
@@ -7056,6 +9047,23 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7056
9047
  });
7057
9048
  const tableClasses = computed(() => cn("yd-table-wrapper", props.bordered && "yd-table-wrapper--bordered"));
7058
9049
  const sortedData = computed(() => {
9050
+ if (props.remote) return [...props.dataSource];
9051
+ if (sortStates.value.length > 0) {
9052
+ const data = [...props.dataSource];
9053
+ data.sort((a, b) => {
9054
+ for (const state of sortStates.value) {
9055
+ if (!state.key || state.order === null) continue;
9056
+ const aVal = a[state.key];
9057
+ const bVal = b[state.key];
9058
+ let result = 0;
9059
+ if (aVal < bVal) result = -1;
9060
+ else if (aVal > bVal) result = 1;
9061
+ if (result !== 0) return state.order === "asc" ? result : -result;
9062
+ }
9063
+ return 0;
9064
+ });
9065
+ return data;
9066
+ }
7059
9067
  if (!sortKey.value) return [...props.dataSource];
7060
9068
  const data = [...props.dataSource];
7061
9069
  data.sort((a, b) => {
@@ -7067,9 +9075,13 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7067
9075
  });
7068
9076
  return data;
7069
9077
  });
7070
- const total = computed(() => sortedData.value.length);
9078
+ const total = computed(() => {
9079
+ if (props.remote) return props.total;
9080
+ return sortedData.value.length;
9081
+ });
7071
9082
  const totalPages = computed(() => Math.ceil(total.value / props.pageSize));
7072
9083
  const displayData = computed(() => {
9084
+ if (props.remote) return sortedData.value;
7073
9085
  if (!props.pagination) return sortedData.value;
7074
9086
  const start = (currentPage.value - 1) * props.pageSize;
7075
9087
  return sortedData.value.slice(start, start + props.pageSize);
@@ -7090,8 +9102,7 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7090
9102
  });
7091
9103
  const visibleCount = computed(() => {
7092
9104
  if (!props.virtualScroll) return displayData.value.length;
7093
- const containerHeight = scrollContainer.value?.clientHeight || 400;
7094
- return Math.ceil(containerHeight / props.rowHeight) + props.overscan * 2;
9105
+ return Math.ceil((scrollContainer.value?.clientHeight || 400) / props.rowHeight) + props.overscan * 2;
7095
9106
  });
7096
9107
  const visibleRows = computed(() => {
7097
9108
  if (!props.virtualScroll) return displayData.value;
@@ -7104,21 +9115,108 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7104
9115
  return `yd-table__${element}`;
7105
9116
  }
7106
9117
  function handleScroll() {
7107
- if (scrollContainer.value) scrollTop.value = scrollContainer.value.scrollTop;
9118
+ if (scrollContainer.value) {
9119
+ scrollTop.value = scrollContainer.value.scrollTop;
9120
+ if (props.remote && props.virtualScroll && props.loadMore) {
9121
+ const { scrollTop: st, scrollHeight, clientHeight } = scrollContainer.value;
9122
+ if (scrollHeight - st - clientHeight < 50) emit("scroll-end");
9123
+ }
9124
+ }
7108
9125
  }
7109
- function handleSort(key) {
7110
- if (sortKey.value === key) sortOrder.value = sortOrder.value === "asc" ? "desc" : "asc";
7111
- else {
7112
- sortKey.value = key;
7113
- sortOrder.value = "asc";
9126
+ function handleSort(key, event) {
9127
+ if (event?.shiftKey) {
9128
+ const existingIndex = sortStates.value.findIndex((s) => s.key === key);
9129
+ if (existingIndex >= 0) {
9130
+ const existing = sortStates.value[existingIndex];
9131
+ if (existing.order === null) sortStates.value[existingIndex].order = "asc";
9132
+ else if (existing.order === "asc") sortStates.value[existingIndex].order = "desc";
9133
+ else sortStates.value.splice(existingIndex, 1);
9134
+ } else sortStates.value.push({
9135
+ key,
9136
+ order: "asc",
9137
+ priority: sortStates.value.length + 1
9138
+ });
9139
+ emit("sort-change", sortStates.value);
9140
+ } else {
9141
+ if (sortKey.value === key) sortOrder.value = sortOrder.value === "asc" ? "desc" : "asc";
9142
+ else {
9143
+ sortKey.value = key;
9144
+ sortOrder.value = "asc";
9145
+ sortStates.value = [];
9146
+ }
9147
+ emit("sort", key, sortOrder.value);
9148
+ emit("sort-change", sortKey.value ? [{
9149
+ key: sortKey.value,
9150
+ order: sortOrder.value,
9151
+ priority: 1
9152
+ }] : []);
7114
9153
  }
7115
- emit("sort", key, sortOrder.value);
7116
9154
  }
7117
9155
  function handlePageChange(page) {
7118
9156
  if (page < 1 || page > totalPages.value) return;
7119
9157
  currentPage.value = page;
7120
9158
  emit("page-change", page);
7121
9159
  }
9160
+ function isColumnSorted(key) {
9161
+ return sortStates.value.some((s) => s.key === key && s.order !== null) || sortKey.value === key && sortStates.value.length === 0;
9162
+ }
9163
+ function getSortOrder(key) {
9164
+ return sortStates.value.find((s) => s.key === key)?.order || null;
9165
+ }
9166
+ function getSortPriority(key) {
9167
+ const index = sortStates.value.findIndex((s) => s.key === key && s.order !== null);
9168
+ return index >= 0 ? index + 1 : 0;
9169
+ }
9170
+ const columnWidths = ref({});
9171
+ let resizeStartX = 0;
9172
+ let resizeColumnKey = "";
9173
+ function startResize(event, key) {
9174
+ resizeStartX = event.clientX;
9175
+ resizeColumnKey = key;
9176
+ document.addEventListener("mousemove", handleResizeMove);
9177
+ document.addEventListener("mouseup", stopResize);
9178
+ event.preventDefault();
9179
+ }
9180
+ function handleResizeMove(event) {
9181
+ if (!resizeColumnKey) return;
9182
+ const delta = event.clientX - resizeStartX;
9183
+ const currentWidth = parseFloat(columnWidths.value[resizeColumnKey] || props.columns.find((c) => c.key === resizeColumnKey)?.width?.replace("px", "") || "100");
9184
+ const newWidth = Math.max(50, currentWidth + delta);
9185
+ columnWidths.value[resizeColumnKey] = `${newWidth}px`;
9186
+ resizeStartX = event.clientX;
9187
+ }
9188
+ function stopResize() {
9189
+ document.removeEventListener("mousemove", handleResizeMove);
9190
+ document.removeEventListener("mouseup", stopResize);
9191
+ if (resizeColumnKey && columnWidths.value[resizeColumnKey]) emit("column-resize", resizeColumnKey, columnWidths.value[resizeColumnKey]);
9192
+ resizeColumnKey = "";
9193
+ }
9194
+ function handleColumnDragStart(event, index) {
9195
+ if (!props.columns[index]?.draggable) return;
9196
+ draggedColumnIndex.value = index;
9197
+ if (event.dataTransfer) {
9198
+ event.dataTransfer.effectAllowed = "move";
9199
+ event.dataTransfer.setData("text/plain", String(index));
9200
+ }
9201
+ }
9202
+ function handleColumnDragOver(event, index) {
9203
+ event.preventDefault();
9204
+ if (draggedColumnIndex.value !== null && draggedColumnIndex.value !== index) draggedOverColumnIndex.value = index;
9205
+ }
9206
+ function handleColumnDragLeave() {
9207
+ draggedOverColumnIndex.value = null;
9208
+ }
9209
+ function handleColumnDrop(event, toIndex) {
9210
+ event.preventDefault();
9211
+ const fromIndex = draggedColumnIndex.value;
9212
+ if (fromIndex !== null && fromIndex !== toIndex) emit("column-reorder", fromIndex, toIndex);
9213
+ draggedColumnIndex.value = null;
9214
+ draggedOverColumnIndex.value = null;
9215
+ }
9216
+ function handleColumnDragEnd() {
9217
+ draggedColumnIndex.value = null;
9218
+ draggedOverColumnIndex.value = null;
9219
+ }
7122
9220
  function handleRowClick(row) {
7123
9221
  emit("row-click", row);
7124
9222
  }
@@ -7252,24 +9350,42 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7252
9350
  }, [createElementVNode("span", {
7253
9351
  class: normalizeClass(e("expand-all")),
7254
9352
  onClick: toggleExpandAll
7255
- }, toDisplayString(isAllExpanded.value ? "▾" : "▸"), 3)], 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (col) => {
9353
+ }, toDisplayString(isAllExpanded.value ? "▾" : "▸"), 3)], 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (col, colIndex) => {
7256
9354
  return openBlock(), createElementBlock("div", {
7257
9355
  key: col.key,
7258
9356
  class: normalizeClass([
7259
9357
  e("th"),
7260
9358
  col.align && e(`th--${col.align}`),
7261
- col.fixed && e(`th--fixed-${col.fixed}`)
9359
+ col.fixed && e(`th--fixed-${col.fixed}`),
9360
+ col.resizable && e("th--resizable"),
9361
+ col.draggable && e("th--draggable"),
9362
+ draggedColumnIndex.value === colIndex && e("th--dragging"),
9363
+ draggedOverColumnIndex.value === colIndex && e("th--drag-over")
7262
9364
  ]),
9365
+ draggable: col.draggable,
7263
9366
  style: normalizeStyle(col.width ? {
7264
9367
  width: col.width,
7265
- minWidth: col.width,
9368
+ minWidth: col.minWidth || col.width,
7266
9369
  flexShrink: 0
7267
- } : {})
7268
- }, [createElementVNode("div", { class: normalizeClass(e("th-content")) }, [createElementVNode("span", null, toDisplayString(col.title), 1), col.sortable ? (openBlock(), createElementBlock("button", {
7269
- key: 0,
7270
- class: normalizeClass(e("sort-btn")),
7271
- onClick: ($event) => handleSort(col.key)
7272
- }, [createElementVNode("span", { class: normalizeClass([e("sort-icon"), { [e("sort-icon--active")]: sortKey.value === col.key }]) }, toDisplayString(sortKey.value === col.key ? sortOrder.value === "asc" ? "↑" : "↓" : "↕"), 3)], 10, _hoisted_2$8)) : createCommentVNode("v-if", true)], 2)], 6);
9370
+ } : { flex: 1 }),
9371
+ onDragstart: ($event) => handleColumnDragStart($event, colIndex),
9372
+ onDragover: ($event) => handleColumnDragOver($event, colIndex),
9373
+ onDragleave: handleColumnDragLeave,
9374
+ onDrop: ($event) => handleColumnDrop($event, colIndex),
9375
+ onDragend: handleColumnDragEnd
9376
+ }, [
9377
+ createElementVNode("div", { class: normalizeClass(e("th-content")) }, [createElementVNode("span", null, toDisplayString(col.title), 1), col.sortable || col.multipleSortable ? (openBlock(), createElementBlock("button", {
9378
+ key: 0,
9379
+ class: normalizeClass(e("sort-btn")),
9380
+ onClick: ($event) => handleSort(col.key, $event)
9381
+ }, [createElementVNode("span", { class: normalizeClass([e("sort-icon"), { [e("sort-icon--active")]: isColumnSorted(col.key) }]) }, [getSortPriority(col.key) > 0 ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(getSortPriority(col.key)), 1)], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(isColumnSorted(col.key) ? getSortOrder(col.key) === "asc" ? "↑" : "↓" : "↕"), 1)], 64))], 2)], 10, _hoisted_3$5)) : createCommentVNode("v-if", true)], 2),
9382
+ createCommentVNode(" Resize handle "),
9383
+ col.resizable ? (openBlock(), createElementBlock("div", {
9384
+ key: 0,
9385
+ class: normalizeClass(e("resize-handle")),
9386
+ onMousedown: withModifiers(($event) => startResize($event, col.key), ["stop"])
9387
+ }, null, 42, _hoisted_4$4)) : createCommentVNode("v-if", true)
9388
+ ], 46, _hoisted_2$8);
7273
9389
  }), 128))], 2)) : createCommentVNode("v-if", true),
7274
9390
  createCommentVNode(" Visible rows "),
7275
9391
  (openBlock(true), createElementBlock(Fragment, null, renderList(visibleRows.value, (row, index) => {
@@ -7297,7 +9413,7 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7297
9413
  }, [createElementVNode("span", {
7298
9414
  class: normalizeClass([e("expand-icon"), { [e("expand-icon--expanded")]: expandedRows.value.has(startIndex.value + index) }]),
7299
9415
  onClick: withModifiers(($event) => toggleExpand(startIndex.value + index), ["stop"])
7300
- }, toDisplayString(expandedRows.value.has(startIndex.value + index) ? "▾" : "▸"), 11, _hoisted_4$4)], 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (col) => {
9416
+ }, toDisplayString(expandedRows.value.has(startIndex.value + index) ? "▾" : "▸"), 11, _hoisted_6$1)], 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (col) => {
7301
9417
  return openBlock(), createElementBlock("div", {
7302
9418
  key: col.key,
7303
9419
  class: normalizeClass([
@@ -7318,8 +9434,8 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7318
9434
  row,
7319
9435
  column: col,
7320
9436
  index: startIndex.value + index
7321
- }, () => [createTextVNode(toDisplayString(row[col.key]), 1)], true)], 46, _hoisted_5$1);
7322
- }), 128))], 14, _hoisted_3$5),
9437
+ }, () => [createTextVNode(toDisplayString(row[col.key]), 1)], true)], 46, _hoisted_7);
9438
+ }), 128))], 14, _hoisted_5$1),
7323
9439
  createCommentVNode(" Expand row "),
7324
9440
  __props.expandable && expandedRows.value.has(startIndex.value + index) ? (openBlock(), createElementBlock("div", {
7325
9441
  key: 0,
@@ -7335,7 +9451,7 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7335
9451
  }, [renderSlot(_ctx.$slots, "expand", {
7336
9452
  row,
7337
9453
  index: startIndex.value + index
7338
- }, void 0, true)], 10, _hoisted_6$1)], 6)) : createCommentVNode("v-if", true)
9454
+ }, void 0, true)], 10, _hoisted_8)], 6)) : createCommentVNode("v-if", true)
7339
9455
  ], 64);
7340
9456
  }), 128)),
7341
9457
  displayData.value.length === 0 && !__props.loading ? (openBlock(), createElementBlock("div", {
@@ -7352,23 +9468,41 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7352
9468
  }, [createElementVNode("span", {
7353
9469
  class: normalizeClass(e("expand-all")),
7354
9470
  onClick: toggleExpandAll
7355
- }, toDisplayString(isAllExpanded.value ? "▾" : "▸"), 3)], 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (col) => {
9471
+ }, toDisplayString(isAllExpanded.value ? "▾" : "▸"), 3)], 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (col, colIndex) => {
7356
9472
  return openBlock(), createElementBlock("th", {
7357
9473
  key: col.key,
7358
9474
  class: normalizeClass([
7359
9475
  e("th"),
7360
9476
  col.align && e(`th--${col.align}`),
7361
- col.fixed && e(`th--fixed-${col.fixed}`)
9477
+ col.fixed && e(`th--fixed-${col.fixed}`),
9478
+ col.resizable && e("th--resizable"),
9479
+ col.draggable && e("th--draggable"),
9480
+ draggedColumnIndex.value === colIndex && e("th--dragging"),
9481
+ draggedOverColumnIndex.value === colIndex && e("th--drag-over")
7362
9482
  ]),
9483
+ draggable: col.draggable,
7363
9484
  style: normalizeStyle(col.width ? {
7364
9485
  width: col.width,
7365
- minWidth: col.width
7366
- } : {})
7367
- }, [createElementVNode("div", { class: normalizeClass(e("th-content")) }, [createElementVNode("span", null, toDisplayString(col.title), 1), col.sortable ? (openBlock(), createElementBlock("button", {
7368
- key: 0,
7369
- class: normalizeClass(e("sort-btn")),
7370
- onClick: ($event) => handleSort(col.key)
7371
- }, [createElementVNode("span", { class: normalizeClass([e("sort-icon"), { [e("sort-icon--active")]: sortKey.value === col.key }]) }, toDisplayString(sortKey.value === col.key ? sortOrder.value === "asc" ? "↑" : "↓" : "↕"), 3)], 10, _hoisted_7)) : createCommentVNode("v-if", true)], 2)], 6);
9486
+ minWidth: col.minWidth || col.width
9487
+ } : {}),
9488
+ onDragstart: ($event) => handleColumnDragStart($event, colIndex),
9489
+ onDragover: ($event) => handleColumnDragOver($event, colIndex),
9490
+ onDragleave: handleColumnDragLeave,
9491
+ onDrop: ($event) => handleColumnDrop($event, colIndex),
9492
+ onDragend: handleColumnDragEnd
9493
+ }, [
9494
+ createElementVNode("div", { class: normalizeClass(e("th-content")) }, [createElementVNode("span", null, toDisplayString(col.title), 1), col.sortable || col.multipleSortable ? (openBlock(), createElementBlock("button", {
9495
+ key: 0,
9496
+ class: normalizeClass(e("sort-btn")),
9497
+ onClick: ($event) => handleSort(col.key, $event)
9498
+ }, [createElementVNode("span", { class: normalizeClass([e("sort-icon"), { [e("sort-icon--active")]: isColumnSorted(col.key) }]) }, [getSortPriority(col.key) > 0 ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(toDisplayString(getSortPriority(col.key)), 1)], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(isColumnSorted(col.key) ? getSortOrder(col.key) === "asc" ? "↑" : "↓" : "↕"), 1)], 64))], 2)], 10, _hoisted_10)) : createCommentVNode("v-if", true)], 2),
9499
+ createCommentVNode(" Resize handle "),
9500
+ col.resizable ? (openBlock(), createElementBlock("div", {
9501
+ key: 0,
9502
+ class: normalizeClass(e("resize-handle")),
9503
+ onMousedown: withModifiers(($event) => startResize($event, col.key), ["stop"])
9504
+ }, null, 42, _hoisted_11)) : createCommentVNode("v-if", true)
9505
+ ], 46, _hoisted_9);
7372
9506
  }), 128))])], 2), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(displayData.value, (row, index) => {
7373
9507
  return openBlock(), createElementBlock(Fragment, { key: index }, [
7374
9508
  createElementVNode("tr", {
@@ -7384,7 +9518,7 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7384
9518
  }, [createElementVNode("span", {
7385
9519
  class: normalizeClass([e("expand-icon"), { [e("expand-icon--expanded")]: expandedRows.value.has(index) }]),
7386
9520
  onClick: withModifiers(($event) => toggleExpand(index), ["stop"])
7387
- }, toDisplayString(expandedRows.value.has(index) ? "▾" : "▸"), 11, _hoisted_9)], 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (col) => {
9521
+ }, toDisplayString(expandedRows.value.has(index) ? "▾" : "▸"), 11, _hoisted_13)], 2)) : createCommentVNode("v-if", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (col) => {
7388
9522
  return openBlock(), createElementBlock("td", {
7389
9523
  key: col.key,
7390
9524
  class: normalizeClass([
@@ -7400,8 +9534,8 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7400
9534
  row,
7401
9535
  column: col,
7402
9536
  index
7403
- }, () => [createTextVNode(toDisplayString(row[col.key]), 1)], true)], 42, _hoisted_10);
7404
- }), 128))], 10, _hoisted_8),
9537
+ }, () => [createTextVNode(toDisplayString(row[col.key]), 1)], true)], 42, _hoisted_14);
9538
+ }), 128))], 10, _hoisted_12),
7405
9539
  createCommentVNode(" Expand row "),
7406
9540
  __props.expandable && expandedRows.value.has(index) ? (openBlock(), createElementBlock("tr", {
7407
9541
  key: 0,
@@ -7412,12 +9546,12 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7412
9546
  }, [renderSlot(_ctx.$slots, "expand", {
7413
9547
  row,
7414
9548
  index
7415
- }, void 0, true)], 10, _hoisted_11)], 2)) : createCommentVNode("v-if", true)
9549
+ }, void 0, true)], 10, _hoisted_15)], 2)) : createCommentVNode("v-if", true)
7416
9550
  ], 64);
7417
- }), 128)), displayData.value.length === 0 && !__props.loading ? (openBlock(), createElementBlock("tr", _hoisted_12, [createElementVNode("td", {
9551
+ }), 128)), displayData.value.length === 0 && !__props.loading ? (openBlock(), createElementBlock("tr", _hoisted_16, [createElementVNode("td", {
7418
9552
  class: normalizeClass(e("empty")),
7419
9553
  colspan: __props.columns.length + (__props.expandable ? 1 : 0)
7420
- }, [renderSlot(_ctx.$slots, "empty", {}, () => [createVNode(empty_default, { description: __props.emptyText }, null, 8, ["description"])], true)], 10, _hoisted_13)])) : createCommentVNode("v-if", true)])], 2)], 64))], 38),
9554
+ }, [renderSlot(_ctx.$slots, "empty", {}, () => [createVNode(empty_default, { description: __props.emptyText }, null, 8, ["description"])], true)], 10, _hoisted_17)])) : createCommentVNode("v-if", true)])], 2)], 64))], 38),
7421
9555
  createCommentVNode(" Export toolbar "),
7422
9556
  __props.exportable ? (openBlock(), createElementBlock("div", {
7423
9557
  key: 2,
@@ -7445,7 +9579,7 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7445
9579
  class: normalizeClass(e("page-btn")),
7446
9580
  disabled: currentPage.value === 1,
7447
9581
  onClick: _cache[3] || (_cache[3] = ($event) => handlePageChange(currentPage.value - 1))
7448
- }, " ‹ ", 10, _hoisted_14),
9582
+ }, " ‹ ", 10, _hoisted_18),
7449
9583
  (openBlock(true), createElementBlock(Fragment, null, renderList(visiblePages.value, (page) => {
7450
9584
  return openBlock(), createElementBlock(Fragment, { key: page }, [page === "..." ? (openBlock(), createElementBlock("button", {
7451
9585
  key: 0,
@@ -7455,13 +9589,13 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7455
9589
  key: 1,
7456
9590
  class: normalizeClass([e("page-btn"), { [e("page-btn--active")]: page === currentPage.value }]),
7457
9591
  onClick: ($event) => handlePageChange(page)
7458
- }, toDisplayString(page), 11, _hoisted_15))], 64);
9592
+ }, toDisplayString(page), 11, _hoisted_19))], 64);
7459
9593
  }), 128)),
7460
9594
  createElementVNode("button", {
7461
9595
  class: normalizeClass(e("page-btn")),
7462
9596
  disabled: currentPage.value === totalPages.value,
7463
9597
  onClick: _cache[4] || (_cache[4] = ($event) => handlePageChange(currentPage.value + 1))
7464
- }, " › ", 10, _hoisted_16),
9598
+ }, " › ", 10, _hoisted_20),
7465
9599
  createElementVNode("span", { class: normalizeClass(e("page-info")) }, "共 " + toDisplayString(total.value) + " 条", 3)
7466
9600
  ], 2)) : createCommentVNode("v-if", true),
7467
9601
  createCommentVNode(" Cell overflow tooltip "),
@@ -7476,7 +9610,7 @@ var table_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
7476
9610
  ], 2);
7477
9611
  };
7478
9612
  }
7479
- }), [["__scopeId", "data-v-c276ac4a"]]);
9613
+ }), [["__scopeId", "data-v-0736270c"]]);
7480
9614
  //#endregion
7481
9615
  //#region src/components/data-display/progress/progress.vue
7482
9616
  const _hoisted_1$12 = ["stroke-width"];
@@ -7814,8 +9948,7 @@ var tree_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ defineC
7814
9948
  });
7815
9949
  const visibleCount = computed(() => {
7816
9950
  if (!props.virtualScroll) return flatNodes.value.length;
7817
- const containerHeight = scrollContainer.value?.clientHeight || 400;
7818
- return Math.ceil(containerHeight / props.rowHeight) + props.overscan * 2;
9951
+ return Math.ceil((scrollContainer.value?.clientHeight || 400) / props.rowHeight) + props.overscan * 2;
7819
9952
  });
7820
9953
  const visibleNodes = computed(() => {
7821
9954
  if (!props.virtualScroll) return flatNodes.value;
@@ -8649,7 +10782,7 @@ var pagination_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ d
8649
10782
  ], 2);
8650
10783
  };
8651
10784
  }
8652
- }), [["__scopeId", "data-v-f4020c55"]]);
10785
+ }), [["__scopeId", "data-v-9e7079e4"]]);
8653
10786
  //#endregion
8654
10787
  //#region src/components/navigation/steps/steps.vue
8655
10788
  const _hoisted_1$7 = { key: 0 };
@@ -8915,7 +11048,7 @@ var modal_default = /* @__PURE__ */ export_helper_default(/* @__PURE__ */ define
8915
11048
  })], 8, ["disabled"]);
8916
11049
  };
8917
11050
  }
8918
- }), [["__scopeId", "data-v-770df8cd"]]);
11051
+ }), [["__scopeId", "data-v-9c8fa661"]]);
8919
11052
  //#endregion
8920
11053
  //#region src/components/feedback/message/message.vue
8921
11054
  const _hoisted_1$4 = {
@@ -9821,7 +11954,7 @@ const DEFAULT_FORM = {
9821
11954
  * 登录表单逻辑
9822
11955
  */
9823
11956
  function useLoginForm(options = {}) {
9824
- const { showCaptcha = false, captchaCode, captchaKey, defaultTab = "account", onSendCode } = options;
11957
+ const { showCaptcha = false, captchaCode, captchaKey, defaultTab = "account", onSendCode, captchaAnswer, captchaMode = "client" } = options;
9825
11958
  const formData = reactive({ ...DEFAULT_FORM });
9826
11959
  const activeTab = ref(defaultTab);
9827
11960
  const errorMsg = ref("");
@@ -9852,8 +11985,13 @@ function useLoginForm(options = {}) {
9852
11985
  }
9853
11986
  },
9854
11987
  captcha: () => {
11988
+ if (captchaMode === "server") {
11989
+ if (showCaptcha && !formData.captchaCode) return "请输入图片验证码";
11990
+ return "";
11991
+ }
9855
11992
  if (showCaptcha && !formData.captchaCode) return "请输入图片验证码";
9856
- if (showCaptcha && formData.captchaCode.toUpperCase() !== captchaCode?.value.toUpperCase()) return "图片验证码错误";
11993
+ const expectedCode = captchaAnswer?.value || captchaCode?.value;
11994
+ if (showCaptcha && formData.captchaCode.toUpperCase() !== expectedCode?.toUpperCase()) return "图片验证码错误";
9857
11995
  return "";
9858
11996
  }
9859
11997
  };
@@ -9978,6 +12116,25 @@ function useLoading(initialValue = false) {
9978
12116
  };
9979
12117
  }
9980
12118
  //#endregion
12119
+ //#region src/types/index.ts
12120
+ /** 是否为数组 */
12121
+ const isArray = Array.isArray;
12122
+ /** 是否为对象 */
12123
+ const isObject = (val) => val !== null && typeof val === "object" && !isArray(val);
12124
+ /** 是否为日期 */
12125
+ const isDate = (val) => val instanceof Date;
12126
+ /** 是否为函数 */
12127
+ const isFunction = (val) => typeof val === "function";
12128
+ /** 是否为空 */
12129
+ const isEmpty = (val) => {
12130
+ if (val === null || val === void 0) return true;
12131
+ if (isArray(val) || typeof val === "string") return val.length === 0;
12132
+ if (isObject(val)) return Object.keys(val).length === 0;
12133
+ return false;
12134
+ };
12135
+ /** 是否为 Promise */
12136
+ const isPromise = (val) => val instanceof Promise || typeof val === "object" && typeof val?.["then"] === "function";
12137
+ //#endregion
9981
12138
  //#region src/styles/themes/index.ts
9982
12139
  /**
9983
12140
  * Theme definitions
@@ -10050,8 +12207,7 @@ function secureStoragePlugin({ store }) {
10050
12207
  if (isSession) storageReady.then(restore);
10051
12208
  else restore();
10052
12209
  store.$subscribe(async () => {
10053
- const plainState = { ...store.$state };
10054
- await storage.setItem(store.$id, plainState);
12210
+ await storage.setItem(store.$id, { ...store.$state });
10055
12211
  });
10056
12212
  }
10057
12213
  //#endregion
@@ -10496,6 +12652,7 @@ const modules = /* @__PURE__ */ Object.assign({
10496
12652
  "./langs/en-US.json": en_US_exports,
10497
12653
  "./langs/zh-CN.json": zh_CN_exports
10498
12654
  });
12655
+ const lazyLocales = /* @__PURE__ */ new Map();
10499
12656
  /**
10500
12657
  * 支持的语言
10501
12658
  */
@@ -10507,6 +12664,12 @@ const supportedLocales = [{
10507
12664
  value: "en-US"
10508
12665
  }];
10509
12666
  /**
12667
+ * 注册懒加载的 locale 文件
12668
+ */
12669
+ function registerLazyLocale(locale, loader) {
12670
+ lazyLocales.set(locale, loader);
12671
+ }
12672
+ /**
10510
12673
  * 获取 locale 消息
10511
12674
  */
10512
12675
  function getLocaleMessages() {
@@ -10528,10 +12691,23 @@ function setLocale(locale) {
10528
12691
  document?.querySelector("html")?.setAttribute("lang", locale);
10529
12692
  }
10530
12693
  /**
12694
+ * 获取当前语言
12695
+ */
12696
+ function getCurrentLocale() {
12697
+ return unref(i18n.global.locale);
12698
+ }
12699
+ /**
10531
12700
  * 初始化 i18n
10532
12701
  */
10533
12702
  async function setupI18n(app, options = {}) {
10534
- const { defaultLocale = "zh-CN" } = options;
12703
+ const { defaultLocale = "zh-CN", lazy = false } = options;
12704
+ if (lazy) {
12705
+ const supported = supportedLocales.map((l) => l.value);
12706
+ for (const locale of supported) if (!lazyLocales.has(locale)) try {
12707
+ const module = await import(`./langs/${locale}.json`);
12708
+ lazyLocales.set(locale, () => Promise.resolve(module.default));
12709
+ } catch {}
12710
+ }
10535
12711
  const messages = getLocaleMessages();
10536
12712
  i18n.global.setLocaleMessage(defaultLocale, messages[defaultLocale] || {});
10537
12713
  const fallbackLocale = defaultLocale === "zh-CN" ? "en-US" : "zh-CN";
@@ -10547,6 +12723,13 @@ async function setupI18n(app, options = {}) {
10547
12723
  */
10548
12724
  async function changeLocale(locale) {
10549
12725
  if (unref(i18n.global.locale) === locale) return;
12726
+ const lazyLoader = lazyLocales.get(locale);
12727
+ if (lazyLoader) {
12728
+ const messages = await lazyLoader();
12729
+ i18n.global.setLocaleMessage(locale, messages);
12730
+ setLocale(locale);
12731
+ return;
12732
+ }
10550
12733
  const messages = getLocaleMessages();
10551
12734
  if (!messages[locale]) {
10552
12735
  console.warn(`[yd-admin] Locale '${locale}' not found`);
@@ -10555,5 +12738,51 @@ async function changeLocale(locale) {
10555
12738
  i18n.global.setLocaleMessage(locale, messages[locale]);
10556
12739
  setLocale(locale);
10557
12740
  }
12741
+ /**
12742
+ * 获取翻译文本
12743
+ */
12744
+ function t(key, params) {
12745
+ const msg = i18n.global.t(key, params);
12746
+ return typeof msg === "string" ? msg : key;
12747
+ }
12748
+ /**
12749
+ * 获取翻译文本(复数形式)- 使用 'one' 和 'other' 选择器
12750
+ */
12751
+ function tc(key, choice, params) {
12752
+ const msg = i18n.global.t(`${key}.${choice === 1 ? "one" : "other"}`, params);
12753
+ return typeof msg === "string" ? msg : key;
12754
+ }
12755
+ /**
12756
+ * 获取日期时间格式化
12757
+ */
12758
+ function dt(value, options, locale) {
12759
+ const currentLocale = locale || unref(i18n.global.locale);
12760
+ return new Intl.DateTimeFormat(currentLocale, options).format(new Date(value));
12761
+ }
12762
+ /**
12763
+ * 获取数字格式化
12764
+ */
12765
+ function nf(value, options, locale) {
12766
+ const currentLocale = locale || unref(i18n.global.locale);
12767
+ return new Intl.NumberFormat(currentLocale, options).format(value);
12768
+ }
12769
+ //#endregion
12770
+ //#region src/resolver/index.ts
12771
+ /**
12772
+ * YdAdmin 组件库解析器
12773
+ * 将 YdXxx 组件自动映射到 yd-admin 包
12774
+ */
12775
+ function YdAdminResolver() {
12776
+ return (componentName) => {
12777
+ if (componentName.startsWith("Yd")) return {
12778
+ name: componentName,
12779
+ from: "yd-admin"
12780
+ };
12781
+ if (componentName === "Message" || componentName === "Notification") return {
12782
+ name: componentName,
12783
+ from: "yd-admin"
12784
+ };
12785
+ };
12786
+ }
10558
12787
  //#endregion
10559
- export { ANIMATION_DURATION, COMPONENT_PREFIX, CSS_PREFIX, DEBOUNCE_DEFAULTS, DEBOUNCE_DELAY, DEFAULT_LAYOUT_SIZE, Message, Notification, THROTTLE_DEFAULTS, THROTTLE_DELAY, anchor_default as YdAnchor, auto_complete_default as YdAutoComplete, avatar_default as YdAvatar, badge_default as YdBadge, breadcrumb_default as YdBreadcrumb, button_default as YdButton, captcha_default as YdCaptcha, card_default as YdCard, cascader_default as YdCascader, checkbox_default as YdCheckbox, checkbox_group_default as YdCheckboxGroup, collapse_default as YdCollapse, config_provider_default as YdConfigProvider, context_menu_default as YdContextMenu, date_picker_default as YdDatePicker, date_range_picker_default as YdDateRangePicker, divider_default as YdDivider, drawer_default as YdDrawer, dropdown_default as YdDropdown, empty_default as YdEmpty, form_default as YdForm, form_item_default as YdFormItem, image_default as YdImage, image_preview_group_default as YdImagePreviewGroup, input_default as YdInput, input_number_default as YdInputNumber, layout_default as YdLayout, layout_content_default as YdLayoutContent, layout_header_default as YdLayoutHeader, layout_sidebar_default as YdLayoutSidebar, list_default as YdList, login_default as YdLogin, login_centered_default as YdLoginCentered, menu_default as YdMenu, modal_default as YdModal, pagination_default as YdPagination, pin_input_default as YdPinInput, popconfirm_default as YdPopconfirm, progress_default as YdProgress, radio_default as YdRadio, radio_group_default as YdRadioGroup, rate_default as YdRate, result_default as YdResult, select_default as YdSelect, skeleton_default as YdSkeleton, slider_default as YdSlider, space_default as YdSpace, spin_default as YdSpin, statistic_default as YdStatistic, steps_default as YdSteps, switch_default as YdSwitch, table_default as YdTable, tabs_default as YdTabs, tag_default as YdTag, textarea_default as YdTextarea, time_picker_default as YdTimePicker, timeline_default as YdTimeline, tooltip_default as YdTooltip, transfer_default as YdTransfer, tree_default as YdTree, upload_default as YdUpload, Z_INDEX, changeLocale, cn, debounce, decrypt, deepClone, encrypt, generateId, generateSessionKey, i18n, initSecureStorage, isEmptyObject, secureLocal, secureSession, secureStoragePlugin, setLocale, setupI18n, supportedLocales, themes, throttle, useFormValidate, useLoading, useLoginForm, useNamespace };
12788
+ export { ANIMATION_DURATION, COMPONENT_PREFIX, CSS_PREFIX, DEBOUNCE_DEFAULTS, DEBOUNCE_DELAY, DEFAULT_LAYOUT_SIZE, Message, Notification, THROTTLE_DEFAULTS, THROTTLE_DELAY, YdAdminResolver, anchor_default as YdAnchor, auto_complete_default as YdAutoComplete, avatar_default as YdAvatar, badge_default as YdBadge, breadcrumb_default as YdBreadcrumb, button_default as YdButton, captcha_default as YdCaptcha, card_default as YdCard, cascader_default as YdCascader, checkbox_default as YdCheckbox, checkbox_group_default as YdCheckboxGroup, collapse_default as YdCollapse, color_picker_default as YdColorPicker, config_provider_default as YdConfigProvider, context_menu_default as YdContextMenu, date_picker_default as YdDatePicker, date_range_picker_default as YdDateRangePicker, divider_default as YdDivider, drawer_default as YdDrawer, dropdown_default as YdDropdown, empty_default as YdEmpty, form_default as YdForm, form_item_default as YdFormItem, image_default as YdImage, image_preview_group_default as YdImagePreviewGroup, input_default as YdInput, input_number_default as YdInputNumber, layout_default as YdLayout, layout_content_default as YdLayoutContent, layout_header_default as YdLayoutHeader, layout_sidebar_default as YdLayoutSidebar, list_default as YdList, login_default as YdLogin, login_centered_default as YdLoginCentered, menu_default as YdMenu, modal_default as YdModal, pagination_default as YdPagination, pin_input_default as YdPinInput, popconfirm_default as YdPopconfirm, progress_default as YdProgress, radio_default as YdRadio, radio_group_default as YdRadioGroup, rate_default as YdRate, result_default as YdResult, SchemaForm_default as YdSchemaForm, select_default as YdSelect, skeleton_default as YdSkeleton, slider_default as YdSlider, space_default as YdSpace, spin_default as YdSpin, statistic_default as YdStatistic, steps_default as YdSteps, switch_default as YdSwitch, table_default as YdTable, tabs_default as YdTabs, tag_default as YdTag, textarea_default as YdTextarea, time_picker_default as YdTimePicker, timeline_default as YdTimeline, tooltip_default as YdTooltip, transfer_default as YdTransfer, tree_default as YdTree, tree_select_default as YdTreeSelect, upload_default as YdUpload, Z_INDEX, buildBreadcrumb, changeLocale, checkRoutePermission, cn, convertToSimpleRoute, debounce, decrypt, deepClone, dt, dynamicRouter, encrypt, filterMenuItems, findMenuItem, findMenuPath, flattenMenuItems, generateId, generateRouteTitle, generateSessionKey, getBreadcrumbPaths, getCurrentLocale, i18n, initSecureStorage, isArray, isDate, isEmpty, isEmptyObject, isFunction, isObject, isPathMatch, isPromise, joinPath, menuToRoutes, nf, normalizePath, registerLazyLocale, searchMenuItems, secureLocal, secureSession, secureStoragePlugin, setLocale, setupI18n, supportedLocales, t, tc, themes, throttle, useFormSchema, useFormValidate, useLoading, useLoginForm, useNamespace };