workdesktop-ai 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/CHANGELOG.md +31 -6
  2. package/README.md +16 -6
  3. package/dist/api-button/index.mjs +1 -1
  4. package/dist/auto-complete/index.mjs +1 -1
  5. package/dist/base.css +1 -1
  6. package/dist/checkbox-list/index.mjs +1 -1
  7. package/dist/chunks/{ApiButton.vue_vue_type_script_setup_true_lang-CweWFfDE.mjs → ApiButton.vue_vue_type_script_setup_true_lang-CH_B3jbO.mjs} +2 -2
  8. package/dist/chunks/{ApiButton.vue_vue_type_script_setup_true_lang-CweWFfDE.mjs.map → ApiButton.vue_vue_type_script_setup_true_lang-CH_B3jbO.mjs.map} +1 -1
  9. package/dist/chunks/{AutoComplete-B_L169hU.mjs → AutoComplete-6yrCFGZ5.mjs} +2 -2
  10. package/dist/chunks/{AutoComplete-B_L169hU.mjs.map → AutoComplete-6yrCFGZ5.mjs.map} +1 -1
  11. package/dist/chunks/{CheckboxList-bPqpbd8d.mjs → CheckboxList-ChmfF6zs.mjs} +2 -2
  12. package/dist/chunks/{CheckboxList-bPqpbd8d.mjs.map → CheckboxList-ChmfF6zs.mjs.map} +1 -1
  13. package/dist/chunks/{ConfirmButton.vue_vue_type_script_setup_true_lang-DpdMPkka.mjs → ConfirmButton.vue_vue_type_script_setup_true_lang-D9ZUQB7V.mjs} +2 -2
  14. package/dist/chunks/{ConfirmButton.vue_vue_type_script_setup_true_lang-DpdMPkka.mjs.map → ConfirmButton.vue_vue_type_script_setup_true_lang-D9ZUQB7V.mjs.map} +1 -1
  15. package/dist/chunks/{DataForm-C6UW92Ds.mjs → DataForm-Rsa1PT-X.mjs} +16 -16
  16. package/dist/chunks/{DataForm-C6UW92Ds.mjs.map → DataForm-Rsa1PT-X.mjs.map} +1 -1
  17. package/dist/chunks/{DataGrid-BhgND4G_.mjs → DataGrid-DzbJpT43.mjs} +4 -4
  18. package/dist/chunks/{DataGrid-BhgND4G_.mjs.map → DataGrid-DzbJpT43.mjs.map} +1 -1
  19. package/dist/chunks/{EditableGrid-Cx7ScWkW.mjs → EditableGrid-C-0uy89H.mjs} +330 -333
  20. package/dist/chunks/EditableGrid-C-0uy89H.mjs.map +1 -0
  21. package/dist/chunks/{ImageUpload-D3JGJjVO.mjs → ImageUpload-CrDyIjWC.mjs} +2 -2
  22. package/dist/chunks/{ImageUpload-D3JGJjVO.mjs.map → ImageUpload-CrDyIjWC.mjs.map} +1 -1
  23. package/dist/chunks/{Panel-d4chdlTA.mjs → Panel-BHqAeBaH.mjs} +33 -31
  24. package/dist/chunks/Panel-BHqAeBaH.mjs.map +1 -0
  25. package/dist/chunks/{PromptButton.vue_vue_type_script_setup_true_lang-BqoNAUoo.mjs → PromptButton.vue_vue_type_script_setup_true_lang-ClrF3C2w.mjs} +2 -2
  26. package/dist/chunks/{PromptButton.vue_vue_type_script_setup_true_lang-BqoNAUoo.mjs.map → PromptButton.vue_vue_type_script_setup_true_lang-ClrF3C2w.mjs.map} +1 -1
  27. package/dist/chunks/{RadioList-DT-8WSN2.mjs → RadioList-BIwUZ6lm.mjs} +2 -2
  28. package/dist/chunks/{RadioList-DT-8WSN2.mjs.map → RadioList-BIwUZ6lm.mjs.map} +1 -1
  29. package/dist/chunks/{Requester.vue_vue_type_script_setup_true_lang-5B1V-53c.mjs → Requester.vue_vue_type_script_setup_true_lang-Bu10N1Hj.mjs} +2 -2
  30. package/dist/chunks/{Requester.vue_vue_type_script_setup_true_lang-5B1V-53c.mjs.map → Requester.vue_vue_type_script_setup_true_lang-Bu10N1Hj.mjs.map} +1 -1
  31. package/dist/chunks/{SearchPanel-xQ1hPaNq.mjs → SearchPanel-DPlWWuXb.mjs} +2 -2
  32. package/dist/chunks/{SearchPanel-xQ1hPaNq.mjs.map → SearchPanel-DPlWWuXb.mjs.map} +1 -1
  33. package/dist/chunks/{Select-CMw-tWYm.mjs → Select-DlJ9U0nE.mjs} +2 -2
  34. package/dist/chunks/{Select-CMw-tWYm.mjs.map → Select-DlJ9U0nE.mjs.map} +1 -1
  35. package/dist/chunks/{Station-BF_QlQ8c.mjs → Station-CrMTjqfa.mjs} +2 -2
  36. package/dist/chunks/{Station-BF_QlQ8c.mjs.map → Station-CrMTjqfa.mjs.map} +1 -1
  37. package/dist/chunks/{Switch.vue_vue_type_script_setup_true_lang-CCU_d3jW.mjs → Switch.vue_vue_type_script_setup_true_lang-BxJdsReQ.mjs} +2 -2
  38. package/dist/chunks/{Switch.vue_vue_type_script_setup_true_lang-CCU_d3jW.mjs.map → Switch.vue_vue_type_script_setup_true_lang-BxJdsReQ.mjs.map} +1 -1
  39. package/dist/chunks/{Upload.vue_vue_type_script_setup_true_lang-CkxGO85H.mjs → Upload.vue_vue_type_script_setup_true_lang-DORizGEF.mjs} +2 -2
  40. package/dist/chunks/{Upload.vue_vue_type_script_setup_true_lang-CkxGO85H.mjs.map → Upload.vue_vue_type_script_setup_true_lang-DORizGEF.mjs.map} +1 -1
  41. package/dist/chunks/{Viewer-COLbtcgF.mjs → Viewer-DcMSN3_1.mjs} +2 -2
  42. package/dist/chunks/{Viewer-COLbtcgF.mjs.map → Viewer-DcMSN3_1.mjs.map} +1 -1
  43. package/dist/chunks/http-9ToPNkWJ.mjs +4026 -0
  44. package/dist/chunks/http-9ToPNkWJ.mjs.map +1 -0
  45. package/dist/chunks/{useApiAction-C1CdKGjt.mjs → useApiAction-BetCGQrx.mjs} +2 -2
  46. package/dist/chunks/{useApiAction-C1CdKGjt.mjs.map → useApiAction-BetCGQrx.mjs.map} +1 -1
  47. package/dist/chunks/{useColumnSettings-BDtF5-8R.mjs → useColumnSettings-CnXeA0k7.mjs} +2 -2
  48. package/dist/chunks/{useColumnSettings-BDtF5-8R.mjs.map → useColumnSettings-CnXeA0k7.mjs.map} +1 -1
  49. package/dist/chunks/{useOptionsLoader-D0RTB_ar.mjs → useOptionsLoader-BwRdHDPL.mjs} +2 -2
  50. package/dist/chunks/{useOptionsLoader-D0RTB_ar.mjs.map → useOptionsLoader-BwRdHDPL.mjs.map} +1 -1
  51. package/dist/confirm-button/index.mjs +1 -1
  52. package/dist/data-form/index.mjs +1 -1
  53. package/dist/data-form/style.css +1 -1
  54. package/dist/data-grid/index.mjs +1 -1
  55. package/dist/data-grid/style.css +1 -1
  56. package/dist/editable-grid/index.mjs +1 -1
  57. package/dist/editable-grid/style.css +1 -1
  58. package/dist/image-upload/index.mjs +1 -1
  59. package/dist/index.esm.js +106 -103
  60. package/dist/index.umd.js +605 -18
  61. package/dist/index.umd.js.map +1 -1
  62. package/dist/panel/index.mjs +1 -1
  63. package/dist/panel/style.css +1 -1
  64. package/dist/prompt-button/index.mjs +1 -1
  65. package/dist/radio-list/index.mjs +1 -1
  66. package/dist/requester/index.mjs +1 -1
  67. package/dist/search-panel/index.mjs +1 -1
  68. package/dist/search-panel/style.css +1 -1
  69. package/dist/select/index.mjs +1 -1
  70. package/dist/station/index.mjs +1 -1
  71. package/dist/station/style.css +1 -1
  72. package/dist/style.css +1 -1
  73. package/dist/switch/index.mjs +1 -1
  74. package/dist/types/src/components/data/editable-grid/EditableGrid.vue.d.ts +9 -9
  75. package/dist/types/src/components/styles/Panel.vue.d.ts +11 -0
  76. package/dist/types/src/index.d.ts +2 -0
  77. package/dist/types/src/lib/core/skins/apple.d.ts +3 -0
  78. package/dist/types/src/lib/core/skins/business.d.ts +3 -0
  79. package/dist/types/src/lib/core/skins/chinese.d.ts +3 -0
  80. package/dist/types/src/lib/core/skins/cool.d.ts +3 -0
  81. package/dist/types/src/lib/core/skins/cyberpunk.d.ts +3 -0
  82. package/dist/types/src/lib/core/skins/default.d.ts +3 -0
  83. package/dist/types/src/lib/core/skins/fashion.d.ts +3 -0
  84. package/dist/types/src/lib/core/skins/flat.d.ts +3 -0
  85. package/dist/types/src/lib/core/skins/governance.d.ts +3 -0
  86. package/dist/types/src/lib/core/skins/index.d.ts +15 -0
  87. package/dist/types/src/lib/core/skins/tech-brain.d.ts +5 -0
  88. package/dist/types/src/lib/core/skins/tech.d.ts +3 -0
  89. package/dist/types/src/lib/core/skins/types.d.ts +19 -0
  90. package/dist/types/src/lib/core/theme.d.ts +7 -2
  91. package/dist/types/src/types/config.d.ts +4 -0
  92. package/dist/upload/index.mjs +1 -1
  93. package/dist/viewer/index.mjs +1 -1
  94. package/llms.txt +688 -0
  95. package/package.json +3 -2
  96. package/dist/chunks/EditableGrid-Cx7ScWkW.mjs.map +0 -1
  97. package/dist/chunks/Panel-d4chdlTA.mjs.map +0 -1
  98. package/dist/chunks/http-DUPsbs2K.mjs +0 -2951
  99. package/dist/chunks/http-DUPsbs2K.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Station-BF_QlQ8c.mjs","sources":["../../src/lib/core/station-linkage.ts","../../src/components/layout/StationMenuNode.vue","../../src/components/layout/Station.vue"],"sourcesContent":["/**\n * WdStation 联动注册中心\n *\n * 复用 DataGrid linkage 的 filter 分组心智:\n * - Station 挂载时按 filter 注册;\n * - 业务代码调用 setStationFooter(target, info, selfFilter) 更新底部动态信息;\n * - refreshStationView(target, selfFilter) 触发内容区强制刷新(重新挂载)。\n *\n * target:true = 与发起方同 filter 组;字符串 = 定向该 filter 组。\n */\n\nexport interface StationInstance {\n /** 组件 filter 分组标识 */\n filter: string\n /** 设置底部动态信息 */\n setFooterInfo: (info: string) => void\n /** 刷新内容区(强制重挂载) */\n refresh: () => void\n}\n\n/** filter 分组 → Station 实例集合 */\nconst stationRegistry: Map<string, Set<StationInstance>> = new Map()\n\nfunction groupOf(filter?: string): string {\n return filter || ''\n}\n\n/**\n * 注册 Station 实例,返回注销函数(组件 onUnmounted 调用)\n */\nexport function registerStation(instance: StationInstance): () => void {\n const key = groupOf(instance.filter)\n if (!stationRegistry.has(key)) {\n stationRegistry.set(key, new Set())\n }\n stationRegistry.get(key)!.add(instance)\n return () => {\n stationRegistry.get(key)?.delete(instance)\n }\n}\n\nfunction resolveTargets(target: boolean | string | undefined, selfFilter?: string): StationInstance[] {\n if (!target) return []\n const targetFilter = typeof target === 'string' ? target : groupOf(selfFilter)\n const group = stationRegistry.get(targetFilter)\n return group ? Array.from(group) : []\n}\n\n/**\n * 设置目标 Station 底部动态信息\n * @param target true=同 filter 组;字符串=定向该 filter 组\n * @param info 展示内容(文本)\n * @param selfFilter 发起方自身 filter\n * @returns 被更新的实例数量\n */\nexport function setStationFooter(\n target: boolean | string,\n info: string,\n selfFilter?: string\n): number {\n const targets = resolveTargets(target, selfFilter)\n let count = 0\n targets.forEach((station) => {\n try {\n station.setFooterInfo(info)\n count += 1\n } catch (e) {\n console.error('[WorkDesktop] setStationFooter error:', e)\n }\n })\n return count\n}\n\n/**\n * 刷新目标 Station 内容区(强制重新挂载)\n * @param target true=同 filter 组(默认);字符串=定向该 filter 组\n * @param selfFilter 发起方自身 filter\n * @returns 被刷新的实例数量\n */\nexport function refreshStationView(\n target: boolean | string = true,\n selfFilter?: string\n): number {\n const targets = resolveTargets(target, selfFilter)\n let count = 0\n targets.forEach((station) => {\n try {\n station.refresh()\n count += 1\n } catch (e) {\n console.error('[WorkDesktop] refreshStationView error:', e)\n }\n })\n return count\n}\n\n/**\n * 仅供测试 / 调试:清空注册中心\n */\nexport function clearStationRegistry(): void {\n stationRegistry.clear()\n}\n","<template>\n <template v-for=\"item in items\" :key=\"item._key\">\n <el-sub-menu v-if=\"item.children && item.children.length\" :index=\"item._key\">\n <template #title>\n <el-icon v-if=\"resolveIcon(item.icon)\"><component :is=\"resolveIcon(item.icon)\" /></el-icon>\n <span>{{ item.title }}</span>\n </template>\n <station-menu-node :items=\"item.children\" @select=\"forwardSelect\" />\n </el-sub-menu>\n <el-menu-item v-else :index=\"item._key\" :disabled=\"item.disabled\" @click=\"onClick(item)\">\n <el-icon v-if=\"resolveIcon(item.icon)\"><component :is=\"resolveIcon(item.icon)\" /></el-icon>\n <span>{{ item.title }}</span>\n <el-badge v-if=\"item.badge !== undefined && item.badge !== ''\" :value=\"item.badge\" class=\"wd-station__menu-badge\" />\n </el-menu-item>\n </template>\n</template>\n\n<script setup lang=\"ts\">\nimport * as ElIcons from '@element-plus/icons-vue'\n\ndefineOptions({ name: 'StationMenuNode' })\n\ndefineProps({\n /** 归一化后的菜单项(带 _key) */\n items: { type: Array as () => any[], default: () => [] }\n})\n\nconst emit = defineEmits<{\n (e: 'select', item: any): void\n}>()\n\n/** 图标归一:字符串按 @element-plus/icons-vue 名称解析,组件直接用 */\nfunction resolveIcon(icon: any) {\n if (!icon) return null\n if (typeof icon === 'string') return (ElIcons as any)[icon] || null\n return icon\n}\n\nfunction onClick(item: any) {\n if (item.disabled) return\n emit('select', item)\n}\n\nfunction forwardSelect(item: any) {\n emit('select', item)\n}\n</script>\n\n<style scoped>\n/* 菜单徽章:靠右显示、垂直居中(el-menu-item 为 flex 容器,badge 为末位子元素) */\n.wd-station__menu-badge {\n /* 转 inline-flex:消除继承自 el-menu-item 的 56px line-height 行盒撑高(否则圆点沉底) */\n display: inline-flex;\n align-items: center;\n margin-left: auto;\n align-self: center;\n flex-shrink: 0;\n}\n/* 菜单折叠成窄条时隐藏徽章,避免溢出 */\n.el-menu--collapse .wd-station__menu-badge {\n display: none;\n}\n</style>\n","<template>\n <div class=\"wd-station\" :class=\"{ 'is-collapsed': collapsedState }\">\n <!-- 左侧菜单栏(menuMode=side):logo 与菜单同列,菜单紧贴 logo -->\n <aside v-if=\"menuMode === 'side'\" class=\"wd-station__aside\" :class=\"{ 'is-collapsed': collapsedState }\">\n <div class=\"wd-station__logo\" :class=\"{ 'is-collapsed': collapsedState }\">\n <slot name=\"logo\" :collapsed=\"collapsedState\">\n <el-icon v-if=\"resolveIcon(logo)\" class=\"wd-station__logo-icon\">\n <component :is=\"resolveIcon(logo)\" />\n </el-icon>\n <span v-show=\"!collapsedState\" class=\"wd-station__logo-title\">{{ title }}</span>\n </slot>\n </div>\n <slot name=\"menu-top\" :collapsed=\"collapsedState\" />\n <el-scrollbar class=\"wd-station__menu-scroll\">\n <el-menu class=\"wd-station__menu\" :collapse=\"collapsedState\" :default-active=\"currentKey\">\n <template v-if=\"headerMode === 'title'\">\n <template v-if=\"groups.length > 1\">\n <el-menu-item-group v-for=\"g in groups\" :key=\"g.key\" :title=\"g.title\">\n <station-menu-node :items=\"g.menus\" @select=\"onMenuSelect\" />\n </el-menu-item-group>\n </template>\n <!-- 单分组无分组语义,直接平铺菜单项(不渲染组标题) -->\n <station-menu-node v-else :items=\"groups[0]?.menus || []\" @select=\"onMenuSelect\" />\n </template>\n <station-menu-node v-else :items=\"currentGroupMenus\" @select=\"onMenuSelect\" />\n </el-menu>\n </el-scrollbar>\n <slot name=\"menu-bottom\" :collapsed=\"collapsedState\" />\n </aside>\n\n <div class=\"wd-station__main\">\n <header class=\"wd-station__header\">\n <div class=\"wd-station__header-left\">\n <!-- 折叠按钮:分导台左侧。side 用左右折叠图标,top 用向上折叠图标 -->\n <el-icon\n v-if=\"collapsible && menuMode !== 'none'\"\n class=\"wd-station__collapse\"\n @click=\"toggleCollapsed\"\n >\n <Fold v-if=\"menuMode === 'side' && !collapsedState\" />\n <Expand v-else-if=\"menuMode === 'side'\" />\n <ArrowUp v-else-if=\"!collapsedState\" />\n <ArrowDown v-else />\n </el-icon>\n <!-- top / none 模式 logo 进 header -->\n <div v-if=\"menuMode !== 'side'\" class=\"wd-station__logo wd-station__logo--header\">\n <slot name=\"logo\" :collapsed=\"collapsedState\">\n <el-icon v-if=\"resolveIcon(logo)\" class=\"wd-station__logo-icon\">\n <component :is=\"resolveIcon(logo)\" />\n </el-icon>\n <span class=\"wd-station__logo-title\">{{ title }}</span>\n </slot>\n </div>\n <template v-for=\"tool in toolbarLeft\" :key=\"tool\">\n <el-icon\n v-if=\"tool === 'refresh'\"\n data-tool=\"refresh\"\n class=\"wd-station__tool\"\n @click=\"refresh\"\n ><Refresh /></el-icon>\n <el-icon\n v-else-if=\"tool === 'settings'\"\n data-tool=\"settings\"\n class=\"wd-station__tool\"\n @click=\"onSettings\"\n ><Setting /></el-icon>\n <el-dropdown v-else-if=\"tool === 'user'\" data-tool=\"user\" class=\"wd-station__tool\" trigger=\"click\">\n <span class=\"wd-station__user\">\n <el-avatar :size=\"24\" :src=\"userAvatar || undefined\">{{ userInitial }}</el-avatar>\n <span class=\"wd-station__user-name\">{{ userName }}</span>\n </span>\n <template #dropdown>\n <el-dropdown-menu>\n <el-dropdown-item @click=\"onLogout\">退出登录</el-dropdown-item>\n </el-dropdown-menu>\n </template>\n </el-dropdown>\n <el-button v-else-if=\"tool === 'login'\" data-tool=\"login\" size=\"small\" @click=\"onLogin\">登录</el-button>\n </template>\n <slot name=\"header-left\" />\n </div>\n <div class=\"wd-station__header-center\">\n <!-- 分导台:流式块状分组切换条,仅多分组且 headerMode=nav 时显示 -->\n <nav v-if=\"showNav\" class=\"wd-station__nav\">\n <span\n v-for=\"g in groups\"\n :key=\"g.key\"\n class=\"wd-station__nav-item\"\n :class=\"{ 'is-active': g.key === activeGroupKey }\"\n @click=\"setActiveGroup(g.key)\"\n >\n <el-icon v-if=\"resolveIcon(g.icon)\"><component :is=\"resolveIcon(g.icon)\" /></el-icon>\n {{ g.title }}\n </span>\n </nav>\n <span v-else class=\"wd-station__header-title\">{{ title }}</span>\n <slot name=\"header-center\" />\n </div>\n <div class=\"wd-station__header-right\">\n <slot name=\"header-right\" />\n <template v-for=\"tool in toolbarRight\" :key=\"tool\">\n <el-icon\n v-if=\"tool === 'refresh'\"\n data-tool=\"refresh\"\n class=\"wd-station__tool\"\n @click=\"refresh\"\n ><Refresh /></el-icon>\n <el-icon\n v-else-if=\"tool === 'settings'\"\n data-tool=\"settings\"\n class=\"wd-station__tool\"\n @click=\"onSettings\"\n ><Setting /></el-icon>\n <el-dropdown v-else-if=\"tool === 'user'\" data-tool=\"user\" class=\"wd-station__tool\" trigger=\"click\">\n <span class=\"wd-station__user\">\n <el-avatar :size=\"24\" :src=\"userAvatar || undefined\">{{ userInitial }}</el-avatar>\n <span class=\"wd-station__user-name\">{{ userName }}</span>\n </span>\n <template #dropdown>\n <el-dropdown-menu>\n <el-dropdown-item @click=\"onLogout\">退出登录</el-dropdown-item>\n </el-dropdown-menu>\n </template>\n </el-dropdown>\n <el-button v-else-if=\"tool === 'login'\" data-tool=\"login\" size=\"small\" @click=\"onLogin\">登录</el-button>\n </template>\n </div>\n </header>\n\n <!-- 顶部菜单(menuMode=top),向上折叠时隐藏 -->\n <div v-if=\"menuMode === 'top'\" v-show=\"!collapsedState\" class=\"wd-station__top-menu\">\n <slot name=\"top-menu-left\" />\n <el-menu mode=\"horizontal\" :default-active=\"currentKey\">\n <station-menu-node :items=\"currentGroupMenus\" @select=\"onMenuSelect\" />\n </el-menu>\n <slot name=\"top-menu-right\" />\n </div>\n\n <!-- tabs 导航(contentMode=tabs):整宽撑满,右侧下拉批量关闭;自绘 label 插槽,affix 无关闭图标 -->\n <div v-if=\"contentMode === 'tabs'\" class=\"wd-station__tabs-bar\">\n <slot name=\"tabs-left\" />\n <el-tabs\n :model-value=\"currentKey\"\n type=\"card\"\n class=\"wd-station__tabs\"\n >\n <el-tab-pane v-for=\"tab in tabs\" :key=\"tab.key\" :name=\"tab.key\">\n <template #label>\n <span class=\"wd-station__tab-label\" @click=\"onTabClick(tab)\">{{ tab.title }}</span>\n <el-icon v-if=\"!tab.affix\" class=\"wd-station__tab-close\" @click.stop=\"closeTab(tab.key)\">\n <Close />\n </el-icon>\n </template>\n </el-tab-pane>\n </el-tabs>\n <el-dropdown class=\"wd-station__tabs-actions\" trigger=\"click\">\n <span class=\"wd-station__tabs-more\">\n <el-icon><ArrowDown /></el-icon>\n </span>\n <template #dropdown>\n <el-dropdown-menu>\n <el-dropdown-item :disabled=\"!canCloseCurrent\" @click=\"closeCurrentTab\">关闭当前标签</el-dropdown-item>\n <el-dropdown-item :disabled=\"!canCloseLeft\" @click=\"closeLeftTabs\">关闭左侧标签</el-dropdown-item>\n <el-dropdown-item :disabled=\"!canCloseOthers\" @click=\"closeOtherTabs\">关闭其他标签</el-dropdown-item>\n <el-dropdown-item :disabled=\"!canCloseAll\" @click=\"closeAllTabs\">关闭所有标签</el-dropdown-item>\n </el-dropdown-menu>\n </template>\n </el-dropdown>\n <slot name=\"tabs-right\" />\n </div>\n\n <!-- 内容区:router 模式渲染 RouterView,html 模式渲染默认插槽;contentKey 强制重挂载 -->\n <main class=\"wd-station__content\">\n <div :key=\"contentKey\" class=\"wd-station__content-inner\">\n <template v-if=\"isRouterMode && RouterViewComp\">\n <keep-alive v-if=\"keepAlive\"><component :is=\"RouterViewComp\" /></keep-alive>\n <component :is=\"RouterViewComp\" v-else />\n </template>\n <slot v-else />\n </div>\n </main>\n\n <!-- 底部信息栏:动态信息 + 版权(footer 插槽可整体替换) -->\n <footer class=\"wd-station__footer\">\n <slot name=\"footer\">\n <span v-if=\"displayFooterInfo\" class=\"wd-station__footer-info\">{{ displayFooterInfo }}</span>\n <span v-if=\"copyright\" class=\"wd-station__footer-copyright\">{{ copyright }}</span>\n </slot>\n </footer>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, onMounted, onUnmounted, ref, watch, type PropType } from 'vue'\nimport * as ElIcons from '@element-plus/icons-vue'\nimport { Fold, Expand, ArrowUp, ArrowDown, Refresh, Setting, Close } from '@element-plus/icons-vue'\nimport { filterProp } from '../common/props'\nimport { registerStation } from '../../lib/core/station-linkage'\nimport StationMenuNode from './StationMenuNode.vue'\nimport type { StationMenuGroup, StationTab, StationToolbarConfig } from './types'\n\ndefineOptions({ name: 'WdStation' })\n\nconst props = defineProps({\n ...filterProp,\n /** 系统标题(logo 区 / headerMode=title 时的头部标题) */\n title: { type: String, default: '' },\n /** logo 图标(@element-plus/icons-vue 名称字符串,或直接传组件) */\n logo: { type: [String, Object] as PropType<string | object>, default: '' },\n /** 分组菜单结构(优先),支持 JSON 字符串 */\n menuGroups: { type: [Array, String] as PropType<any[] | string>, default: undefined },\n /** 扁平菜单结构(带 group/groupKey 字段按出现顺序归组),支持 JSON 字符串 */\n menus: { type: [Array, String] as PropType<any[] | string>, default: undefined },\n /** 头部中央模式:nav=分导台 / title=标题(此时侧边渲染全量菜单并带组标题) */\n headerMode: { type: String as PropType<'nav' | 'title'>, default: 'nav' },\n /** 菜单位置:side=左侧 / top=顶部 / none=不启用 */\n menuMode: { type: String as PropType<'side' | 'top' | 'none'>, default: 'side' },\n /** 内容方式:page=单页 / tabs=多标签 */\n contentMode: { type: String as PropType<'page' | 'tabs'>, default: 'page' },\n /** 路由适配:auto=自动检测 $router / router / html */\n routerMode: { type: String as PropType<'auto' | 'router' | 'html'>, default: 'auto' },\n /** 是否显示折叠按钮 */\n collapsible: { type: Boolean, default: true },\n /** 折叠状态(v-model:collapsed) */\n collapsed: { type: Boolean, default: false },\n /** 当前分组 key(v-model:active-group) */\n activeGroup: { type: String, default: '' },\n /** 当前菜单 key(v-model:active-menu) */\n activeMenu: { type: String, default: '' },\n /** 已开启标签(v-model:open-tabs,受控) */\n openTabs: { type: Array as PropType<StationTab[]>, default: undefined },\n /** 用户名(有值显示用户下拉,无值显示登录按钮) */\n userName: { type: String, default: '' },\n /** 用户头像地址 */\n userAvatar: { type: String, default: '' },\n /** 版权信息 */\n copyright: { type: String, default: '' },\n /** 底部动态信息(v-model:footer-info) */\n footerInfo: { type: String, default: '' },\n /** router 模式内容区 keep-alive */\n keepAlive: { type: Boolean, default: false },\n /** 工具栏点位配置:refresh/settings/user/login 各自 left/right/none,支持 JSON 字符串 */\n toolbarConfig: { type: [Object, String] as PropType<StationToolbarConfig | string>, default: undefined }\n})\n\nconst emit = defineEmits([\n 'update:collapsed',\n 'update:active-group',\n 'update:active-menu',\n 'update:open-tabs',\n 'update:footer-info',\n 'group-change',\n 'menu-select',\n 'tab-click',\n 'tab-close',\n 'refresh',\n 'login',\n 'logout',\n 'settings'\n])\n\nconst instance = getCurrentInstance()\n\n/* ---------- 软依赖检测:vue-router / RouterView ---------- */\nconst router =\n (instance?.proxy as any)?.$router || instance?.appContext?.config?.globalProperties?.$router\nconst route =\n (instance?.proxy as any)?.$route || instance?.appContext?.config?.globalProperties?.$route\nconst RouterViewComp = instance?.appContext?.components?.['RouterView']\n\nconst isRouterMode = computed(() => {\n if (props.routerMode === 'html') return false\n if (props.routerMode === 'router') return true\n return !!router\n})\n\n/* ---------- JSON 字符串入参兼容(UMD 属性式写法) ---------- */\nfunction parseMaybeJson(val: any, fallback: any): any {\n if (val === undefined || val === null || val === '') return fallback\n if (typeof val !== 'string') return val\n try {\n return JSON.parse(val)\n } catch (e) {\n console.error('[WorkDesktop] WdStation JSON 解析失败,已回退默认值:', e)\n return fallback\n }\n}\n\n/* ---------- 菜单归一化:统一为 分组 Group → 菜单树 ---------- */\nfunction assignKeys(menus: any[], groupKey: string): any[] {\n return menus.map((m) => ({\n ...m,\n _key: m._key || `${groupKey}:${m.name || m.path || m.title}`,\n children: m.children && m.children.length ? assignKeys(m.children, groupKey) : undefined\n }))\n}\n\nfunction flatToGroups(flat: any[]): StationMenuGroup[] {\n const order: string[] = []\n const map = new Map<string, StationMenuGroup>()\n flat.forEach((m) => {\n const key = m.groupKey || m.group || 'default'\n if (!map.has(key)) {\n map.set(key, {\n key,\n title: m.group || (key === 'default' ? '默认' : key),\n icon: m.groupIcon,\n menus: []\n })\n order.push(key)\n }\n map.get(key)!.menus.push(m)\n })\n return order.map((k) => map.get(k)!)\n}\n\nlet depthWarned = false\nfunction checkMenuDepth(list: StationMenuGroup[]): void {\n if (depthWarned) return\n const walk = (menus: any[], depth: number): void => {\n menus.forEach((m) => {\n if (depth > 2 && !depthWarned) {\n depthWarned = true\n console.warn('[WorkDesktop] WdStation: 菜单层级建议不超过两层,当前已超出(仍按原样渲染)')\n }\n if (m.children && m.children.length) walk(m.children, depth + 1)\n })\n }\n list.forEach((g) => walk(g.menus, 1))\n}\n\nconst groups = computed<StationMenuGroup[]>(() => {\n const mg = parseMaybeJson(props.menuGroups, null)\n let list: StationMenuGroup[]\n if (Array.isArray(mg) && mg.length) {\n list = mg.map((g: any) => ({ key: g.key, title: g.title, icon: g.icon, menus: g.menus || [] }))\n } else {\n const flat = parseMaybeJson(props.menus, [])\n list = flatToGroups(Array.isArray(flat) ? flat : [])\n }\n // 统一分配 _key 并检查层级\n list = list.map((g) => ({ ...g, menus: assignKeys(g.menus, g.key) }))\n checkMenuDepth(list)\n return list\n})\n\n/* ---------- 分组(分导台) ---------- */\nconst innerActiveGroup = ref('')\nconst activeGroupKey = computed(\n () => props.activeGroup || innerActiveGroup.value || groups.value[0]?.key || ''\n)\nconst showNav = computed(() => props.headerMode === 'nav' && groups.value.length > 1)\nconst currentGroup = computed(\n () => groups.value.find((g) => g.key === activeGroupKey.value) || groups.value[0]\n)\nconst currentGroupMenus = computed(() => currentGroup.value?.menus || [])\n\nfunction setActiveGroup(key: string) {\n innerActiveGroup.value = key\n emit('update:active-group', key)\n const g = groups.value.find((item) => item.key === key)\n if (g) emit('group-change', { key: g.key, title: g.title })\n}\n\n/* ---------- 当前菜单 / 标签激活 ---------- */\nconst innerActiveMenu = ref('')\nwatch(\n () => props.activeMenu,\n (v) => {\n if (v) innerActiveMenu.value = v\n }\n)\nconst currentKey = computed(() => props.activeMenu || innerActiveMenu.value)\n\nfunction setActiveMenu(key: string) {\n innerActiveMenu.value = key\n emit('update:active-menu', key)\n}\n\n/* ---------- 菜单点击 ---------- */\nfunction onMenuSelect(item: any) {\n setActiveMenu(item._key)\n emit('menu-select', item)\n if (props.contentMode === 'tabs') openTab(item)\n if (isRouterMode.value && item.path) router.push(item.path)\n}\n\n/* ---------- 路由反查:按当前路径定位分组与菜单 ---------- */\nfunction walkMenus(menus: any[], fn: (m: any) => void): void {\n menus.forEach((m) => {\n fn(m)\n if (m.children && m.children.length) walkMenus(m.children, fn)\n })\n}\n\nfunction findMenuByPath(path: string): { group: StationMenuGroup; item: any } | null {\n for (const g of groups.value) {\n let found: any = null\n walkMenus(g.menus, (m) => {\n if (!found && m.path === path) found = m\n })\n if (found) return { group: g, item: found }\n }\n return null\n}\n\nwatch(\n () => route?.path,\n (path) => {\n if (!path || !isRouterMode.value) return\n const found = findMenuByPath(path)\n if (found) {\n innerActiveGroup.value = found.group.key\n setActiveMenu(found.item._key)\n }\n },\n { immediate: true }\n)\n\n/* ---------- tabs ---------- */\nconst innerTabs = ref<StationTab[]>([])\nconst isTabsControlled = computed(() => props.openTabs !== undefined)\nconst tabs = computed<StationTab[]>(() =>\n isTabsControlled.value ? (props.openTabs as StationTab[]) : innerTabs.value\n)\n\nfunction commitTabs(newTabs: StationTab[]) {\n if (!isTabsControlled.value) innerTabs.value = newTabs\n emit('update:open-tabs', newTabs)\n}\n\nfunction openTab(tab: any) {\n const key = tab._key || tab.key\n if (!key) return\n if (!tabs.value.find((t) => t.key === key)) {\n commitTabs([...tabs.value, { key, title: tab.title, path: tab.path, affix: tab.affix }])\n }\n setActiveMenu(key)\n}\n\nfunction closeTab(key: string) {\n const list = tabs.value\n const idx = list.findIndex((t) => t.key === key)\n if (idx < 0) return\n const tab = list[idx]\n if (tab.affix) return\n const newTabs = list.filter((t) => t.key !== key)\n commitTabs(newTabs)\n emit('tab-close', { ...tab })\n // 关闭激活标签 → 跳到相邻(先右后左)\n if (currentKey.value === key) {\n const next = newTabs[idx] || newTabs[idx - 1]\n if (next) setActiveMenu(next.key)\n }\n}\n\nfunction onTabClick(tab: StationTab) {\n setActiveMenu(tab.key)\n emit('tab-click', { ...tab })\n if (isRouterMode.value && tab.path) router.push(tab.path)\n}\n\n/* ---------- tabs 批量关闭(右侧下拉) ---------- */\nfunction closeTabsBy(shouldClose: (t: StationTab, i: number) => boolean) {\n const list = tabs.value\n const removed = list.filter((t, i) => shouldClose(t, i) && !t.affix)\n if (!removed.length) return\n const removedKeys = new Set(removed.map((t) => t.key))\n const kept = list.filter((t) => !removedKeys.has(t.key))\n commitTabs(kept)\n removed.forEach((t) => emit('tab-close', { ...t }))\n // 激活标签被关掉 → 跳到原位置附近(先右后左)\n if (!kept.find((t) => t.key === currentKey.value)) {\n const idx = list.findIndex((t) => t.key === currentKey.value)\n const next = kept[Math.min(idx, kept.length - 1)]\n if (next) setActiveMenu(next.key)\n }\n}\n\nfunction closeCurrentTab() {\n closeTab(currentKey.value)\n}\nfunction closeLeftTabs() {\n const idx = tabs.value.findIndex((t) => t.key === currentKey.value)\n if (idx < 0) return\n closeTabsBy((_, i) => i < idx)\n}\nfunction closeOtherTabs() {\n closeTabsBy((t) => t.key !== currentKey.value)\n}\nfunction closeAllTabs() {\n closeTabsBy(() => true)\n}\n\nconst canCloseCurrent = computed(() => {\n const cur = tabs.value.find((t) => t.key === currentKey.value)\n return !!cur && !cur.affix\n})\nconst canCloseLeft = computed(() => {\n const idx = tabs.value.findIndex((t) => t.key === currentKey.value)\n return idx > 0 && tabs.value.slice(0, idx).some((t) => !t.affix)\n})\nconst canCloseOthers = computed(() =>\n tabs.value.some((t) => !t.affix && t.key !== currentKey.value)\n)\nconst canCloseAll = computed(() => tabs.value.some((t) => !t.affix))\n\n/* ---------- 工具栏点位 ---------- */\nconst toolbarCfg = computed<Required<StationToolbarConfig>>(() => {\n const raw = parseMaybeJson(props.toolbarConfig, {}) || {}\n return {\n refresh: raw.refresh || 'right',\n settings: raw.settings || 'right',\n user: raw.user || 'right',\n login: raw.login || 'right'\n }\n})\nconst accountTool = computed(() => (props.userName ? 'user' : 'login'))\nconst toolbarLeft = computed(() => {\n const list: string[] = []\n const cfg = toolbarCfg.value\n if (cfg.refresh === 'left') list.push('refresh')\n if (cfg.settings === 'left') list.push('settings')\n if (cfg[accountTool.value as keyof StationToolbarConfig] === 'left') list.push(accountTool.value)\n return list\n})\nconst toolbarRight = computed(() => {\n const list: string[] = []\n const cfg = toolbarCfg.value\n if (cfg.refresh === 'right') list.push('refresh')\n if (cfg.settings === 'right') list.push('settings')\n if (cfg[accountTool.value as keyof StationToolbarConfig] === 'right') list.push(accountTool.value)\n return list\n})\n\nconst userInitial = computed(() => (props.userName ? props.userName.charAt(0) : ''))\n\nfunction onSettings() {\n emit('settings')\n}\nfunction onLogin() {\n emit('login')\n}\nfunction onLogout() {\n emit('logout')\n}\n\n/* ---------- 折叠 ---------- */\n// 与 activeGroup 同一模式:props 优先,未受控时走内部状态\nconst innerCollapsed = ref(false)\nconst collapsedState = computed(() => props.collapsed || innerCollapsed.value)\nfunction toggleCollapsed() {\n innerCollapsed.value = !collapsedState.value\n emit('update:collapsed', collapsedState.value)\n}\n\n/* ---------- 内容刷新(强制重挂载) ---------- */\nconst contentKey = ref(0)\nfunction refresh() {\n contentKey.value += 1\n emit('refresh')\n}\n\n/* ---------- 底部动态信息 + 联动注册 ---------- */\nconst innerFooterInfo = ref('')\nfunction setFooterInfo(info: string) {\n innerFooterInfo.value = info\n emit('update:footer-info', info)\n}\nconst displayFooterInfo = computed(() => innerFooterInfo.value || props.footerInfo)\n\nlet unregister: (() => void) | null = null\nonMounted(() => {\n unregister = registerStation({ filter: props.filter, setFooterInfo, refresh })\n // tabs 模式:affix 菜单挂载时自动开启\n if (props.contentMode === 'tabs') {\n groups.value.forEach((g) =>\n walkMenus(g.menus, (m) => {\n if (m.affix) openTab(m)\n })\n )\n }\n})\nonUnmounted(() => {\n unregister?.()\n})\n\n/* ---------- 图标归一 ---------- */\nfunction resolveIcon(icon: any) {\n if (!icon) return null\n if (typeof icon === 'string') return (ElIcons as any)[icon] || null\n return icon\n}\n\ndefineExpose({ refresh, openTab, closeTab })\n</script>\n\n<style scoped>\n.wd-station {\n display: flex;\n width: 100%;\n height: 100%;\n min-height: 0;\n background: var(--wd-bg-color-page);\n color: var(--wd-text-color-primary);\n}\n\n/* 左侧菜单栏:logo 与菜单同列同宽,菜单紧贴 logo */\n.wd-station__aside {\n width: 220px;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n background: var(--wd-bg-color);\n border-right: 1px solid var(--wd-border-color-light);\n transition: width 0.2s;\n}\n.wd-station__aside.is-collapsed {\n width: 64px;\n}\n.wd-station__logo {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 48px;\n padding: 0 16px;\n overflow: hidden;\n flex-shrink: 0;\n border-bottom: 1px solid var(--wd-border-color-light);\n}\n.wd-station__logo.is-collapsed {\n padding: 0;\n justify-content: center;\n}\n.wd-station__logo--header {\n height: auto;\n padding: 0;\n border-bottom: none;\n}\n.wd-station__logo-title {\n font-size: var(--wd-font-size-large);\n font-weight: 600;\n white-space: nowrap;\n}\n.wd-station__menu-scroll {\n flex: 1;\n min-height: 0;\n}\n.wd-station__menu {\n border-right: none;\n}\n\n/* 右侧主区 */\n.wd-station__main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n.wd-station__header {\n display: flex;\n align-items: center;\n height: 48px;\n padding: 0 var(--wd-spacing-large);\n background: var(--wd-bg-color);\n border-bottom: 1px solid var(--wd-border-color-light);\n flex-shrink: 0;\n}\n.wd-station__header-left {\n display: flex;\n align-items: center;\n gap: var(--wd-spacing-base);\n min-width: 0;\n flex-shrink: 0;\n}\n/* 中央区占满剩余空间,分导台/标题左对齐排列 */\n.wd-station__header-center {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n flex: 1;\n min-width: 0;\n padding: 0 var(--wd-spacing-base);\n}\n.wd-station__header-right {\n display: flex;\n align-items: center;\n gap: var(--wd-spacing-base);\n min-width: 0;\n flex-shrink: 0;\n justify-content: flex-end;\n}\n.wd-station__header-title {\n font-size: var(--wd-font-size-large);\n font-weight: 600;\n}\n.wd-station__collapse {\n cursor: pointer;\n font-size: 18px;\n color: var(--wd-text-color-regular);\n}\n.wd-station__collapse:hover {\n color: var(--wd-color-primary);\n}\n\n/* 分导台:流式块状分组切换条 */\n.wd-station__nav {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n.wd-station__nav-item {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 12px;\n border-radius: var(--wd-radius-base);\n cursor: pointer;\n color: var(--wd-text-color-regular);\n font-size: var(--wd-font-size-base);\n white-space: nowrap;\n}\n.wd-station__nav-item:hover {\n color: var(--wd-color-primary);\n background: var(--wd-bg-color-page);\n}\n.wd-station__nav-item.is-active {\n color: var(--wd-color-primary);\n background: var(--wd-bg-color-page);\n font-weight: 600;\n}\n\n/* 工具栏 */\n.wd-station__tool {\n cursor: pointer;\n font-size: 16px;\n color: var(--wd-text-color-regular);\n}\n.wd-station__tool:hover {\n color: var(--wd-color-primary);\n}\n.wd-station__user {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n}\n.wd-station__user-name {\n font-size: var(--wd-font-size-base);\n color: var(--wd-text-color-primary);\n}\n\n/* 顶部菜单:flex 排版,左右插槽夹住中间菜单(菜单占满剩余宽度) */\n.wd-station__top-menu {\n display: flex;\n align-items: center;\n background: var(--wd-bg-color);\n border-bottom: 1px solid var(--wd-border-color-light);\n flex-shrink: 0;\n}\n.wd-station__top-menu :deep(.el-menu) {\n flex: 1;\n min-width: 0;\n}\n\n/* tabs 条:整宽撑满,消左/上边框,右侧下拉批量关闭 */\n.wd-station__tabs-bar {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n padding-top: 4px;\n background: var(--wd-bg-color);\n border-bottom: 1px solid var(--wd-border-color-light);\n}\n.wd-station__tabs {\n flex: 1;\n min-width: 0;\n}\n.wd-station__tabs-bar :deep(.el-tabs--card > .el-tabs__header) {\n margin-bottom: 0;\n border-bottom: none;\n}\n.wd-station__tabs-bar :deep(.el-tabs--card > .el-tabs__header .el-tabs__nav) {\n border: none;\n border-radius: 0;\n}\n/* 分隔线统一放右侧:每个 tab(含最后一个)默认带右边框,tabs 区右端封闭 */\n.wd-station__tabs-bar :deep(.el-tabs--card > .el-tabs__header .el-tabs__nav .el-tabs__item) {\n border-left: none;\n border-right: 1px solid var(--wd-border-color-light);\n}\n.wd-station__tabs-actions {\n flex-shrink: 0;\n margin: 0 var(--wd-spacing-large);\n cursor: pointer;\n}\n.wd-station__tabs-more {\n display: inline-flex;\n align-items: center;\n padding: 4px;\n color: var(--wd-text-color-regular);\n}\n.wd-station__tabs-more:hover {\n color: var(--wd-color-primary);\n}\n.wd-station__tab-label {\n cursor: pointer;\n}\n.wd-station__tab-close {\n margin-left: 4px;\n font-size: 12px;\n cursor: pointer;\n}\n\n/* 内容区 */\n.wd-station__content {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: var(--wd-spacing-large);\n}\n.wd-station__content-inner {\n height: 100%;\n}\n\n/* 底部信息栏 */\n.wd-station__footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wd-spacing-base);\n height: 32px;\n padding: 0 var(--wd-spacing-large);\n background: var(--wd-bg-color);\n border-top: 1px solid var(--wd-border-color-light);\n color: var(--wd-text-color-secondary);\n font-size: var(--wd-font-size-small);\n flex-shrink: 0;\n}\n.wd-station__footer-info {\n color: var(--wd-text-color-regular);\n}\n</style>\n"],"names":["stationRegistry","groupOf","filter","registerStation","instance","key","_a","resolveTargets","target","selfFilter","targetFilter","group","setStationFooter","info","targets","count","station","e","refreshStationView","emit","__emit","resolveIcon","icon","ElIcons","onClick","item","forwardSelect","_createElementBlock","_Fragment","_renderList","__props","_createBlock","_component_el_sub_menu","_component_el_icon","_openBlock","_resolveDynamicComponent","_createElementVNode","_toDisplayString","_createVNode","_component_station_menu_node","_component_el_menu_item","$event","_component_el_badge","props","getCurrentInstance","router","_d","_c","_b","route","_e","_h","_g","_f","RouterViewComp","_j","_i","isRouterMode","computed","parseMaybeJson","val","fallback","assignKeys","menus","groupKey","m","flatToGroups","flat","order","map","k","depthWarned","checkMenuDepth","list","walk","depth","g","groups","mg","innerActiveGroup","ref","activeGroupKey","showNav","currentGroup","currentGroupMenus","setActiveGroup","innerActiveMenu","watch","v","currentKey","setActiveMenu","onMenuSelect","openTab","walkMenus","fn","findMenuByPath","path","found","innerTabs","isTabsControlled","tabs","commitTabs","newTabs","tab","t","closeTab","idx","next","onTabClick","closeTabsBy","shouldClose","removed","i","removedKeys","kept","closeCurrentTab","closeLeftTabs","_","closeOtherTabs","closeAllTabs","canCloseCurrent","cur","canCloseLeft","canCloseOthers","canCloseAll","toolbarCfg","raw","accountTool","toolbarLeft","cfg","toolbarRight","userInitial","onSettings","onLogin","onLogout","innerCollapsed","collapsedState","toggleCollapsed","contentKey","refresh","innerFooterInfo","setFooterInfo","displayFooterInfo","unregister","onMounted","onUnmounted","__expose","_normalizeClass","_renderSlot","_ctx","_withDirectives","_component_el_scrollbar","_component_el_menu","_component_el_menu_item_group","StationMenuNode","_hoisted_1","_hoisted_2","_hoisted_3","_unref","Fold","Expand","ArrowDown","ArrowUp","_hoisted_4","_hoisted_5","tool","Refresh","Setting","_component_el_dropdown","_component_el_dropdown_menu","_component_el_dropdown_item","_cache","_hoisted_6","_component_el_avatar","_hoisted_7","_component_el_button","_hoisted_8","_hoisted_9","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_component_el_tabs","_component_el_tab_pane","_hoisted_17","_withModifiers","Close","_hoisted_18","_hoisted_19","_KeepAlive","_hoisted_20","_hoisted_21","_hoisted_22"],"mappings":"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"}
1
+ {"version":3,"file":"Station-CrMTjqfa.mjs","sources":["../../src/lib/core/station-linkage.ts","../../src/components/layout/StationMenuNode.vue","../../src/components/layout/Station.vue"],"sourcesContent":["/**\n * WdStation 联动注册中心\n *\n * 复用 DataGrid linkage 的 filter 分组心智:\n * - Station 挂载时按 filter 注册;\n * - 业务代码调用 setStationFooter(target, info, selfFilter) 更新底部动态信息;\n * - refreshStationView(target, selfFilter) 触发内容区强制刷新(重新挂载)。\n *\n * target:true = 与发起方同 filter 组;字符串 = 定向该 filter 组。\n */\n\nexport interface StationInstance {\n /** 组件 filter 分组标识 */\n filter: string\n /** 设置底部动态信息 */\n setFooterInfo: (info: string) => void\n /** 刷新内容区(强制重挂载) */\n refresh: () => void\n}\n\n/** filter 分组 → Station 实例集合 */\nconst stationRegistry: Map<string, Set<StationInstance>> = new Map()\n\nfunction groupOf(filter?: string): string {\n return filter || ''\n}\n\n/**\n * 注册 Station 实例,返回注销函数(组件 onUnmounted 调用)\n */\nexport function registerStation(instance: StationInstance): () => void {\n const key = groupOf(instance.filter)\n if (!stationRegistry.has(key)) {\n stationRegistry.set(key, new Set())\n }\n stationRegistry.get(key)!.add(instance)\n return () => {\n stationRegistry.get(key)?.delete(instance)\n }\n}\n\nfunction resolveTargets(target: boolean | string | undefined, selfFilter?: string): StationInstance[] {\n if (!target) return []\n const targetFilter = typeof target === 'string' ? target : groupOf(selfFilter)\n const group = stationRegistry.get(targetFilter)\n return group ? Array.from(group) : []\n}\n\n/**\n * 设置目标 Station 底部动态信息\n * @param target true=同 filter 组;字符串=定向该 filter 组\n * @param info 展示内容(文本)\n * @param selfFilter 发起方自身 filter\n * @returns 被更新的实例数量\n */\nexport function setStationFooter(\n target: boolean | string,\n info: string,\n selfFilter?: string\n): number {\n const targets = resolveTargets(target, selfFilter)\n let count = 0\n targets.forEach((station) => {\n try {\n station.setFooterInfo(info)\n count += 1\n } catch (e) {\n console.error('[WorkDesktop] setStationFooter error:', e)\n }\n })\n return count\n}\n\n/**\n * 刷新目标 Station 内容区(强制重新挂载)\n * @param target true=同 filter 组(默认);字符串=定向该 filter 组\n * @param selfFilter 发起方自身 filter\n * @returns 被刷新的实例数量\n */\nexport function refreshStationView(\n target: boolean | string = true,\n selfFilter?: string\n): number {\n const targets = resolveTargets(target, selfFilter)\n let count = 0\n targets.forEach((station) => {\n try {\n station.refresh()\n count += 1\n } catch (e) {\n console.error('[WorkDesktop] refreshStationView error:', e)\n }\n })\n return count\n}\n\n/**\n * 仅供测试 / 调试:清空注册中心\n */\nexport function clearStationRegistry(): void {\n stationRegistry.clear()\n}\n","<template>\n <template v-for=\"item in items\" :key=\"item._key\">\n <el-sub-menu v-if=\"item.children && item.children.length\" :index=\"item._key\">\n <template #title>\n <el-icon v-if=\"resolveIcon(item.icon)\"><component :is=\"resolveIcon(item.icon)\" /></el-icon>\n <span>{{ item.title }}</span>\n </template>\n <station-menu-node :items=\"item.children\" @select=\"forwardSelect\" />\n </el-sub-menu>\n <el-menu-item v-else :index=\"item._key\" :disabled=\"item.disabled\" @click=\"onClick(item)\">\n <el-icon v-if=\"resolveIcon(item.icon)\"><component :is=\"resolveIcon(item.icon)\" /></el-icon>\n <span>{{ item.title }}</span>\n <el-badge v-if=\"item.badge !== undefined && item.badge !== ''\" :value=\"item.badge\" class=\"wd-station__menu-badge\" />\n </el-menu-item>\n </template>\n</template>\n\n<script setup lang=\"ts\">\nimport * as ElIcons from '@element-plus/icons-vue'\n\ndefineOptions({ name: 'StationMenuNode' })\n\ndefineProps({\n /** 归一化后的菜单项(带 _key) */\n items: { type: Array as () => any[], default: () => [] }\n})\n\nconst emit = defineEmits<{\n (e: 'select', item: any): void\n}>()\n\n/** 图标归一:字符串按 @element-plus/icons-vue 名称解析,组件直接用 */\nfunction resolveIcon(icon: any) {\n if (!icon) return null\n if (typeof icon === 'string') return (ElIcons as any)[icon] || null\n return icon\n}\n\nfunction onClick(item: any) {\n if (item.disabled) return\n emit('select', item)\n}\n\nfunction forwardSelect(item: any) {\n emit('select', item)\n}\n</script>\n\n<style scoped>\n/* 菜单徽章:靠右显示、垂直居中(el-menu-item 为 flex 容器,badge 为末位子元素) */\n.wd-station__menu-badge {\n /* 转 inline-flex:消除继承自 el-menu-item 的 56px line-height 行盒撑高(否则圆点沉底) */\n display: inline-flex;\n align-items: center;\n margin-left: auto;\n align-self: center;\n flex-shrink: 0;\n}\n/* 菜单折叠成窄条时隐藏徽章,避免溢出 */\n.el-menu--collapse .wd-station__menu-badge {\n display: none;\n}\n</style>\n","<template>\n <div class=\"wd-station\" :class=\"{ 'is-collapsed': collapsedState }\">\n <!-- 左侧菜单栏(menuMode=side):logo 与菜单同列,菜单紧贴 logo -->\n <aside v-if=\"menuMode === 'side'\" class=\"wd-station__aside\" :class=\"{ 'is-collapsed': collapsedState }\">\n <div class=\"wd-station__logo\" :class=\"{ 'is-collapsed': collapsedState }\">\n <slot name=\"logo\" :collapsed=\"collapsedState\">\n <el-icon v-if=\"resolveIcon(logo)\" class=\"wd-station__logo-icon\">\n <component :is=\"resolveIcon(logo)\" />\n </el-icon>\n <span v-show=\"!collapsedState\" class=\"wd-station__logo-title\">{{ title }}</span>\n </slot>\n </div>\n <slot name=\"menu-top\" :collapsed=\"collapsedState\" />\n <el-scrollbar class=\"wd-station__menu-scroll\">\n <el-menu class=\"wd-station__menu\" :collapse=\"collapsedState\" :default-active=\"currentKey\">\n <template v-if=\"headerMode === 'title'\">\n <template v-if=\"groups.length > 1\">\n <el-menu-item-group v-for=\"g in groups\" :key=\"g.key\" :title=\"g.title\">\n <station-menu-node :items=\"g.menus\" @select=\"onMenuSelect\" />\n </el-menu-item-group>\n </template>\n <!-- 单分组无分组语义,直接平铺菜单项(不渲染组标题) -->\n <station-menu-node v-else :items=\"groups[0]?.menus || []\" @select=\"onMenuSelect\" />\n </template>\n <station-menu-node v-else :items=\"currentGroupMenus\" @select=\"onMenuSelect\" />\n </el-menu>\n </el-scrollbar>\n <slot name=\"menu-bottom\" :collapsed=\"collapsedState\" />\n </aside>\n\n <div class=\"wd-station__main\">\n <header class=\"wd-station__header\">\n <div class=\"wd-station__header-left\">\n <!-- 折叠按钮:分导台左侧。side 用左右折叠图标,top 用向上折叠图标 -->\n <el-icon\n v-if=\"collapsible && menuMode !== 'none'\"\n class=\"wd-station__collapse\"\n @click=\"toggleCollapsed\"\n >\n <Fold v-if=\"menuMode === 'side' && !collapsedState\" />\n <Expand v-else-if=\"menuMode === 'side'\" />\n <ArrowUp v-else-if=\"!collapsedState\" />\n <ArrowDown v-else />\n </el-icon>\n <!-- top / none 模式 logo 进 header -->\n <div v-if=\"menuMode !== 'side'\" class=\"wd-station__logo wd-station__logo--header\">\n <slot name=\"logo\" :collapsed=\"collapsedState\">\n <el-icon v-if=\"resolveIcon(logo)\" class=\"wd-station__logo-icon\">\n <component :is=\"resolveIcon(logo)\" />\n </el-icon>\n <span class=\"wd-station__logo-title\">{{ title }}</span>\n </slot>\n </div>\n <template v-for=\"tool in toolbarLeft\" :key=\"tool\">\n <el-icon\n v-if=\"tool === 'refresh'\"\n data-tool=\"refresh\"\n class=\"wd-station__tool\"\n @click=\"refresh\"\n ><Refresh /></el-icon>\n <el-icon\n v-else-if=\"tool === 'settings'\"\n data-tool=\"settings\"\n class=\"wd-station__tool\"\n @click=\"onSettings\"\n ><Setting /></el-icon>\n <el-dropdown v-else-if=\"tool === 'user'\" data-tool=\"user\" class=\"wd-station__tool\" trigger=\"click\">\n <span class=\"wd-station__user\">\n <el-avatar :size=\"24\" :src=\"userAvatar || undefined\">{{ userInitial }}</el-avatar>\n <span class=\"wd-station__user-name\">{{ userName }}</span>\n </span>\n <template #dropdown>\n <el-dropdown-menu>\n <el-dropdown-item @click=\"onLogout\">退出登录</el-dropdown-item>\n </el-dropdown-menu>\n </template>\n </el-dropdown>\n <el-button v-else-if=\"tool === 'login'\" data-tool=\"login\" size=\"small\" @click=\"onLogin\">登录</el-button>\n </template>\n <slot name=\"header-left\" />\n </div>\n <div class=\"wd-station__header-center\">\n <!-- 分导台:流式块状分组切换条,仅多分组且 headerMode=nav 时显示 -->\n <nav v-if=\"showNav\" class=\"wd-station__nav\">\n <span\n v-for=\"g in groups\"\n :key=\"g.key\"\n class=\"wd-station__nav-item\"\n :class=\"{ 'is-active': g.key === activeGroupKey }\"\n @click=\"setActiveGroup(g.key)\"\n >\n <el-icon v-if=\"resolveIcon(g.icon)\"><component :is=\"resolveIcon(g.icon)\" /></el-icon>\n {{ g.title }}\n </span>\n </nav>\n <span v-else class=\"wd-station__header-title\">{{ title }}</span>\n <slot name=\"header-center\" />\n </div>\n <div class=\"wd-station__header-right\">\n <slot name=\"header-right\" />\n <template v-for=\"tool in toolbarRight\" :key=\"tool\">\n <el-icon\n v-if=\"tool === 'refresh'\"\n data-tool=\"refresh\"\n class=\"wd-station__tool\"\n @click=\"refresh\"\n ><Refresh /></el-icon>\n <el-icon\n v-else-if=\"tool === 'settings'\"\n data-tool=\"settings\"\n class=\"wd-station__tool\"\n @click=\"onSettings\"\n ><Setting /></el-icon>\n <el-dropdown v-else-if=\"tool === 'user'\" data-tool=\"user\" class=\"wd-station__tool\" trigger=\"click\">\n <span class=\"wd-station__user\">\n <el-avatar :size=\"24\" :src=\"userAvatar || undefined\">{{ userInitial }}</el-avatar>\n <span class=\"wd-station__user-name\">{{ userName }}</span>\n </span>\n <template #dropdown>\n <el-dropdown-menu>\n <el-dropdown-item @click=\"onLogout\">退出登录</el-dropdown-item>\n </el-dropdown-menu>\n </template>\n </el-dropdown>\n <el-button v-else-if=\"tool === 'login'\" data-tool=\"login\" size=\"small\" @click=\"onLogin\">登录</el-button>\n </template>\n </div>\n </header>\n\n <!-- 顶部菜单(menuMode=top),向上折叠时隐藏 -->\n <div v-if=\"menuMode === 'top'\" v-show=\"!collapsedState\" class=\"wd-station__top-menu\">\n <slot name=\"top-menu-left\" />\n <el-menu mode=\"horizontal\" :default-active=\"currentKey\">\n <station-menu-node :items=\"currentGroupMenus\" @select=\"onMenuSelect\" />\n </el-menu>\n <slot name=\"top-menu-right\" />\n </div>\n\n <!-- tabs 导航(contentMode=tabs):整宽撑满,右侧下拉批量关闭;自绘 label 插槽,affix 无关闭图标 -->\n <div v-if=\"contentMode === 'tabs'\" class=\"wd-station__tabs-bar\">\n <slot name=\"tabs-left\" />\n <el-tabs\n :model-value=\"currentKey\"\n type=\"card\"\n class=\"wd-station__tabs\"\n >\n <el-tab-pane v-for=\"tab in tabs\" :key=\"tab.key\" :name=\"tab.key\">\n <template #label>\n <span class=\"wd-station__tab-label\" @click=\"onTabClick(tab)\">{{ tab.title }}</span>\n <el-icon v-if=\"!tab.affix\" class=\"wd-station__tab-close\" @click.stop=\"closeTab(tab.key)\">\n <Close />\n </el-icon>\n </template>\n </el-tab-pane>\n </el-tabs>\n <el-dropdown class=\"wd-station__tabs-actions\" trigger=\"click\">\n <span class=\"wd-station__tabs-more\">\n <el-icon><ArrowDown /></el-icon>\n </span>\n <template #dropdown>\n <el-dropdown-menu>\n <el-dropdown-item :disabled=\"!canCloseCurrent\" @click=\"closeCurrentTab\">关闭当前标签</el-dropdown-item>\n <el-dropdown-item :disabled=\"!canCloseLeft\" @click=\"closeLeftTabs\">关闭左侧标签</el-dropdown-item>\n <el-dropdown-item :disabled=\"!canCloseOthers\" @click=\"closeOtherTabs\">关闭其他标签</el-dropdown-item>\n <el-dropdown-item :disabled=\"!canCloseAll\" @click=\"closeAllTabs\">关闭所有标签</el-dropdown-item>\n </el-dropdown-menu>\n </template>\n </el-dropdown>\n <slot name=\"tabs-right\" />\n </div>\n\n <!-- 内容区:router 模式渲染 RouterView,html 模式渲染默认插槽;contentKey 强制重挂载 -->\n <main class=\"wd-station__content\">\n <div :key=\"contentKey\" class=\"wd-station__content-inner\">\n <template v-if=\"isRouterMode && RouterViewComp\">\n <keep-alive v-if=\"keepAlive\"><component :is=\"RouterViewComp\" /></keep-alive>\n <component :is=\"RouterViewComp\" v-else />\n </template>\n <slot v-else />\n </div>\n </main>\n\n <!-- 底部信息栏:动态信息 + 版权(footer 插槽可整体替换) -->\n <footer class=\"wd-station__footer\">\n <slot name=\"footer\">\n <span v-if=\"displayFooterInfo\" class=\"wd-station__footer-info\">{{ displayFooterInfo }}</span>\n <span v-if=\"copyright\" class=\"wd-station__footer-copyright\">{{ copyright }}</span>\n </slot>\n </footer>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, onMounted, onUnmounted, ref, watch, type PropType } from 'vue'\nimport * as ElIcons from '@element-plus/icons-vue'\nimport { Fold, Expand, ArrowUp, ArrowDown, Refresh, Setting, Close } from '@element-plus/icons-vue'\nimport { filterProp } from '../common/props'\nimport { registerStation } from '../../lib/core/station-linkage'\nimport StationMenuNode from './StationMenuNode.vue'\nimport type { StationMenuGroup, StationTab, StationToolbarConfig } from './types'\n\ndefineOptions({ name: 'WdStation' })\n\nconst props = defineProps({\n ...filterProp,\n /** 系统标题(logo 区 / headerMode=title 时的头部标题) */\n title: { type: String, default: '' },\n /** logo 图标(@element-plus/icons-vue 名称字符串,或直接传组件) */\n logo: { type: [String, Object] as PropType<string | object>, default: '' },\n /** 分组菜单结构(优先),支持 JSON 字符串 */\n menuGroups: { type: [Array, String] as PropType<any[] | string>, default: undefined },\n /** 扁平菜单结构(带 group/groupKey 字段按出现顺序归组),支持 JSON 字符串 */\n menus: { type: [Array, String] as PropType<any[] | string>, default: undefined },\n /** 头部中央模式:nav=分导台 / title=标题(此时侧边渲染全量菜单并带组标题) */\n headerMode: { type: String as PropType<'nav' | 'title'>, default: 'nav' },\n /** 菜单位置:side=左侧 / top=顶部 / none=不启用 */\n menuMode: { type: String as PropType<'side' | 'top' | 'none'>, default: 'side' },\n /** 内容方式:page=单页 / tabs=多标签 */\n contentMode: { type: String as PropType<'page' | 'tabs'>, default: 'page' },\n /** 路由适配:auto=自动检测 $router / router / html */\n routerMode: { type: String as PropType<'auto' | 'router' | 'html'>, default: 'auto' },\n /** 是否显示折叠按钮 */\n collapsible: { type: Boolean, default: true },\n /** 折叠状态(v-model:collapsed) */\n collapsed: { type: Boolean, default: false },\n /** 当前分组 key(v-model:active-group) */\n activeGroup: { type: String, default: '' },\n /** 当前菜单 key(v-model:active-menu) */\n activeMenu: { type: String, default: '' },\n /** 已开启标签(v-model:open-tabs,受控) */\n openTabs: { type: Array as PropType<StationTab[]>, default: undefined },\n /** 用户名(有值显示用户下拉,无值显示登录按钮) */\n userName: { type: String, default: '' },\n /** 用户头像地址 */\n userAvatar: { type: String, default: '' },\n /** 版权信息 */\n copyright: { type: String, default: '' },\n /** 底部动态信息(v-model:footer-info) */\n footerInfo: { type: String, default: '' },\n /** router 模式内容区 keep-alive */\n keepAlive: { type: Boolean, default: false },\n /** 工具栏点位配置:refresh/settings/user/login 各自 left/right/none,支持 JSON 字符串 */\n toolbarConfig: { type: [Object, String] as PropType<StationToolbarConfig | string>, default: undefined }\n})\n\nconst emit = defineEmits([\n 'update:collapsed',\n 'update:active-group',\n 'update:active-menu',\n 'update:open-tabs',\n 'update:footer-info',\n 'group-change',\n 'menu-select',\n 'tab-click',\n 'tab-close',\n 'refresh',\n 'login',\n 'logout',\n 'settings'\n])\n\nconst instance = getCurrentInstance()\n\n/* ---------- 软依赖检测:vue-router / RouterView ---------- */\nconst router =\n (instance?.proxy as any)?.$router || instance?.appContext?.config?.globalProperties?.$router\nconst route =\n (instance?.proxy as any)?.$route || instance?.appContext?.config?.globalProperties?.$route\nconst RouterViewComp = instance?.appContext?.components?.['RouterView']\n\nconst isRouterMode = computed(() => {\n if (props.routerMode === 'html') return false\n if (props.routerMode === 'router') return true\n return !!router\n})\n\n/* ---------- JSON 字符串入参兼容(UMD 属性式写法) ---------- */\nfunction parseMaybeJson(val: any, fallback: any): any {\n if (val === undefined || val === null || val === '') return fallback\n if (typeof val !== 'string') return val\n try {\n return JSON.parse(val)\n } catch (e) {\n console.error('[WorkDesktop] WdStation JSON 解析失败,已回退默认值:', e)\n return fallback\n }\n}\n\n/* ---------- 菜单归一化:统一为 分组 Group → 菜单树 ---------- */\nfunction assignKeys(menus: any[], groupKey: string): any[] {\n return menus.map((m) => ({\n ...m,\n _key: m._key || `${groupKey}:${m.name || m.path || m.title}`,\n children: m.children && m.children.length ? assignKeys(m.children, groupKey) : undefined\n }))\n}\n\nfunction flatToGroups(flat: any[]): StationMenuGroup[] {\n const order: string[] = []\n const map = new Map<string, StationMenuGroup>()\n flat.forEach((m) => {\n const key = m.groupKey || m.group || 'default'\n if (!map.has(key)) {\n map.set(key, {\n key,\n title: m.group || (key === 'default' ? '默认' : key),\n icon: m.groupIcon,\n menus: []\n })\n order.push(key)\n }\n map.get(key)!.menus.push(m)\n })\n return order.map((k) => map.get(k)!)\n}\n\nlet depthWarned = false\nfunction checkMenuDepth(list: StationMenuGroup[]): void {\n if (depthWarned) return\n const walk = (menus: any[], depth: number): void => {\n menus.forEach((m) => {\n if (depth > 2 && !depthWarned) {\n depthWarned = true\n console.warn('[WorkDesktop] WdStation: 菜单层级建议不超过两层,当前已超出(仍按原样渲染)')\n }\n if (m.children && m.children.length) walk(m.children, depth + 1)\n })\n }\n list.forEach((g) => walk(g.menus, 1))\n}\n\nconst groups = computed<StationMenuGroup[]>(() => {\n const mg = parseMaybeJson(props.menuGroups, null)\n let list: StationMenuGroup[]\n if (Array.isArray(mg) && mg.length) {\n list = mg.map((g: any) => ({ key: g.key, title: g.title, icon: g.icon, menus: g.menus || [] }))\n } else {\n const flat = parseMaybeJson(props.menus, [])\n list = flatToGroups(Array.isArray(flat) ? flat : [])\n }\n // 统一分配 _key 并检查层级\n list = list.map((g) => ({ ...g, menus: assignKeys(g.menus, g.key) }))\n checkMenuDepth(list)\n return list\n})\n\n/* ---------- 分组(分导台) ---------- */\nconst innerActiveGroup = ref('')\nconst activeGroupKey = computed(\n () => props.activeGroup || innerActiveGroup.value || groups.value[0]?.key || ''\n)\nconst showNav = computed(() => props.headerMode === 'nav' && groups.value.length > 1)\nconst currentGroup = computed(\n () => groups.value.find((g) => g.key === activeGroupKey.value) || groups.value[0]\n)\nconst currentGroupMenus = computed(() => currentGroup.value?.menus || [])\n\nfunction setActiveGroup(key: string) {\n innerActiveGroup.value = key\n emit('update:active-group', key)\n const g = groups.value.find((item) => item.key === key)\n if (g) emit('group-change', { key: g.key, title: g.title })\n}\n\n/* ---------- 当前菜单 / 标签激活 ---------- */\nconst innerActiveMenu = ref('')\nwatch(\n () => props.activeMenu,\n (v) => {\n if (v) innerActiveMenu.value = v\n }\n)\nconst currentKey = computed(() => props.activeMenu || innerActiveMenu.value)\n\nfunction setActiveMenu(key: string) {\n innerActiveMenu.value = key\n emit('update:active-menu', key)\n}\n\n/* ---------- 菜单点击 ---------- */\nfunction onMenuSelect(item: any) {\n setActiveMenu(item._key)\n emit('menu-select', item)\n if (props.contentMode === 'tabs') openTab(item)\n if (isRouterMode.value && item.path) router.push(item.path)\n}\n\n/* ---------- 路由反查:按当前路径定位分组与菜单 ---------- */\nfunction walkMenus(menus: any[], fn: (m: any) => void): void {\n menus.forEach((m) => {\n fn(m)\n if (m.children && m.children.length) walkMenus(m.children, fn)\n })\n}\n\nfunction findMenuByPath(path: string): { group: StationMenuGroup; item: any } | null {\n for (const g of groups.value) {\n let found: any = null\n walkMenus(g.menus, (m) => {\n if (!found && m.path === path) found = m\n })\n if (found) return { group: g, item: found }\n }\n return null\n}\n\nwatch(\n () => route?.path,\n (path) => {\n if (!path || !isRouterMode.value) return\n const found = findMenuByPath(path)\n if (found) {\n innerActiveGroup.value = found.group.key\n setActiveMenu(found.item._key)\n }\n },\n { immediate: true }\n)\n\n/* ---------- tabs ---------- */\nconst innerTabs = ref<StationTab[]>([])\nconst isTabsControlled = computed(() => props.openTabs !== undefined)\nconst tabs = computed<StationTab[]>(() =>\n isTabsControlled.value ? (props.openTabs as StationTab[]) : innerTabs.value\n)\n\nfunction commitTabs(newTabs: StationTab[]) {\n if (!isTabsControlled.value) innerTabs.value = newTabs\n emit('update:open-tabs', newTabs)\n}\n\nfunction openTab(tab: any) {\n const key = tab._key || tab.key\n if (!key) return\n if (!tabs.value.find((t) => t.key === key)) {\n commitTabs([...tabs.value, { key, title: tab.title, path: tab.path, affix: tab.affix }])\n }\n setActiveMenu(key)\n}\n\nfunction closeTab(key: string) {\n const list = tabs.value\n const idx = list.findIndex((t) => t.key === key)\n if (idx < 0) return\n const tab = list[idx]\n if (tab.affix) return\n const newTabs = list.filter((t) => t.key !== key)\n commitTabs(newTabs)\n emit('tab-close', { ...tab })\n // 关闭激活标签 → 跳到相邻(先右后左)\n if (currentKey.value === key) {\n const next = newTabs[idx] || newTabs[idx - 1]\n if (next) setActiveMenu(next.key)\n }\n}\n\nfunction onTabClick(tab: StationTab) {\n setActiveMenu(tab.key)\n emit('tab-click', { ...tab })\n if (isRouterMode.value && tab.path) router.push(tab.path)\n}\n\n/* ---------- tabs 批量关闭(右侧下拉) ---------- */\nfunction closeTabsBy(shouldClose: (t: StationTab, i: number) => boolean) {\n const list = tabs.value\n const removed = list.filter((t, i) => shouldClose(t, i) && !t.affix)\n if (!removed.length) return\n const removedKeys = new Set(removed.map((t) => t.key))\n const kept = list.filter((t) => !removedKeys.has(t.key))\n commitTabs(kept)\n removed.forEach((t) => emit('tab-close', { ...t }))\n // 激活标签被关掉 → 跳到原位置附近(先右后左)\n if (!kept.find((t) => t.key === currentKey.value)) {\n const idx = list.findIndex((t) => t.key === currentKey.value)\n const next = kept[Math.min(idx, kept.length - 1)]\n if (next) setActiveMenu(next.key)\n }\n}\n\nfunction closeCurrentTab() {\n closeTab(currentKey.value)\n}\nfunction closeLeftTabs() {\n const idx = tabs.value.findIndex((t) => t.key === currentKey.value)\n if (idx < 0) return\n closeTabsBy((_, i) => i < idx)\n}\nfunction closeOtherTabs() {\n closeTabsBy((t) => t.key !== currentKey.value)\n}\nfunction closeAllTabs() {\n closeTabsBy(() => true)\n}\n\nconst canCloseCurrent = computed(() => {\n const cur = tabs.value.find((t) => t.key === currentKey.value)\n return !!cur && !cur.affix\n})\nconst canCloseLeft = computed(() => {\n const idx = tabs.value.findIndex((t) => t.key === currentKey.value)\n return idx > 0 && tabs.value.slice(0, idx).some((t) => !t.affix)\n})\nconst canCloseOthers = computed(() =>\n tabs.value.some((t) => !t.affix && t.key !== currentKey.value)\n)\nconst canCloseAll = computed(() => tabs.value.some((t) => !t.affix))\n\n/* ---------- 工具栏点位 ---------- */\nconst toolbarCfg = computed<Required<StationToolbarConfig>>(() => {\n const raw = parseMaybeJson(props.toolbarConfig, {}) || {}\n return {\n refresh: raw.refresh || 'right',\n settings: raw.settings || 'right',\n user: raw.user || 'right',\n login: raw.login || 'right'\n }\n})\nconst accountTool = computed(() => (props.userName ? 'user' : 'login'))\nconst toolbarLeft = computed(() => {\n const list: string[] = []\n const cfg = toolbarCfg.value\n if (cfg.refresh === 'left') list.push('refresh')\n if (cfg.settings === 'left') list.push('settings')\n if (cfg[accountTool.value as keyof StationToolbarConfig] === 'left') list.push(accountTool.value)\n return list\n})\nconst toolbarRight = computed(() => {\n const list: string[] = []\n const cfg = toolbarCfg.value\n if (cfg.refresh === 'right') list.push('refresh')\n if (cfg.settings === 'right') list.push('settings')\n if (cfg[accountTool.value as keyof StationToolbarConfig] === 'right') list.push(accountTool.value)\n return list\n})\n\nconst userInitial = computed(() => (props.userName ? props.userName.charAt(0) : ''))\n\nfunction onSettings() {\n emit('settings')\n}\nfunction onLogin() {\n emit('login')\n}\nfunction onLogout() {\n emit('logout')\n}\n\n/* ---------- 折叠 ---------- */\n// 与 activeGroup 同一模式:props 优先,未受控时走内部状态\nconst innerCollapsed = ref(false)\nconst collapsedState = computed(() => props.collapsed || innerCollapsed.value)\nfunction toggleCollapsed() {\n innerCollapsed.value = !collapsedState.value\n emit('update:collapsed', collapsedState.value)\n}\n\n/* ---------- 内容刷新(强制重挂载) ---------- */\nconst contentKey = ref(0)\nfunction refresh() {\n contentKey.value += 1\n emit('refresh')\n}\n\n/* ---------- 底部动态信息 + 联动注册 ---------- */\nconst innerFooterInfo = ref('')\nfunction setFooterInfo(info: string) {\n innerFooterInfo.value = info\n emit('update:footer-info', info)\n}\nconst displayFooterInfo = computed(() => innerFooterInfo.value || props.footerInfo)\n\nlet unregister: (() => void) | null = null\nonMounted(() => {\n unregister = registerStation({ filter: props.filter, setFooterInfo, refresh })\n // tabs 模式:affix 菜单挂载时自动开启\n if (props.contentMode === 'tabs') {\n groups.value.forEach((g) =>\n walkMenus(g.menus, (m) => {\n if (m.affix) openTab(m)\n })\n )\n }\n})\nonUnmounted(() => {\n unregister?.()\n})\n\n/* ---------- 图标归一 ---------- */\nfunction resolveIcon(icon: any) {\n if (!icon) return null\n if (typeof icon === 'string') return (ElIcons as any)[icon] || null\n return icon\n}\n\ndefineExpose({ refresh, openTab, closeTab })\n</script>\n\n<style scoped>\n.wd-station {\n display: flex;\n width: 100%;\n height: 100%;\n min-height: 0;\n background: var(--wd-bg-color-page);\n color: var(--wd-text-color-primary);\n}\n\n/* 左侧菜单栏:logo 与菜单同列同宽,菜单紧贴 logo */\n.wd-station__aside {\n width: 220px;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n /* 组件级令牌回退链:皮肤可单独定制导航区背景 */\n background: var(--wd-station-aside-bg, var(--wd-bg-color));\n /* 背景素材:皮肤可挂纹理/图片(须置于 background 简写之后,否则被简写重置) */\n background-image: var(--wd-station-aside-bg-image, none);\n border-right: var(--wd-border-width, 1px) var(--wd-border-style, solid) var(--wd-border-color-light);\n transition: width 0.2s;\n}\n.wd-station__aside.is-collapsed {\n width: 64px;\n}\n.wd-station__logo {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 48px;\n padding: 0 var(--wd-spacing-large, 16px);\n overflow: hidden;\n flex-shrink: 0;\n border-bottom: var(--wd-border-width, 1px) var(--wd-border-style, solid) var(--wd-border-color-light);\n}\n.wd-station__logo.is-collapsed {\n padding: 0;\n justify-content: center;\n}\n.wd-station__logo--header {\n height: auto;\n padding: 0;\n border-bottom: none;\n}\n.wd-station__logo-title {\n font-size: var(--wd-font-size-large);\n font-weight: 600;\n white-space: nowrap;\n}\n.wd-station__menu-scroll {\n flex: 1;\n min-height: 0;\n}\n.wd-station__menu {\n border-right: none;\n}\n\n/* 右侧主区 */\n.wd-station__main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n.wd-station__header {\n display: flex;\n align-items: center;\n height: 48px;\n padding: 0 var(--wd-spacing-large);\n background: var(--wd-station-header-bg, var(--wd-bg-color));\n /* 背景素材:皮肤可挂纹理/图片(须置于 background 简写之后,否则被简写重置) */\n background-image: var(--wd-station-header-bg-image, none);\n border-bottom: var(--wd-border-width, 1px) var(--wd-border-style, solid) var(--wd-border-color-light);\n flex-shrink: 0;\n}\n.wd-station__header-left {\n display: flex;\n align-items: center;\n gap: var(--wd-spacing-base);\n min-width: 0;\n flex-shrink: 0;\n}\n/* 中央区占满剩余空间,分导台/标题左对齐排列 */\n.wd-station__header-center {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n flex: 1;\n min-width: 0;\n padding: 0 var(--wd-spacing-base);\n}\n.wd-station__header-right {\n display: flex;\n align-items: center;\n gap: var(--wd-spacing-base);\n min-width: 0;\n flex-shrink: 0;\n justify-content: flex-end;\n}\n.wd-station__header-title {\n font-size: var(--wd-font-size-large);\n font-weight: 600;\n}\n.wd-station__collapse {\n cursor: pointer;\n font-size: 18px;\n color: var(--wd-text-color-regular);\n}\n.wd-station__collapse:hover {\n color: var(--wd-color-primary);\n}\n\n/* 分导台:流式块状分组切换条 */\n.wd-station__nav {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 4px;\n}\n.wd-station__nav-item {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 12px;\n border-radius: var(--wd-radius-base);\n cursor: pointer;\n color: var(--wd-text-color-regular);\n font-size: var(--wd-font-size-base);\n white-space: nowrap;\n}\n.wd-station__nav-item:hover {\n color: var(--wd-color-primary);\n background: var(--wd-bg-color-page);\n}\n.wd-station__nav-item.is-active {\n color: var(--wd-color-primary);\n background: var(--wd-bg-color-page);\n font-weight: 600;\n}\n\n/* 工具栏 */\n.wd-station__tool {\n cursor: pointer;\n font-size: 16px;\n color: var(--wd-text-color-regular);\n}\n.wd-station__tool:hover {\n color: var(--wd-color-primary);\n}\n.wd-station__user {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n}\n.wd-station__user-name {\n font-size: var(--wd-font-size-base);\n color: var(--wd-text-color-primary);\n}\n\n/* 顶部菜单:flex 排版,左右插槽夹住中间菜单(菜单占满剩余宽度) */\n.wd-station__top-menu {\n display: flex;\n align-items: center;\n background: var(--wd-bg-color);\n border-bottom: var(--wd-border-width, 1px) var(--wd-border-style, solid) var(--wd-border-color-light);\n flex-shrink: 0;\n}\n.wd-station__top-menu :deep(.el-menu) {\n flex: 1;\n min-width: 0;\n}\n\n/* tabs 条:整宽撑满,消左/上边框,右侧下拉批量关闭 */\n.wd-station__tabs-bar {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n padding-top: 4px;\n background: var(--wd-station-tabs-bg, var(--wd-bg-color));\n /* 背景素材:皮肤可挂纹理/图片(须置于 background 简写之后,否则被简写重置) */\n background-image: var(--wd-station-tabs-bg-image, none);\n border-bottom: var(--wd-border-width, 1px) var(--wd-border-style, solid) var(--wd-border-color-light);\n}\n.wd-station__tabs {\n flex: 1;\n min-width: 0;\n}\n.wd-station__tabs-bar :deep(.el-tabs--card > .el-tabs__header) {\n margin-bottom: 0;\n border-bottom: none;\n}\n.wd-station__tabs-bar :deep(.el-tabs--card > .el-tabs__header .el-tabs__nav) {\n border: none;\n border-radius: 0;\n}\n/* 分隔线统一放右侧:每个 tab(含最后一个)默认带右边框,tabs 区右端封闭 */\n.wd-station__tabs-bar :deep(.el-tabs--card > .el-tabs__header .el-tabs__nav .el-tabs__item) {\n border-left: none;\n border-right: var(--wd-border-width, 1px) var(--wd-border-style, solid) var(--wd-border-color-light);\n}\n.wd-station__tabs-actions {\n flex-shrink: 0;\n margin: 0 var(--wd-spacing-large);\n cursor: pointer;\n}\n.wd-station__tabs-more {\n display: inline-flex;\n align-items: center;\n padding: 4px;\n color: var(--wd-text-color-regular);\n}\n.wd-station__tabs-more:hover {\n color: var(--wd-color-primary);\n}\n.wd-station__tab-label {\n cursor: pointer;\n}\n.wd-station__tab-close {\n margin-left: 4px;\n font-size: 12px;\n cursor: pointer;\n}\n\n/* 内容区 */\n.wd-station__content {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: var(--wd-spacing-large);\n}\n.wd-station__content-inner {\n height: 100%;\n}\n\n/* 底部信息栏 */\n.wd-station__footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--wd-spacing-base);\n height: 32px;\n padding: 0 var(--wd-spacing-large);\n background: var(--wd-bg-color);\n border-top: var(--wd-border-width, 1px) var(--wd-border-style, solid) var(--wd-border-color-light);\n color: var(--wd-text-color-secondary);\n font-size: var(--wd-font-size-small);\n flex-shrink: 0;\n}\n.wd-station__footer-info {\n color: var(--wd-text-color-regular);\n}\n</style>\n"],"names":["stationRegistry","groupOf","filter","registerStation","instance","key","_a","resolveTargets","target","selfFilter","targetFilter","group","setStationFooter","info","targets","count","station","e","refreshStationView","emit","__emit","resolveIcon","icon","ElIcons","onClick","item","forwardSelect","_createElementBlock","_Fragment","_renderList","__props","_createBlock","_component_el_sub_menu","_component_el_icon","_openBlock","_resolveDynamicComponent","_createElementVNode","_toDisplayString","_createVNode","_component_station_menu_node","_component_el_menu_item","$event","_component_el_badge","props","getCurrentInstance","router","_d","_c","_b","route","_e","_h","_g","_f","RouterViewComp","_j","_i","isRouterMode","computed","parseMaybeJson","val","fallback","assignKeys","menus","groupKey","m","flatToGroups","flat","order","map","k","depthWarned","checkMenuDepth","list","walk","depth","g","groups","mg","innerActiveGroup","ref","activeGroupKey","showNav","currentGroup","currentGroupMenus","setActiveGroup","innerActiveMenu","watch","v","currentKey","setActiveMenu","onMenuSelect","openTab","walkMenus","fn","findMenuByPath","path","found","innerTabs","isTabsControlled","tabs","commitTabs","newTabs","tab","t","closeTab","idx","next","onTabClick","closeTabsBy","shouldClose","removed","i","removedKeys","kept","closeCurrentTab","closeLeftTabs","_","closeOtherTabs","closeAllTabs","canCloseCurrent","cur","canCloseLeft","canCloseOthers","canCloseAll","toolbarCfg","raw","accountTool","toolbarLeft","cfg","toolbarRight","userInitial","onSettings","onLogin","onLogout","innerCollapsed","collapsedState","toggleCollapsed","contentKey","refresh","innerFooterInfo","setFooterInfo","displayFooterInfo","unregister","onMounted","onUnmounted","__expose","_normalizeClass","_renderSlot","_ctx","_withDirectives","_component_el_scrollbar","_component_el_menu","_component_el_menu_item_group","StationMenuNode","_hoisted_1","_hoisted_2","_hoisted_3","_unref","Fold","Expand","ArrowDown","ArrowUp","_hoisted_4","_hoisted_5","tool","Refresh","Setting","_component_el_dropdown","_component_el_dropdown_menu","_component_el_dropdown_item","_cache","_hoisted_6","_component_el_avatar","_hoisted_7","_component_el_button","_hoisted_8","_hoisted_9","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_component_el_tabs","_component_el_tab_pane","_hoisted_17","_withModifiers","Close","_hoisted_18","_hoisted_19","_KeepAlive","_hoisted_20","_hoisted_21","_hoisted_22"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as V, ref as h, computed as y, resolveComponent as p, openBlock as d, createBlock as m, withCtx as S, createVNode as w, mergeProps as f } from "vue";
2
- import { r as v } from "./http-DUPsbs2K.mjs";
2
+ import { r as v } from "./http-9ToPNkWJ.mjs";
3
3
  import { r as B } from "./linkage-FbL1mcz3.mjs";
4
4
  import { a as A, h as P, f as k } from "./props-DAytpx7D.mjs";
5
5
  const x = /* @__PURE__ */ V({
@@ -68,4 +68,4 @@ const x = /* @__PURE__ */ V({
68
68
  export {
69
69
  x as _
70
70
  };
71
- //# sourceMappingURL=Switch.vue_vue_type_script_setup_true_lang-CCU_d3jW.mjs.map
71
+ //# sourceMappingURL=Switch.vue_vue_type_script_setup_true_lang-BxJdsReQ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.vue_vue_type_script_setup_true_lang-CCU_d3jW.mjs","sources":["../../src/components/inputs/Switch.vue"],"sourcesContent":["<template>\n <el-tooltip v-if=\"tips\" :content=\"tips\" placement=\"top\">\n <el-switch\n v-model=\"inner\"\n :active-value=\"activeValue\"\n :inactive-value=\"inactiveValue\"\n :loading=\"loading\"\n v-bind=\"$attrs\"\n @change=\"onChange\"\n />\n </el-tooltip>\n <el-switch\n v-else\n v-model=\"inner\"\n :active-value=\"activeValue\"\n :inactive-value=\"inactiveValue\"\n :loading=\"loading\"\n v-bind=\"$attrs\"\n @change=\"onChange\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { request } from '../../lib/core/http'\nimport { refreshDataGrid } from '../../lib/core/linkage'\nimport { filterProp, headRefreshDatagridProp, apiProps } from '../common/props'\nimport type { PropType } from 'vue'\n\ndefineOptions({ name: 'WdSwitch', inheritAttrs: false })\n\nconst props = defineProps({\n ...filterProp,\n ...headRefreshDatagridProp,\n ...apiProps,\n modelValue: { type: [String, Number, Boolean] as PropType<any>, default: false },\n /** 悬停提示 */\n tips: { type: String, default: '' },\n /** 提交参数的字段名 */\n paramKey: { type: String, default: 'status' },\n activeValue: { type: [String, Number, Boolean], default: true },\n inactiveValue: { type: [String, Number, Boolean], default: false }\n})\n\nconst emit = defineEmits(['update:modelValue', 'change', 'apiBefore', 'apiSuccess', 'apiFail', 'apiException', 'apiAfter'])\n\nconst loading = ref(false)\n\nconst inner = computed({\n get: () => props.modelValue,\n set: (val) => emit('update:modelValue', val)\n})\n\nasync function onChange(val: any) {\n emit('change', val)\n if (!props.api) return\n\n // 记录旧值,失败回滚\n const oldVal = val === props.activeValue ? props.inactiveValue : props.activeValue\n loading.value = true\n emit('apiBefore', { url: props.api })\n try {\n const param = { ...props.apiParam, [props.paramKey]: val }\n const result =\n props.apiMethod === 'get'\n ? await request.get(props.api, param)\n : await request.post(props.api, param)\n if (result.success) {\n emit('apiSuccess', { data: result.data })\n if (props.headRefreshDatagrid) {\n refreshDataGrid(props.headRefreshDatagrid, props.filter)\n }\n emit('apiAfter', { data: result.data })\n } else {\n // 业务失败:回滚状态\n emit('update:modelValue', oldVal)\n emit('apiFail', { code: result.code, message: result.message })\n emit('apiAfter', { code: result.code })\n }\n } catch (error: any) {\n // 网络异常:回滚状态\n emit('update:modelValue', oldVal)\n emit('apiException', { error, message: error?.message })\n emit('apiAfter', { error })\n } finally {\n loading.value = false\n }\n}\n</script>\n"],"names":["props","__props","emit","__emit","loading","ref","inner","computed","val","onChange","oldVal","param","result","request","refreshDataGrid","error","_createBlock","_component_el_tooltip","_createVNode","_component_el_switch","_mergeProps","$event","$attrs","_openBlock"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA+BA,UAAMA,IAAQC,GAaRC,IAAOC,GAEPC,IAAUC,EAAI,EAAK,GAEnBC,IAAQC,EAAS;AAAA,MACrB,KAAK,MAAMP,EAAM;AAAA,MACjB,KAAK,CAACQ,MAAQN,EAAK,qBAAqBM,CAAG;AAAA,IAAA,CAC5C;AAED,mBAAeC,EAASD,GAAU;AAEhC,UADAN,EAAK,UAAUM,CAAG,GACd,CAACR,EAAM,IAAK;AAGhB,YAAMU,IAASF,MAAQR,EAAM,cAAcA,EAAM,gBAAgBA,EAAM;AACvE,MAAAI,EAAQ,QAAQ,IAChBF,EAAK,aAAa,EAAE,KAAKF,EAAM,KAAK;AACpC,UAAI;AACF,cAAMW,IAAQ,EAAE,GAAGX,EAAM,UAAU,CAACA,EAAM,QAAQ,GAAGQ,EAAA,GAC/CI,IACJZ,EAAM,cAAc,QAChB,MAAMa,EAAQ,IAAIb,EAAM,KAAKW,CAAK,IAClC,MAAME,EAAQ,KAAKb,EAAM,KAAKW,CAAK;AACzC,QAAIC,EAAO,WACTV,EAAK,cAAc,EAAE,MAAMU,EAAO,MAAM,GACpCZ,EAAM,uBACRc,EAAgBd,EAAM,qBAAqBA,EAAM,MAAM,GAEzDE,EAAK,YAAY,EAAE,MAAMU,EAAO,MAAM,MAGtCV,EAAK,qBAAqBQ,CAAM,GAChCR,EAAK,WAAW,EAAE,MAAMU,EAAO,MAAM,SAASA,EAAO,SAAS,GAC9DV,EAAK,YAAY,EAAE,MAAMU,EAAO,MAAM;AAAA,MAE1C,SAASG,GAAY;AAEnB,QAAAb,EAAK,qBAAqBQ,CAAM,GAChCR,EAAK,gBAAgB,EAAE,OAAAa,GAAO,SAASA,KAAA,gBAAAA,EAAO,SAAS,GACvDb,EAAK,YAAY,EAAE,OAAAa,GAAO;AAAA,MAC5B,UAAA;AACE,QAAAX,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;;;aAtFoBH,EAAA,aAAlBe,EASaC,GAAA;AAAA;QATY,SAAShB,EAAA;AAAA,QAAM,WAAU;AAAA,MAAA;mBAChD,MAOE;AAAA,UAPFiB,EAOEC,GAPFC,EAOE;AAAA,wBANSd,EAAA;AAAA,0DAAAA,EAAK,QAAAe;AAAA,YACb,gBAAcpB,EAAA;AAAA,YACd,kBAAgBA,EAAA;AAAA,YAChB,SAASG,EAAA;AAAA,UAAA,GACFkB,EAAAA,QAAM,EACb,UAAAb,GAAgB,GAAA,MAAA,IAAA,CAAA,cAAA,gBAAA,kBAAA,SAAA,CAAA;AAAA,QAAA;;6BAGrBc,EAAA,GAAAP,EAQEG,GARFC,EAQE;AAAA;oBANSd,EAAA;AAAA,sDAAAA,EAAK,QAAAe;AAAA,QACb,gBAAcpB,EAAA;AAAA,QACd,kBAAgBA,EAAA;AAAA,QAChB,SAASG,EAAA;AAAA,MAAA,GACFkB,EAAAA,QAAM,EACb,UAAAb,GAAgB,GAAA,MAAA,IAAA,CAAA,cAAA,gBAAA,kBAAA,SAAA,CAAA;AAAA;;;"}
1
+ {"version":3,"file":"Switch.vue_vue_type_script_setup_true_lang-BxJdsReQ.mjs","sources":["../../src/components/inputs/Switch.vue"],"sourcesContent":["<template>\n <el-tooltip v-if=\"tips\" :content=\"tips\" placement=\"top\">\n <el-switch\n v-model=\"inner\"\n :active-value=\"activeValue\"\n :inactive-value=\"inactiveValue\"\n :loading=\"loading\"\n v-bind=\"$attrs\"\n @change=\"onChange\"\n />\n </el-tooltip>\n <el-switch\n v-else\n v-model=\"inner\"\n :active-value=\"activeValue\"\n :inactive-value=\"inactiveValue\"\n :loading=\"loading\"\n v-bind=\"$attrs\"\n @change=\"onChange\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { request } from '../../lib/core/http'\nimport { refreshDataGrid } from '../../lib/core/linkage'\nimport { filterProp, headRefreshDatagridProp, apiProps } from '../common/props'\nimport type { PropType } from 'vue'\n\ndefineOptions({ name: 'WdSwitch', inheritAttrs: false })\n\nconst props = defineProps({\n ...filterProp,\n ...headRefreshDatagridProp,\n ...apiProps,\n modelValue: { type: [String, Number, Boolean] as PropType<any>, default: false },\n /** 悬停提示 */\n tips: { type: String, default: '' },\n /** 提交参数的字段名 */\n paramKey: { type: String, default: 'status' },\n activeValue: { type: [String, Number, Boolean], default: true },\n inactiveValue: { type: [String, Number, Boolean], default: false }\n})\n\nconst emit = defineEmits(['update:modelValue', 'change', 'apiBefore', 'apiSuccess', 'apiFail', 'apiException', 'apiAfter'])\n\nconst loading = ref(false)\n\nconst inner = computed({\n get: () => props.modelValue,\n set: (val) => emit('update:modelValue', val)\n})\n\nasync function onChange(val: any) {\n emit('change', val)\n if (!props.api) return\n\n // 记录旧值,失败回滚\n const oldVal = val === props.activeValue ? props.inactiveValue : props.activeValue\n loading.value = true\n emit('apiBefore', { url: props.api })\n try {\n const param = { ...props.apiParam, [props.paramKey]: val }\n const result =\n props.apiMethod === 'get'\n ? await request.get(props.api, param)\n : await request.post(props.api, param)\n if (result.success) {\n emit('apiSuccess', { data: result.data })\n if (props.headRefreshDatagrid) {\n refreshDataGrid(props.headRefreshDatagrid, props.filter)\n }\n emit('apiAfter', { data: result.data })\n } else {\n // 业务失败:回滚状态\n emit('update:modelValue', oldVal)\n emit('apiFail', { code: result.code, message: result.message })\n emit('apiAfter', { code: result.code })\n }\n } catch (error: any) {\n // 网络异常:回滚状态\n emit('update:modelValue', oldVal)\n emit('apiException', { error, message: error?.message })\n emit('apiAfter', { error })\n } finally {\n loading.value = false\n }\n}\n</script>\n"],"names":["props","__props","emit","__emit","loading","ref","inner","computed","val","onChange","oldVal","param","result","request","refreshDataGrid","error","_createBlock","_component_el_tooltip","_createVNode","_component_el_switch","_mergeProps","$event","$attrs","_openBlock"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA+BA,UAAMA,IAAQC,GAaRC,IAAOC,GAEPC,IAAUC,EAAI,EAAK,GAEnBC,IAAQC,EAAS;AAAA,MACrB,KAAK,MAAMP,EAAM;AAAA,MACjB,KAAK,CAACQ,MAAQN,EAAK,qBAAqBM,CAAG;AAAA,IAAA,CAC5C;AAED,mBAAeC,EAASD,GAAU;AAEhC,UADAN,EAAK,UAAUM,CAAG,GACd,CAACR,EAAM,IAAK;AAGhB,YAAMU,IAASF,MAAQR,EAAM,cAAcA,EAAM,gBAAgBA,EAAM;AACvE,MAAAI,EAAQ,QAAQ,IAChBF,EAAK,aAAa,EAAE,KAAKF,EAAM,KAAK;AACpC,UAAI;AACF,cAAMW,IAAQ,EAAE,GAAGX,EAAM,UAAU,CAACA,EAAM,QAAQ,GAAGQ,EAAA,GAC/CI,IACJZ,EAAM,cAAc,QAChB,MAAMa,EAAQ,IAAIb,EAAM,KAAKW,CAAK,IAClC,MAAME,EAAQ,KAAKb,EAAM,KAAKW,CAAK;AACzC,QAAIC,EAAO,WACTV,EAAK,cAAc,EAAE,MAAMU,EAAO,MAAM,GACpCZ,EAAM,uBACRc,EAAgBd,EAAM,qBAAqBA,EAAM,MAAM,GAEzDE,EAAK,YAAY,EAAE,MAAMU,EAAO,MAAM,MAGtCV,EAAK,qBAAqBQ,CAAM,GAChCR,EAAK,WAAW,EAAE,MAAMU,EAAO,MAAM,SAASA,EAAO,SAAS,GAC9DV,EAAK,YAAY,EAAE,MAAMU,EAAO,MAAM;AAAA,MAE1C,SAASG,GAAY;AAEnB,QAAAb,EAAK,qBAAqBQ,CAAM,GAChCR,EAAK,gBAAgB,EAAE,OAAAa,GAAO,SAASA,KAAA,gBAAAA,EAAO,SAAS,GACvDb,EAAK,YAAY,EAAE,OAAAa,GAAO;AAAA,MAC5B,UAAA;AACE,QAAAX,EAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;;;aAtFoBH,EAAA,aAAlBe,EASaC,GAAA;AAAA;QATY,SAAShB,EAAA;AAAA,QAAM,WAAU;AAAA,MAAA;mBAChD,MAOE;AAAA,UAPFiB,EAOEC,GAPFC,EAOE;AAAA,wBANSd,EAAA;AAAA,0DAAAA,EAAK,QAAAe;AAAA,YACb,gBAAcpB,EAAA;AAAA,YACd,kBAAgBA,EAAA;AAAA,YAChB,SAASG,EAAA;AAAA,UAAA,GACFkB,EAAAA,QAAM,EACb,UAAAb,GAAgB,GAAA,MAAA,IAAA,CAAA,cAAA,gBAAA,kBAAA,SAAA,CAAA;AAAA,QAAA;;6BAGrBc,EAAA,GAAAP,EAQEG,GARFC,EAQE;AAAA;oBANSd,EAAA;AAAA,sDAAAA,EAAK,QAAAe;AAAA,QACb,gBAAcpB,EAAA;AAAA,QACd,kBAAgBA,EAAA;AAAA,QAChB,SAASG,EAAA;AAAA,MAAA,GACFkB,EAAAA,QAAM,EACb,UAAAb,GAAgB,GAAA,MAAA,IAAA,CAAA,cAAA,gBAAA,kBAAA,SAAA,CAAA;AAAA;;;"}
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as j, getCurrentInstance as G, ref as h, watch as H, computed as b, onMounted as O, resolveComponent as A, openBlock as W, createBlock as J, mergeProps as Q, createSlots as X, withCtx as p, renderSlot as Y, createVNode as B, createTextVNode as N, toDisplayString as M, createElementVNode as Z, withModifiers as F } from "vue";
2
2
  import { ElMessage as m, ElMessageBox as _ } from "element-plus";
3
- import { a as v, r as g } from "./http-DUPsbs2K.mjs";
3
+ import { a as v, r as g } from "./http-9ToPNkWJ.mjs";
4
4
  import { r as U } from "./linkage-FbL1mcz3.mjs";
5
5
  import { h as ee, f as te } from "./props-DAytpx7D.mjs";
6
6
  const ae = { class: "el-upload__tip" }, ne = /* @__PURE__ */ j({
@@ -197,4 +197,4 @@ const ae = { class: "el-upload__tip" }, ne = /* @__PURE__ */ j({
197
197
  export {
198
198
  ne as _
199
199
  };
200
- //# sourceMappingURL=Upload.vue_vue_type_script_setup_true_lang-CkxGO85H.mjs.map
200
+ //# sourceMappingURL=Upload.vue_vue_type_script_setup_true_lang-DORizGEF.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Upload.vue_vue_type_script_setup_true_lang-CkxGO85H.mjs","sources":["../../src/components/upload/Upload.vue"],"sourcesContent":["<template>\n <el-upload\n ref=\"uploadRef\"\n :action=\"resolvedAction\"\n :headers=\"uploadHeaders\"\n :accept=\"accept\"\n :limit=\"limit\"\n :multiple=\"multiple\"\n :auto-upload=\"autoUpload\"\n :name=\"name\"\n :data=\"data\"\n :disabled=\"disabled\"\n :show-file-list=\"showFileList\"\n v-model:file-list=\"innerFileList\"\n :before-upload=\"beforeUpload\"\n :before-remove=\"beforeRemove\"\n :on-success=\"onSuccess\"\n :on-error=\"onError\"\n :on-remove=\"onRemove\"\n :on-exceed=\"onExceed\"\n :on-preview=\"onPreview\"\n v-bind=\"$attrs\"\n >\n <slot>\n <el-button type=\"primary\">{{ buttonText }}</el-button>\n </slot>\n <template v-if=\"withSubmit && !autoUpload\" #tip>\n <div class=\"el-upload__tip\">\n <el-button size=\"small\" type=\"success\" :loading=\"submitting\" @click.stop=\"submitUpload\">\n {{ submitButtonText }}\n </el-button>\n </div>\n </template>\n </el-upload>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, onMounted, ref, watch } from 'vue'\nimport type { UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus'\nimport { ElMessage, ElMessageBox } from 'element-plus'\nimport { request } from '../../lib/core/http'\nimport { getGlobalConfig } from '../../lib/core/config'\nimport { refreshDataGrid } from '../../lib/core/linkage'\nimport { filterProp, headRefreshDatagridProp } from '../common/props'\nimport type { PropType } from 'vue'\n\ndefineOptions({ name: 'WdUpload', inheritAttrs: false })\n\nconst props = defineProps({\n ...filterProp,\n ...headRefreshDatagridProp,\n /** 上传地址(走全局 urlPrefix 拼接;为空则 el-upload 不真正提交,由外部接管) */\n api: { type: String, default: '' },\n /** 后端删除地址 */\n deleteApi: { type: String, default: '' },\n /** 删除请求方法 */\n deleteMethod: {\n type: String as PropType<'get' | 'post' | 'put' | 'delete'>,\n default: 'post'\n },\n /** 删除时取文件记录的主键字段名 */\n primaryKey: { type: String, default: 'id' },\n /** 手动提交按钮文案(auto-upload=false 时显示) */\n submitButtonText: { type: String, default: '开始上传' },\n /** 选择按钮文案(默认插槽未提供时) */\n buttonText: { type: String, default: '点击上传' },\n // ---- el-upload 同名透传 ----\n accept: { type: String, default: '' },\n limit: { type: Number, default: undefined },\n multiple: { type: Boolean, default: false },\n autoUpload: { type: Boolean, default: true },\n /** 上传字段名 */\n name: { type: String, default: 'file' },\n /** 附加表单数据 */\n data: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n disabled: { type: Boolean, default: false },\n showFileList: { type: Boolean, default: true },\n /** 文件大小限制(MB),0 不限制 */\n maxSize: { type: Number, default: 0 },\n /** v-model 绑定的已上传文件列表(含后端返回记录) */\n modelValue: { type: Array as PropType<UploadUserFile[]>, default: () => [] }\n})\n\nconst emit = defineEmits([\n 'update:modelValue',\n 'change',\n 'success',\n 'error',\n 'delete-success',\n 'preview',\n 'exceed',\n 'apiBefore',\n 'apiSuccess',\n 'apiFail',\n 'apiException',\n 'apiAfter'\n])\n\nconst instance = getCurrentInstance()\nconst uploadRef = ref<UploadInstance>()\nconst submitting = ref(false)\nconst innerFileList = ref<UploadUserFile[]>([...props.modelValue])\n\nwatch(\n () => props.modelValue,\n (val) => {\n innerFileList.value = [...val]\n }\n)\n\n/** 拼接完整上传地址(el-upload 原生 XHR 不走 axios 实例,需自行拼 prefix) */\nconst resolvedAction = computed(() => {\n if (!props.api) return '#'\n if (/^https?:\\/\\//.test(props.api)) return props.api\n const cfg = getGlobalConfig()\n const prefix = cfg.request.urlPrefix || ''\n return prefix ? `${prefix.replace(/\\/$/, '')}/${props.api.replace(/^\\//, '')}` : props.api\n})\n\n/** 透传全局请求头(如 Authorization) */\nconst uploadHeaders = computed<Record<string, string>>(() => {\n const cfg = getGlobalConfig()\n const headers: Record<string, string> = {}\n const interceptor = cfg.request.transform.requestInterceptor\n // requestInterceptor 为 async,无法同步取头;此处仅注入静态 token 头\n const token = (cfg.request as any).token || ''\n if (token) headers.Authorization = `Bearer ${token}`\n return headers\n})\n\nconst withSubmit = computed(() => !props.autoUpload)\n\nfunction syncModel() {\n emit('update:modelValue', innerFileList.value)\n emit('change', innerFileList.value)\n}\n\nconst beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {\n if (props.maxSize && rawFile.size / 1024 / 1024 > props.maxSize) {\n ElMessage.error(`文件大小不能超过 ${props.maxSize}MB`)\n return false\n }\n emit('apiBefore', { url: props.api, file: rawFile })\n return true\n}\n\n/** el-upload 原生 XHR 成功回调:按全局解封约定判断业务成败 */\nconst onSuccess: UploadProps['onSuccess'] = (response, uploadFile, uploadFiles) => {\n const cfg = getGlobalConfig()\n const { codeName } = cfg.response.props\n const code = response?.[codeName]\n const ok = code === undefined || code === null || Number.isNaN(Number(code)) || Number(code) >= cfg.response.successCode\n\n // 把后端返回记录挂到文件对象,供删除时取主键\n ;(uploadFile as any).response = response\n if (ok && response?.[cfg.response.props.dataName]) {\n const bizData = response[cfg.response.props.dataName]\n ;(uploadFile as any).biz = bizData\n if (bizData && typeof bizData === 'object') {\n uploadFile.url = uploadFile.url || bizData.url || bizData.path\n }\n }\n\n if (ok) {\n emit('success', { response, file: uploadFile, files: uploadFiles })\n emit('apiSuccess', { data: response?.[cfg.response.props.dataName], raw: response })\n if (props.headRefreshDatagrid) refreshDataGrid(props.headRefreshDatagrid, props.filter)\n } else {\n ElMessage.error(response?.[cfg.response.props.messageName] || '上传失败')\n emit('error', { response, file: uploadFile })\n emit('apiFail', { code, message: response?.[cfg.response.props.messageName] })\n }\n emit('apiAfter', { url: props.api })\n syncModel()\n}\n\nconst onError: UploadProps['onError'] = (err, uploadFile, uploadFiles) => {\n ElMessage.error('上传失败,请稍后重试')\n emit('error', { error: err, file: uploadFile, files: uploadFiles })\n emit('apiException', { error: err, message: err?.message })\n emit('apiAfter', { url: props.api, error: err })\n syncModel()\n}\n\n/**\n * 删除前置钩子:二次确认 + 已上传文件走后端删除接口\n * 返回 false / reject Promise 中止移除(el-upload 约定)\n */\nconst beforeRemove: UploadProps['beforeRemove'] = async (uploadFile) => {\n try {\n await ElMessageBox.confirm('确认删除该文件?删除后不可恢复。', '提示', {\n confirmButtonText: '确定',\n cancelButtonText: '取消',\n type: 'warning'\n })\n } catch {\n return false\n }\n\n const biz = (uploadFile as any).biz || uploadFile\n const fileId = biz?.[props.primaryKey] ?? (uploadFile.response as any)?.[props.primaryKey]\n\n if (props.deleteApi && fileId !== undefined && fileId !== null) {\n emit('apiBefore', { url: props.deleteApi })\n try {\n const param = { ...(props.data || {}), [props.primaryKey]: fileId }\n const result =\n props.deleteMethod === 'get'\n ? await request.get(props.deleteApi, param)\n : props.deleteMethod === 'delete'\n ? await request.delete(props.deleteApi, param)\n : props.deleteMethod === 'put'\n ? await request.put(props.deleteApi, param)\n : await request.post(props.deleteApi, param)\n if (result.success) {\n emit('delete-success', { file: uploadFile, data: result.data })\n emit('apiSuccess', { data: result.data })\n if (props.headRefreshDatagrid) refreshDataGrid(props.headRefreshDatagrid, props.filter)\n } else {\n emit('apiFail', { code: result.code, message: result.message })\n return false\n }\n } catch (error: any) {\n emit('apiException', { error, message: error?.message })\n return false\n } finally {\n emit('apiAfter', { url: props.deleteApi })\n }\n } else {\n // 仅本地移除(未上传成功或未配置删除接口)\n emit('delete-success', { file: uploadFile })\n }\n return true\n}\n\n/** 文件已从列表移除(el-upload 内部状态已更新) */\nconst onRemove: UploadProps['onRemove'] = () => {\n syncModel()\n}\n\nconst onExceed: UploadProps['onExceed'] = (selectedFiles, uploadFiles) => {\n ElMessage.warning(`最多上传 ${props.limit} 个文件`)\n emit('exceed', { selectedFiles, files: uploadFiles })\n}\n\nconst onPreview: UploadProps['onPreview'] = (uploadFile) => {\n emit('preview', { file: uploadFile })\n}\n\n/** 手动触发上传(auto-upload=false) */\nfunction submitUpload() {\n uploadRef.value?.submit()\n}\n\nfunction clearFiles() {\n uploadRef.value?.clearFiles()\n innerFileList.value = []\n syncModel()\n}\n\n/** 追加外部文件记录(如表单回显) */\nfunction addFile(file: UploadUserFile) {\n innerFileList.value = [...innerFileList.value, file]\n syncModel()\n}\n\nonMounted(() => {\n // 暴露给 HTML 场景根作用域(与 model/q 模式一致)\n if (instance) {\n instance.appContext.config.globalProperties.$wdUpload = { submitUpload, clearFiles }\n }\n})\n\ndefineExpose({ submitUpload, clearFiles, addFile, uploadRef })\n</script>\n"],"names":["props","__props","emit","__emit","instance","getCurrentInstance","uploadRef","ref","submitting","innerFileList","watch","val","resolvedAction","computed","prefix","getGlobalConfig","uploadHeaders","cfg","headers","token","withSubmit","syncModel","beforeUpload","rawFile","ElMessage","onSuccess","response","uploadFile","uploadFiles","codeName","code","ok","bizData","refreshDataGrid","onError","err","beforeRemove","ElMessageBox","biz","fileId","_a","param","result","request","error","onRemove","onExceed","selectedFiles","onPreview","submitUpload","clearFiles","addFile","file","onMounted","__expose","_openBlock","_createBlock","_component_el_upload","_mergeProps","$event","$attrs","_createSlots","_renderSlot","_ctx","_createVNode","_component_el_button","_createElementVNode","_hoisted_1"],"mappings":"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"}
1
+ {"version":3,"file":"Upload.vue_vue_type_script_setup_true_lang-DORizGEF.mjs","sources":["../../src/components/upload/Upload.vue"],"sourcesContent":["<template>\n <el-upload\n ref=\"uploadRef\"\n :action=\"resolvedAction\"\n :headers=\"uploadHeaders\"\n :accept=\"accept\"\n :limit=\"limit\"\n :multiple=\"multiple\"\n :auto-upload=\"autoUpload\"\n :name=\"name\"\n :data=\"data\"\n :disabled=\"disabled\"\n :show-file-list=\"showFileList\"\n v-model:file-list=\"innerFileList\"\n :before-upload=\"beforeUpload\"\n :before-remove=\"beforeRemove\"\n :on-success=\"onSuccess\"\n :on-error=\"onError\"\n :on-remove=\"onRemove\"\n :on-exceed=\"onExceed\"\n :on-preview=\"onPreview\"\n v-bind=\"$attrs\"\n >\n <slot>\n <el-button type=\"primary\">{{ buttonText }}</el-button>\n </slot>\n <template v-if=\"withSubmit && !autoUpload\" #tip>\n <div class=\"el-upload__tip\">\n <el-button size=\"small\" type=\"success\" :loading=\"submitting\" @click.stop=\"submitUpload\">\n {{ submitButtonText }}\n </el-button>\n </div>\n </template>\n </el-upload>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, onMounted, ref, watch } from 'vue'\nimport type { UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus'\nimport { ElMessage, ElMessageBox } from 'element-plus'\nimport { request } from '../../lib/core/http'\nimport { getGlobalConfig } from '../../lib/core/config'\nimport { refreshDataGrid } from '../../lib/core/linkage'\nimport { filterProp, headRefreshDatagridProp } from '../common/props'\nimport type { PropType } from 'vue'\n\ndefineOptions({ name: 'WdUpload', inheritAttrs: false })\n\nconst props = defineProps({\n ...filterProp,\n ...headRefreshDatagridProp,\n /** 上传地址(走全局 urlPrefix 拼接;为空则 el-upload 不真正提交,由外部接管) */\n api: { type: String, default: '' },\n /** 后端删除地址 */\n deleteApi: { type: String, default: '' },\n /** 删除请求方法 */\n deleteMethod: {\n type: String as PropType<'get' | 'post' | 'put' | 'delete'>,\n default: 'post'\n },\n /** 删除时取文件记录的主键字段名 */\n primaryKey: { type: String, default: 'id' },\n /** 手动提交按钮文案(auto-upload=false 时显示) */\n submitButtonText: { type: String, default: '开始上传' },\n /** 选择按钮文案(默认插槽未提供时) */\n buttonText: { type: String, default: '点击上传' },\n // ---- el-upload 同名透传 ----\n accept: { type: String, default: '' },\n limit: { type: Number, default: undefined },\n multiple: { type: Boolean, default: false },\n autoUpload: { type: Boolean, default: true },\n /** 上传字段名 */\n name: { type: String, default: 'file' },\n /** 附加表单数据 */\n data: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n disabled: { type: Boolean, default: false },\n showFileList: { type: Boolean, default: true },\n /** 文件大小限制(MB),0 不限制 */\n maxSize: { type: Number, default: 0 },\n /** v-model 绑定的已上传文件列表(含后端返回记录) */\n modelValue: { type: Array as PropType<UploadUserFile[]>, default: () => [] }\n})\n\nconst emit = defineEmits([\n 'update:modelValue',\n 'change',\n 'success',\n 'error',\n 'delete-success',\n 'preview',\n 'exceed',\n 'apiBefore',\n 'apiSuccess',\n 'apiFail',\n 'apiException',\n 'apiAfter'\n])\n\nconst instance = getCurrentInstance()\nconst uploadRef = ref<UploadInstance>()\nconst submitting = ref(false)\nconst innerFileList = ref<UploadUserFile[]>([...props.modelValue])\n\nwatch(\n () => props.modelValue,\n (val) => {\n innerFileList.value = [...val]\n }\n)\n\n/** 拼接完整上传地址(el-upload 原生 XHR 不走 axios 实例,需自行拼 prefix) */\nconst resolvedAction = computed(() => {\n if (!props.api) return '#'\n if (/^https?:\\/\\//.test(props.api)) return props.api\n const cfg = getGlobalConfig()\n const prefix = cfg.request.urlPrefix || ''\n return prefix ? `${prefix.replace(/\\/$/, '')}/${props.api.replace(/^\\//, '')}` : props.api\n})\n\n/** 透传全局请求头(如 Authorization) */\nconst uploadHeaders = computed<Record<string, string>>(() => {\n const cfg = getGlobalConfig()\n const headers: Record<string, string> = {}\n const interceptor = cfg.request.transform.requestInterceptor\n // requestInterceptor 为 async,无法同步取头;此处仅注入静态 token 头\n const token = (cfg.request as any).token || ''\n if (token) headers.Authorization = `Bearer ${token}`\n return headers\n})\n\nconst withSubmit = computed(() => !props.autoUpload)\n\nfunction syncModel() {\n emit('update:modelValue', innerFileList.value)\n emit('change', innerFileList.value)\n}\n\nconst beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {\n if (props.maxSize && rawFile.size / 1024 / 1024 > props.maxSize) {\n ElMessage.error(`文件大小不能超过 ${props.maxSize}MB`)\n return false\n }\n emit('apiBefore', { url: props.api, file: rawFile })\n return true\n}\n\n/** el-upload 原生 XHR 成功回调:按全局解封约定判断业务成败 */\nconst onSuccess: UploadProps['onSuccess'] = (response, uploadFile, uploadFiles) => {\n const cfg = getGlobalConfig()\n const { codeName } = cfg.response.props\n const code = response?.[codeName]\n const ok = code === undefined || code === null || Number.isNaN(Number(code)) || Number(code) >= cfg.response.successCode\n\n // 把后端返回记录挂到文件对象,供删除时取主键\n ;(uploadFile as any).response = response\n if (ok && response?.[cfg.response.props.dataName]) {\n const bizData = response[cfg.response.props.dataName]\n ;(uploadFile as any).biz = bizData\n if (bizData && typeof bizData === 'object') {\n uploadFile.url = uploadFile.url || bizData.url || bizData.path\n }\n }\n\n if (ok) {\n emit('success', { response, file: uploadFile, files: uploadFiles })\n emit('apiSuccess', { data: response?.[cfg.response.props.dataName], raw: response })\n if (props.headRefreshDatagrid) refreshDataGrid(props.headRefreshDatagrid, props.filter)\n } else {\n ElMessage.error(response?.[cfg.response.props.messageName] || '上传失败')\n emit('error', { response, file: uploadFile })\n emit('apiFail', { code, message: response?.[cfg.response.props.messageName] })\n }\n emit('apiAfter', { url: props.api })\n syncModel()\n}\n\nconst onError: UploadProps['onError'] = (err, uploadFile, uploadFiles) => {\n ElMessage.error('上传失败,请稍后重试')\n emit('error', { error: err, file: uploadFile, files: uploadFiles })\n emit('apiException', { error: err, message: err?.message })\n emit('apiAfter', { url: props.api, error: err })\n syncModel()\n}\n\n/**\n * 删除前置钩子:二次确认 + 已上传文件走后端删除接口\n * 返回 false / reject Promise 中止移除(el-upload 约定)\n */\nconst beforeRemove: UploadProps['beforeRemove'] = async (uploadFile) => {\n try {\n await ElMessageBox.confirm('确认删除该文件?删除后不可恢复。', '提示', {\n confirmButtonText: '确定',\n cancelButtonText: '取消',\n type: 'warning'\n })\n } catch {\n return false\n }\n\n const biz = (uploadFile as any).biz || uploadFile\n const fileId = biz?.[props.primaryKey] ?? (uploadFile.response as any)?.[props.primaryKey]\n\n if (props.deleteApi && fileId !== undefined && fileId !== null) {\n emit('apiBefore', { url: props.deleteApi })\n try {\n const param = { ...(props.data || {}), [props.primaryKey]: fileId }\n const result =\n props.deleteMethod === 'get'\n ? await request.get(props.deleteApi, param)\n : props.deleteMethod === 'delete'\n ? await request.delete(props.deleteApi, param)\n : props.deleteMethod === 'put'\n ? await request.put(props.deleteApi, param)\n : await request.post(props.deleteApi, param)\n if (result.success) {\n emit('delete-success', { file: uploadFile, data: result.data })\n emit('apiSuccess', { data: result.data })\n if (props.headRefreshDatagrid) refreshDataGrid(props.headRefreshDatagrid, props.filter)\n } else {\n emit('apiFail', { code: result.code, message: result.message })\n return false\n }\n } catch (error: any) {\n emit('apiException', { error, message: error?.message })\n return false\n } finally {\n emit('apiAfter', { url: props.deleteApi })\n }\n } else {\n // 仅本地移除(未上传成功或未配置删除接口)\n emit('delete-success', { file: uploadFile })\n }\n return true\n}\n\n/** 文件已从列表移除(el-upload 内部状态已更新) */\nconst onRemove: UploadProps['onRemove'] = () => {\n syncModel()\n}\n\nconst onExceed: UploadProps['onExceed'] = (selectedFiles, uploadFiles) => {\n ElMessage.warning(`最多上传 ${props.limit} 个文件`)\n emit('exceed', { selectedFiles, files: uploadFiles })\n}\n\nconst onPreview: UploadProps['onPreview'] = (uploadFile) => {\n emit('preview', { file: uploadFile })\n}\n\n/** 手动触发上传(auto-upload=false) */\nfunction submitUpload() {\n uploadRef.value?.submit()\n}\n\nfunction clearFiles() {\n uploadRef.value?.clearFiles()\n innerFileList.value = []\n syncModel()\n}\n\n/** 追加外部文件记录(如表单回显) */\nfunction addFile(file: UploadUserFile) {\n innerFileList.value = [...innerFileList.value, file]\n syncModel()\n}\n\nonMounted(() => {\n // 暴露给 HTML 场景根作用域(与 model/q 模式一致)\n if (instance) {\n instance.appContext.config.globalProperties.$wdUpload = { submitUpload, clearFiles }\n }\n})\n\ndefineExpose({ submitUpload, clearFiles, addFile, uploadRef })\n</script>\n"],"names":["props","__props","emit","__emit","instance","getCurrentInstance","uploadRef","ref","submitting","innerFileList","watch","val","resolvedAction","computed","prefix","getGlobalConfig","uploadHeaders","cfg","headers","token","withSubmit","syncModel","beforeUpload","rawFile","ElMessage","onSuccess","response","uploadFile","uploadFiles","codeName","code","ok","bizData","refreshDataGrid","onError","err","beforeRemove","ElMessageBox","biz","fileId","_a","param","result","request","error","onRemove","onExceed","selectedFiles","onPreview","submitUpload","clearFiles","addFile","file","onMounted","__expose","_openBlock","_createBlock","_component_el_upload","_mergeProps","$event","$attrs","_createSlots","_renderSlot","_ctx","_createVNode","_component_el_button","_createElementVNode","_hoisted_1"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as ge, useSlots as be, computed as h, ref as v, watch as z, onMounted as _e, resolveComponent as u, resolveDirective as we, withDirectives as ye, openBlock as d, createElementBlock as b, createBlock as C, mergeProps as Se, withCtx as n, Fragment as q, renderList as L, resolveDynamicComponent as R, renderSlot as F, createTextVNode as _, toDisplayString as J, createElementVNode as j, withModifiers as N, createVNode as r, unref as P, createCommentVNode as A, normalizeClass as De } from "vue";
2
2
  import { ScaleToOriginal as ke, Setting as he, Rank as $e } from "@element-plus/icons-vue";
3
- import { r as B } from "./http-DUPsbs2K.mjs";
3
+ import { r as B } from "./http-9ToPNkWJ.mjs";
4
4
  import { _ as xe } from "./_plugin-vue_export-helper-CHgC5LLL.mjs";
5
5
  const Ve = { class: "wd-viewer" }, Ce = {
6
6
  key: 1,
@@ -378,4 +378,4 @@ const Ve = { class: "wd-viewer" }, Ce = {
378
378
  export {
379
379
  Ne as W
380
380
  };
381
- //# sourceMappingURL=Viewer-COLbtcgF.mjs.map
381
+ //# sourceMappingURL=Viewer-DcMSN3_1.mjs.map