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
package/llms.txt ADDED
@@ -0,0 +1,688 @@
1
+ # workdesktop-ai — AI 开发参考(LLM-Optimized Component Library Reference)
2
+
3
+ - 创建时间: 2026-09-16 19:45:30
4
+ - 最后修改时间: 2026-09-24 13:44:41
5
+ - 当前版本: V_1.2
6
+ - 适用对象: AI 编码助手(非人类读者;信息密度优先,无修辞)
7
+ - 核心目标: 使 AI 完整认识 workdesktop-ai 组件库,并能正确使用其完成开发任务
8
+ - 文档简略描述: workdesktop-ai@1.1.1 全量事实参考:包结构 / 引入方式 / 全局配置 / 请求体系 / 声明式联动 / 28 组件 API(props/emits/slots/methods)/ 跨 iframe 协议 / 陷阱清单
9
+
10
+ ================================================================================
11
+ ## 0. 如何使用本文档(FOR AI)
12
+ ================================================================================
13
+ - 本文档为唯一事实源优先级:本文档 < 源码(src/)。冲突时以源码为准。
14
+ - 所有组件注册名(name)均为 `WdXxx`;模板中可用 `<wd-xxx>` 或 `<WdXxx>`。
15
+ - 组件基于 ElementPlus(el-*),多数 $attrs 透传到底层 el 组件,标注「透传」处可直接使用 el-* 原生属性。
16
+ - 「默认值」列 = 组件内置默认;全局配置可覆盖的项会标注 [G](page.componentDefault)。
17
+ - 标注 [陷阱] 的条目见 §11,开发前必读。
18
+
19
+ ================================================================================
20
+ ## 1. 包事实(PACKAGE FACTS)
21
+ ================================================================================
22
+ ```yaml
23
+ name: workdesktop-ai
24
+ version: 1.1.1
25
+ description: WorkDesktop 企业级 Vue3 组件库(基于 ElementPlus,HTML 模板渲染友好、AI 编码友好)
26
+ type: module
27
+ main: dist/index.umd.js # UMD, window.WorkDesktop
28
+ module: dist/index.esm.js # ESM
29
+ types: dist/types/src/index.d.ts
30
+ sideEffects: ["*.css", "**/*.css"] # CSS 有副作用,tree-shaking 不会删
31
+ peerDependencies: # 宿主项目必须安装
32
+ vue: ^3.3.0
33
+ element-plus: ^2.5.0
34
+ "@element-plus/icons-vue": ^2.0.0
35
+ dependencies:
36
+ axios: ^1.7.7
37
+ async-validator: ^4.2.5
38
+ ```
39
+
40
+ ================================================================================
41
+ ## 2. 引入方式(IMPORT)
42
+ ================================================================================
43
+ ### 2.1 ESM 全量(构建工具项目首选)
44
+ ```ts
45
+ import { createApp } from 'vue'
46
+ import ElementPlus from 'element-plus'
47
+ import 'element-plus/dist/index.css'
48
+ import WorkDesktop from 'workdesktop-ai'
49
+ import 'workdesktop-ai/style.css' // 全量样式(含全部组件)
50
+ // import 'workdesktop-ai/base.css' // 仅基础样式(按需场景)
51
+
52
+ app.use(ElementPlus)
53
+ app.use(WorkDesktop, globalConfig?) // 第二参 = 全局配置,见 §4
54
+ ```
55
+
56
+ ### 2.2 UMD / 浏览器直引(HTML 模板渲染场景)
57
+ ```html
58
+ <script>
59
+ // 在加载 UMD 之前定义全局配置(可选)
60
+ window.workDesktopConfig = { /* 同 globalConfig */ }
61
+ </script>
62
+ <script src=".../dist/index.umd.js"></script>
63
+ <!-- 全局变量: window.WorkDesktop;组件自动注册为 wd-* -->
64
+ ```
65
+
66
+ ### 2.3 按需子路径(27 个组件入口)
67
+ 格式:`import WdXxx from 'workdesktop-ai/<subpath>'`
68
+ 每个子路径含 types + ESM(.mjs)。
69
+
70
+ | 子路径 | 组件 | 独立样式 |
71
+ |---|---|---|
72
+ | api-button | WdApiButton | — |
73
+ | auto-complete | WdAutoComplete | auto-complete/style.css |
74
+ | checkbox-list | WdCheckboxList | — |
75
+ | confirm-button | WdConfirmButton | — |
76
+ | data-form | WdDataForm | data-form/style.css |
77
+ | data-grid | WdDataGrid | data-grid/style.css |
78
+ | dialog-button | WdDialogButton | — |
79
+ | drawer | WdDrawer | drawer/style.css |
80
+ | drawer-button | WdDrawerButton | — |
81
+ | editable-grid | WdEditableGrid | editable-grid/style.css |
82
+ | form-item | WdFormItem | form-item/style.css |
83
+ | iframe | WdIframe | iframe/style.css |
84
+ | image-upload | WdImageUpload | image-upload/style.css |
85
+ | panel | WdPanel | panel/style.css |
86
+ | prompt-button | WdPromptButton | — |
87
+ | radio-list | WdRadioList | — |
88
+ | requester | WdRequester | — |
89
+ | route-button | WdRouteButton | — |
90
+ | search-item | WdSearchItem | search-item/style.css |
91
+ | search-panel | WdSearchPanel | search-panel/style.css |
92
+ | select | WdSelect | — |
93
+ | station | WdStation | station/style.css |
94
+ | switch | WdSwitch | — |
95
+ | tips | WdTips | tips/style.css |
96
+ | tips-button | WdTipsButton | — |
97
+ | upload | WdUpload | — |
98
+ | viewer | WdViewer | viewer/style.css |
99
+
100
+ - [陷阱] WdPopconfirmButton 无独立子路径,只能从主入口 `import { WdPopconfirmButton } from 'workdesktop-ai'`。
101
+ - 无独立 style.css 的子路径:组件样式为零依赖(纯 el-* 组合)或已含在 base.css。
102
+ - 按需引入样式写法:`import 'workdesktop-ai/base.css'` + `import 'workdesktop-ai/<subpath>/style.css'`(仅上表列出的 14 个)。
103
+
104
+ ### 2.4 主入口导出面(src/index.ts 逐字)
105
+ ```ts
106
+ export default WorkDesktop // Vue 插件(install 注册全部 28 组件 + 初始化配置)
107
+ export * from './components' // 28 个组件,全部 Wd 前缀
108
+ // 配置
109
+ export { initConfig, setGlobalConfig, getGlobalConfig, resetConfig, mergeConfig, getComponentDefault }
110
+ // 预设皮肤(§4.4)
111
+ export { SKIN_PRESETS, getSkinPreset, listSkins }
112
+ export type { SkinPreset }
113
+ // 请求
114
+ export { RequestAPI, request } // request = 全局单例
115
+ export { default as http } // 同 request 体系默认导出
116
+ export type { ApiResult, ApiEventPayload, ApiEventType, ApiEventHandler }
117
+ // 联动(§6)
118
+ export { registerDataGrid, refreshDataGrid, searchDataGrid, resetSearchDataGrid, getDataGrids, clearLinkageRegistry }
119
+ // Station 联动(§6.3)
120
+ export { registerStation, setStationFooter, refreshStationView }
121
+ // hooks
122
+ export { useRequest, useDataGrid, useConfig, useGlobalConfig, useEventBus, useGlobalState }
123
+ // 工具
124
+ export { deepMerge }
125
+ export type * from './types'
126
+ ```
127
+
128
+ ================================================================================
129
+ ## 3. 统一响应协议(RESPONSE PROTOCOL)
130
+ ================================================================================
131
+ - 所有 API 响应结构:`{ code: number, data: any, message: string }`
132
+ - 成功判定:`code >= successCode`(successCode 默认 0,全局可配)
133
+ - 字段名可全局改名:response.props(§4)
134
+ - 列表结构字段可全局改名:response.list(§4)
135
+ - Promise 语义:[关键] 业务失败(code 不达标)→ **resolve**,`success=false`,**不 reject**;仅网络/运行异常 → reject。
136
+ ```ts
137
+ interface ApiResult<T = any> {
138
+ success: boolean // 业务成功
139
+ data: T
140
+ code?: number
141
+ message?: string
142
+ raw?: any // 原始响应
143
+ }
144
+ interface ReqOptions {
145
+ showLoading?: boolean
146
+ showTips?: boolean
147
+ tipsConfig?: TipsConfig
148
+ axiosConfig?: AxiosRequestConfig
149
+ signal?: AbortSignal
150
+ dedup?: boolean // 并发去重,默认 true:method+url+params 一致时只发一次
151
+ [key: string]: any
152
+ }
153
+ ```
154
+
155
+ ================================================================================
156
+ ## 4. 全局配置(GLOBAL CONFIG)
157
+ ================================================================================
158
+ ### 4.1 三级覆盖与缓存时机 [关键]
159
+ 优先级(低→高):内置 defaultConfig < 全局层(`app.use(WorkDesktop, cfg)` / `window.workDesktopConfig`)< 组件 props。
160
+ - 配置在**组件挂载时读取一次并缓存**;运行中修改全局配置只影响**之后新挂载**的组件。
161
+ - 已挂载组件要应用新配置:用 `:key` 变更强制重建。
162
+
163
+ ### 4.2 WorkDesktopConfig 结构
164
+ ```ts
165
+ interface WorkDesktopConfig {
166
+ page?: {
167
+ componentDefault?: Record<string, Record<string, any>> // 按组件 name 覆盖 props 默认值,如 { WdRequester: { method: 'get' } }
168
+ pager?: PagerConfig
169
+ }
170
+ request?: {
171
+ urlPrefix?: string // URL 前缀,默认 ''
172
+ throwException?: boolean // 默认 false:业务失败不抛异常
173
+ dedup?: boolean // 默认 true:并发相同请求合并去重
174
+ loading?: { enable: boolean; props?: Record<string, any> }
175
+ axiosConfig?: AxiosRequestConfig // 默认 { timeout: 30000 },透传 axios
176
+ pageParam?: PageParamConfig
177
+ transform?: { requestInterceptor?: (cfg: any) => any; responseInterceptor?: (res: any) => any }
178
+ }
179
+ response?: ResponseConfig
180
+ theme?: ThemeConfig // 变更后 applyTheme 写入 :root CSS 变量;详见 §4.4
181
+ }
182
+ interface ThemeConfig {
183
+ skin?: SkinName // 预设皮肤(§4.4),11 套
184
+ colors?: Record<string, string> // 语义色键仅 6 个:primary/success/warning/danger/error/info(error 归一 danger);非语义键 → --wd-color-{key}
185
+ cssVars?: Record<string, string> // 任意 CSS 变量直写 :root
186
+ } // 覆盖优先级(低→高):skin < colors < cssVars
187
+ interface PagerConfig {
188
+ size?: 'small' | 'default' | 'large'
189
+ pageSizes?: number[]
190
+ pageSize?: number
191
+ layout?: string // el-pagination layout
192
+ hideOnSinglePage?: boolean
193
+ position?: 'left' | 'center' | 'right'
194
+ }
195
+ interface PageParamConfig {
196
+ pageField?: string // 默认 'currentPage'
197
+ sizeField?: string // 默认 'pageSize'
198
+ searchField?: string // 默认 'param'(搜索条件包裹字段)
199
+ }
200
+ interface ResponseConfig {
201
+ props?: { codeName?: string; messageName?: string; dataName?: string } // 响应字段名映射,默认 code/message/data
202
+ successCode?: number // 默认 0
203
+ list?: { listName?: string; totalName?: string; pageSizeName?: string; currentPageName?: string }
204
+ success?: TipsConfig
205
+ fail?: TipsConfig
206
+ exception?: TipsConfig
207
+ complete?: TipsConfig
208
+ }
209
+ interface TipsConfig {
210
+ tipsMode?: 'message' | 'notify' | 'messagebox' | 'none'
211
+ tipsType?: 'success' | 'warning' | 'error' | 'info'
212
+ showTips?: boolean
213
+ title?: string
214
+ props?: Record<string, any> // 透传给对应 ElMessage/ElNotification/ElMessageBox
215
+ }
216
+ // 所有配置方法均接受 DeepPartial(深合并)
217
+ ```
218
+
219
+ ### 4.3 配置 API(6 个方法)
220
+ ```ts
221
+ useGlobalConfig(): WorkDesktopConfig // 组合式中获取全局配置
222
+ setGlobalConfig(cfg: DeepPartial<WorkDesktopConfig>): void
223
+ mergeConfig(target, source): any // 深合并
224
+ getGlobalConfig(): WorkDesktopConfig
225
+ resetConfig(): void
226
+ useConfig(): WorkDesktopConfig
227
+ // 入口另导出: initConfig(cfg), getComponentDefault(name)
228
+ ```
229
+
230
+ ### 4.4 预设皮肤(SKINS — 1.1.1 新增)
231
+ ```ts
232
+ type SkinName = 'default' | 'fashion' | 'business' | 'tech' | 'cyberpunk' | 'chinese' | 'flat' | 'neumorphism' | 'gradient' | 'cool' | 'governance' // 11 套
233
+ interface SkinPreset {
234
+ key: SkinName
235
+ label: string // 中文名
236
+ desc: string // 风格描述
237
+ theme: ThemeConfig // 皮肤携带的主题配置(colors/cssVars,结构同 §4.2)
238
+ }
239
+ // API(主入口导出,§2.4)
240
+ SKIN_PRESETS: Record<SkinName, SkinPreset> // 全部预设映射
241
+ getSkinPreset(key?: string): SkinPreset | undefined // 无参或未知 key → undefined(由调用方回退)
242
+ listSkins(): SkinPreset[] // 全部 11 套(供皮肤选择器遍历)
243
+ ```
244
+ - 用法:`app.use(WorkDesktop, { theme: { skin: 'fashion' } })` 或 `setGlobalConfig({ theme: { skin: 'cyberpunk' } })`。
245
+ - 覆盖优先级(低→高):皮肤预设 < theme.colors < theme.cssVars。
246
+ - [陷阱] theme.skin 传入未知值:console.warn 并忽略 skin(仅应用用户 colors/cssVars,呈现默认外观),不抛错。
247
+ - El 派生色阶自动推导(1.1.1 起):applyTheme 按 EP 混色公式(light-N 混白 N/10,dark-2 混黑 20%)由 5 个归一化语义色(primary/success/warning/danger/info)自动生成 `--el-color-{key}-light-3/5/7/8/9` 与 `--el-color-{key}-dark-2`,无需手写;写入 :root 顺序:colors 语义键 → El 派生色阶 → cssVars(后者覆盖前者)。
248
+ - 组件级令牌回退链:组件样式引用形如 `var(--wd-panel-bg, var(--wd-bg-color, #fff))` 的令牌,皮肤/cssVars 可单独定制组件外观;覆盖组件:WdDataGrid/WdEditableGrid 卡片、WdSearchPanel、WdDataForm footer、WdStation aside/header/tabs、WdPanel;完整令牌清单见 src/styles/tokens.css。
249
+
250
+ ================================================================================
251
+ ## 5. 请求体系(HTTP / REQUEST)
252
+ ================================================================================
253
+ ### 5.1 RequestAPI 与全局单例
254
+ ```ts
255
+ const api = new RequestAPI(axiosConfig?) // 自建实例
256
+ // 全局单例 request(入口导出):
257
+ request.get(url, params?, reqOptions?)
258
+ request.post(url, data?, reqOptions?)
259
+ request.put(url, data?, reqOptions?)
260
+ request.delete(url, params?, reqOptions?)
261
+ request.request(axiosConfig, reqOptions?)
262
+ request.create(componentReqConfig?) // 派生组件级请求配置
263
+ request.on(handler): () => void // 订阅全局事件,返回取消函数
264
+ ```
265
+ ### 5.2 请求生命周期事件(所有请求类组件统一,顺序固定)
266
+ ```
267
+ apiBefore → (apiSuccess | apiFail | apiException) → apiAfter
268
+ // apiFail=业务失败(resolve);apiException=异常(reject 路径)
269
+ ```
270
+ ### 5.3 useRequest hook
271
+ ```ts
272
+ const { data, loading, error, run, refresh, abort } = useRequest(api, options?)
273
+ interface UseRequestOptions {
274
+ method?: string // 默认 'post'
275
+ immediate?: boolean // 默认 true
276
+ initialParams?: any
277
+ reqOptions?: ReqOptions
278
+ onSuccess?: (result: ApiResult) => void
279
+ onFail?: (result: ApiResult) => void
280
+ onError?: (err: any) => void
281
+ }
282
+ ```
283
+
284
+ ================================================================================
285
+ ## 6. 声明式联动(LINKAGE)
286
+ ================================================================================
287
+ ### 6.1 机制
288
+ - `filter: string`:联动分组标识。同一 filter 值的组件视为一组;空串 = 默认组。
289
+ - `headRefreshDatagrid: boolean | string`:请求类动作成功后触发联动刷新。
290
+ - `true`:刷新同 filter 组的所有 DataGrid。
291
+ - `string`:定向刷新指定 filter 名的组。
292
+ - 适用:按钮组(API/Drawer/Dialog/Prompt 等)、WdSwitch、WdUpload/WdImageUpload、WdDataForm、WdSearchPanel 等均带此二属性。
293
+
294
+ ### 6.2 DataGrid 联动注册表 API(6 个)
295
+ ```ts
296
+ registerDataGrid(instance): () => void // 注册,返回注销函数
297
+ refreshDataGrid(headRefreshDatagrid: boolean|string, selfFilter?): number // 返回刷新数量
298
+ searchDataGrid(params, headRefreshDatagrid, selfFilter?): void
299
+ resetSearchDataGrid(headRefreshDatagrid, selfFilter?): void
300
+ getDataGrids(filter?): DataGridInstance[]
301
+ clearLinkageRegistry(): void
302
+ ```
303
+ ### 6.3 Station 联动 API(3 个)
304
+ ```ts
305
+ registerStation(instance): () => void
306
+ setStationFooter(target: boolean|string, info: string, selfFilter?): void // target=true 同组;string 定向
307
+ refreshStationView(target: boolean|string = true, selfFilter?): number // 返回刷新数量
308
+ ```
309
+
310
+ ================================================================================
311
+ ## 7. 共享 Props / Emits 组(先定义,组件节引用)
312
+ ================================================================================
313
+ ```ts
314
+ // elButtonCommonProps(15,透传 el-button):
315
+ type, size, plain, round, circle, link, text, bg, disabled, icon, native-type, autofocus, tag, color, dark
316
+ // elButtonProps = elButtonCommonProps + loading
317
+ // elButtonPropsNoLoading = elButtonCommonProps(API 类按钮专用:loading 由组件内部接管)
318
+
319
+ tipsProp: { tips?: string, tipsType?: 'dark'|'light' = 'dark', placement?: string = 'top' }
320
+
321
+ buttonApiProps: {
322
+ api?: string // 请求地址
323
+ apiMethod?: string = 'post'
324
+ apiParam?: Record<string, any> = {}
325
+ buttonLoading?: boolean = true // 请求期间按钮 loading
326
+ pageLoading?: boolean = false // 请求期间整页 loading
327
+ headRefreshDatagrid?: boolean|string = false
328
+ filter?: string = ''
329
+ }
330
+
331
+ optionsProps: { // 选项加载类(Select/AutoComplete/CheckboxList/RadioList)
332
+ api?: string
333
+ apiMethod?: string = 'get'
334
+ apiParam?: Record<string, any>
335
+ active?: boolean = true // 挂载即加载 [注意:与 DataGrid.active 默认 false 不同]
336
+ dataSource?: any[] // 静态数据,优先于 api
337
+ textProp?: string = 'text'
338
+ valueProp?: string = 'value'
339
+ tipsProp?: string = 'tips' // 选项 tips 字段名(此处为字符串字段名,非 tipsProp 组)
340
+ addData?: any // 头部追加项
341
+ appendData?: any // 尾部追加项
342
+ }
343
+
344
+ containerProps: { // 弹层容器类(Drawer/DrawerButton/DialogButton)
345
+ modelValue?: boolean // v-model 控制显隐(按钮类不需要)
346
+ title?: string
347
+ url?: string // iframe 地址
348
+ size?: string = '50%' // 弹层宽度(drawer 宽 / dialog 宽)
349
+ confirmMessage?: string // 关闭前确认
350
+ data?: Record<string, any> // 传给弹层的数据
351
+ headRefreshDatagrid?: boolean|string
352
+ filter?: string
353
+ }
354
+
355
+ popconfirmProps: { // WdPopconfirmButton 专用(部分改名避 el-button 冲突)
356
+ confirmButtonText = '确定', cancelButtonText = '取消',
357
+ confirmButtonType = 'primary', cancelButtonType = 'text',
358
+ popIcon, popIconColor = '#f90', hideAfter = 200, popDisabled = false,
359
+ width = 150, trigger = 'click', popperClass, popperOptions,
360
+ showAfter = 0, teleported = true, persistent = false
361
+ }
362
+
363
+ buttonLabelProp: { label?: string } // 按钮文案
364
+
365
+ // optionsEmits(选项类统一 6 个):
366
+ 'update:modelValue'(val), change(val), apiBefore({url}), apiSuccess({data}), apiFail({code,message}), apiAfter()
367
+ // buttonApiEmits(API 按钮统一 6 个):
368
+ click(evt), apiBefore({url,method,params}), apiSuccess({data,code,message}),
369
+ apiFail({code,message}), apiException({error,message}), apiAfter({data?,error?})
370
+ ```
371
+
372
+ ================================================================================
373
+ ## 8. 组件总览(28 个)
374
+ ================================================================================
375
+ | # | 组件 | 类 | 一句话职能 |
376
+ |---|---|---|---|
377
+ | 1 | WdApiButton | 按钮 | 点击发 API 请求 |
378
+ | 2 | WdConfirmButton | 按钮 | MessageBox 确认后发请求 |
379
+ | 3 | WdDialogButton | 按钮 | 打开 dialog 弹层(iframe/插槽) |
380
+ | 4 | WdPopconfirmButton | 按钮 | Popconfirm 确认后发请求 |
381
+ | 5 | WdPromptButton | 按钮 | 输入值并入参后发请求 |
382
+ | 6 | WdRouteButton | 按钮 | 路由/链接跳转 |
383
+ | 7 | WdTipsButton | 按钮 | 纯提示按钮(按钮基座) |
384
+ | 8 | WdDrawerButton | 按钮 | 打开 drawer/dialog 弹层 |
385
+ | 9 | WdDataGrid | 数据 | 分页表格(远程/静态) |
386
+ | 10 | WdEditableGrid | 数据 | 可编辑表格 |
387
+ | 11 | WdViewer | 数据 | 描述列表/详情查看 |
388
+ | 12 | WdRequester | 数据 | 命令式请求器(v-model 开关触发) |
389
+ | 13 | WdDataForm | 表单 | 数据表单(加载/提交/脏检查) |
390
+ | 14 | WdSearchPanel | 表单 | 搜索面板(联动 DataGrid) |
391
+ | 15 | WdFormItem | 表单 | 表单项包装(tip) |
392
+ | 16 | WdSearchItem | 表单 | 搜索项(SearchPanel 语义) |
393
+ | 17 | WdDrawer | 容器 | 抽屉/对话框(iframe 宿主) |
394
+ | 18 | WdIframe | 容器 | iframe 嵌入(通信/自适应高) |
395
+ | 19 | WdSelect | 输入 | 下拉选择(远程/静态) |
396
+ | 20 | WdAutoComplete | 输入 | 自动完成 |
397
+ | 21 | WdCheckboxList | 输入 | 多选组 |
398
+ | 22 | WdRadioList | 输入 | 单选组 |
399
+ | 23 | WdSwitch | 输入 | 开关(切换即请求,失败回滚) |
400
+ | 24 | WdUpload | 上传 | 文件上传 |
401
+ | 25 | WdImageUpload | 上传 | 图片上传(强制 image/*) |
402
+ | 26 | WdPanel | 样式 | 面板容器 |
403
+ | 27 | WdTips | 样式 | 提示图标/提示框 |
404
+ | 28 | WdStation | 布局 | 管理台整页布局(菜单/标签页/工具栏) |
405
+
406
+ ================================================================================
407
+ ## 9. 组件详目(props / emits / slots / methods)
408
+ ================================================================================
409
+ 格式约定:`= 默认值`;`?` 可选;`[G]` 可被 page.componentDefault 全局覆盖;`+` 表示在引用组之上新增。
410
+
411
+ ### 9.1 WdApiButton(按钮基座 + API)
412
+ - props: buttonLabelProp + elButtonPropsNoLoading + tipsProp + buttonApiProps
413
+ - emits: buttonApiEmits
414
+ - 行为: api 为空时仅触发 click,不发请求。
415
+ - [陷阱] 外部透传 loading 无效(内部接管),控制 loading 用 buttonLoading。
416
+
417
+ ### 9.2 WdConfirmButton
418
+ - props: WdApiButton 全部 + confirmText = '确认执行该操作?' / cancelText = '取消'(置空字符串则不显示取消按钮)/ confirmTitle = '提示'
419
+ - emits: buttonApiEmits + confirm / cancel
420
+ - 行为: ElMessageBox.confirm,type 固定 warning;「确定」按钮文案固定不可配。
421
+
422
+ ### 9.3 WdPopconfirmButton
423
+ - props: WdApiButton 全部 + popconfirmProps(16 项,见 §7)
424
+ - emits: buttonApiEmits + confirm / cancel / show / hide
425
+ - 行为: tooltip 与 popconfirm 平级(virtual-ref);placement 同时作用于 tooltip 与 popconfirm。
426
+ - 引入: 仅主入口(无子路径,见 §2.3 [陷阱])。
427
+
428
+ ### 9.4 WdPromptButton
429
+ - props: WdApiButton 全部 + promptTitle = '请输入' / promptPlaceholder = '请输入内容' / paramKey = 'value' / promptDefault = ''
430
+ - emits: buttonApiEmits + prompt(value)(无插槽模式)或 confirm(有插槽模式)
431
+ - slots: #content — 存在即切换为自定义内容模式(此时触发 confirm 而非 prompt)
432
+ - 行为: 输入值以 `{ [paramKey]: value }` 浅合并入 apiParam(同名键被覆盖);API 成功才关弹窗,失败保留;弹窗按钮文案固定「确定/取消」。
433
+
434
+ ### 9.5 WdRouteButton
435
+ - props: buttonLabelProp + elButtonProps + tipsProp + filter +
436
+ routeName / routePath / params = {} / query = {} / target = '_self'
437
+ - 行为: routeName 优先于 routePath;target = '_blank' 仅支持 routePath(window.open 拼 query);无 router 环境退化 location.href。
438
+
439
+ ### 9.6 WdTipsButton
440
+ - props: buttonLabelProp + elButtonProps + tipsProp + filter
441
+ - 行为: 提示基座;tips 非空才包裹 el-tooltip。
442
+
443
+ ### 9.7 WdDrawerButton
444
+ - props: WdTipsButton 全部 + mode = 'drawer' | 'dialog' / title / url / data = {} / size = '50%'(弹层宽度)/ direction = 'rtl' / headRefreshDatagrid / filter
445
+ - emits: open / close / confirm(payload 透传)
446
+ - slots: #button(按钮内容);默认插槽 { data, close }(close = 关闭弹层函数);#footer(透传 footerProps,含 close)
447
+ - 行为: 弹层懒挂载(首次点击才渲染);url 模式 data 拼 query。
448
+ - [陷阱] size 被弹层宽度占用 → 控制按钮本身尺寸用 buttonSize。
449
+
450
+ ### 9.8 WdDialogButton(WdDrawerButton 的 dialog 专用简化版)
451
+ - name: WdDialogButton;inheritAttrs = false
452
+ - props: filter / headRefreshDatagrid / tipsProp / label = '' / title = '' / url = '' / data = {} / size = '50%'(对话框宽度)/ type = 'primary' / buttonSize = 'default' / disabled = false
453
+ - emits: open / close / confirm(payload 透传)
454
+ - slots: #button;默认插槽 { data, close };#footer(透传 footerProps)
455
+ - 行为: 内部固定组合 WdDrawer `mode="dialog"`;懒挂载(首次点击 → rendered → nextTick → 打开)。
456
+
457
+ ### 9.9 WdDataGrid
458
+ - props(33):
459
+ ```
460
+ api, apiMethod = 'post', apiParam, active = false [G], dataSource,
461
+ withPager = true, pagerStyle = 'normal', pagerPosition,
462
+ modeSwitch(卡片/表格模式切换), dynamicColumn, columnStorageKey,
463
+ border, stripe, autoHeight, height = 'fix' | string | number,
464
+ rowKey, tableSize, withIndex = true, withSelection, modelValue(已选 v-model),
465
+ selectionKey, withSelectionCart, cartRowKey, cartConfig,
466
+ rowspanKey, rowspanColumn, treeProps, defaultExpandAll,
467
+ tools, toolsPosition = 'right', toolbarPosition = 'left', rowActions, filter
468
+ ```
469
+ - 类型:
470
+ ```ts
471
+ tools = { refresh?, columnSetting?, modeSwitch?, size?, add?, export?, mode? = 'round', buttonSize? }
472
+ cartConfig = { type? = 'dialog', title? = '已选数据', buttonText?, size? = 560, showClear?, showRemove? }
473
+ RowAction = { text: string, command?: string, type?: string }
474
+ treeProps = { children?: string, hasChildren?: string }
475
+ ```
476
+ - emits(11): add / export / row-action({command,row}) / page-change / selection-change / mode-change / loaded / apiBefore / apiAfter / cart-change / update:modelValue
477
+ - slots(5): 默认(列定义,el-table-column 或列配置)/ toolbar { selection, list } / empty / card-item { row, index } / cart-content { list, remove, clear }
478
+ - methods(11): requestApi(extraParam?) / refresh() / search(params) / resetSearch() / getSelection() / clearSelection() / getCartList() / clearCart() / onChangeCurrentpage(page) / onChangePagesize(size) / tableRef(逃生舱 → el-table 实例)
479
+ - 请求参数结构: `{ [pageField]: n, [sizeField]: n, [searchField]: {...条件} }`(字段名见 PageParamConfig)
480
+
481
+ ### 9.10 WdEditableGrid(继承 WdDataGrid 能力)
482
+ - 列配置 EditableColumn(17 字段):
483
+ ```
484
+ prop, label, width, minWidth, align, fixed,
485
+ editor: 'input' | 'number' | 'select' | 'date',
486
+ editable, placeholder, options, min, max, precision,
487
+ required, validator, rules, formatter
488
+ ```
489
+ - 新增 props: editMode = 'cell' | 'row' / saveApi / saveMethod = 'post' / defaultRow / withToolbar / withAdd / withSave / withDelete / withActions / addButtonText = '新增一行' / saveButtonText = '批量保存' / actionWidth = 150
490
+ - 默认差异: rowKey = 'id';border/stripe = true;withIndex = false;tools.refresh = true
491
+ - 脏行机制 [关键]: 新增行恒脏;修改回原值自动取消脏标记;validate/saveAll 只处理脏行;翻页清空编辑态;静态数据深拷贝隔离。
492
+ - methods: saveAll() / validate() / addRow(row?) / getDirtyRows() + WdDataGrid 全套。
493
+
494
+ ### 9.11 WdViewer
495
+ - 项配置 ViewerItem(13 字段):
496
+ ```
497
+ prop, label, span, width, align, labelAlign, slot, render, formatter,
498
+ type: 'text' | 'tag' | 'time' | 'status' | 'image' | 'copy',
499
+ tagColors, timeFormat, imageSize
500
+ ```
501
+ - props: title / column = 3 / border = true / size / labelStyle = { width:'100px', textAlign:'right' } / contentStyle / api / apiMethod = 'get' / apiParam / active = false [G] / data / items / emptyText = '暂无数据'
502
+ - 行为: data(静态)优先于 api;apiParam 变化自动重新请求;标题栏自带大小切换/字段显隐工具。
503
+ - slots: #content { row, data }(全接管);`{prop}-cell` { row, value }(单元格级)
504
+ - methods: requestApi(extraParam?) / getData() / resetData()
505
+
506
+ ### 9.12 WdRequester(命令式请求器)
507
+ - props: modelValue(触发开关)/ url / method = 'post' [G] / params / reqOptions [G]
508
+ - emits: update:modelValue / api-before(abort 函数) / api-success(ApiResult) / api-fail(ApiResult) / api-exception(error) / api-after
509
+ - 行为: 一次性开关语义(modelValue true 触发后自动回 false);新请求自动静默中断旧请求。
510
+
511
+ ### 9.13 WdDataForm
512
+ - props:
513
+ ```
514
+ mode = 'create' | 'edit',
515
+ api(详情加载), apiMethod = 'get', apiParam,
516
+ submitApi, submitMethod = 'post', submitKeys, submitExcludeKeys(数组或逗号字符串),
517
+ active = false [G], confirmLeave = true, withActions = true,
518
+ actionConfig = { resetText, submitText, continueText, closeText, showReset, showContinue },
519
+ headCloseDrawer = true, headRefreshDatagrid, keepFormButton = true,
520
+ rules, labelWidth = '100px', labelPosition = 'right', inline, data, filter
521
+ ```
522
+ - emits: submit-success / submit-fail / load-success / change / close({reason}) / apiBefore({type}) / apiAfter({type})
523
+ - slots: 默认 { model, form };#footer { submit, reset, loading }
524
+ - methods: submitForm(continueNext?) / validate() / resetForm(clearOnly?) / getFormData() / fillForm(data) / requestApi() / isDirty() / beforeLeave() / formRef(逃生舱 → el-form)
525
+ - 行为: 底部操作按钮仅在宿主环境(WdDrawer / iframe 弹层)中显示 [陷阱]。
526
+
527
+ ### 9.14 WdSearchPanel
528
+ - props: collapsible = true / expand(v-model)/ defaultExpand [陷阱: 元数据标注 true,源码实际 false → 需显式传入] / withActions = true / searchText = '搜索' / resetText = '重置' / expandText = '展开' / collapseText = '收起' / labelWidth = '80px' / actionWidth = 'auto' / headRefreshDatagrid / filter
529
+ - emits: search(params) / reset / expand-change / update:expand
530
+ - slots: 默认 { model }(表单项)/ more { model }(折叠区)/ actions { search, reset }
531
+ - methods: resetForm() / getSearchParams() / expand() / collapse()
532
+ - 行为: $attrs 透传 el-form;HTML(无构建)场景可用全局属性 `q`。
533
+
534
+ ### 9.15 WdFormItem
535
+ - props: label / prop / tip / tipPlacement = 'top'
536
+ - slots: 默认 / label
537
+ - 行为: $attrs 透传 el-form-item。
538
+
539
+ ### 9.16 WdSearchItem
540
+ - 同 WdFormItem(SearchPanel 内语义化别名)。
541
+
542
+ ### 9.17 WdDrawer
543
+ - props: containerProps(8)+ mode = 'drawer' | 'dialog' / direction = 'rtl' / origin / reloadOnOpen = false
544
+ - emits: update:modelValue / open / close / confirm({reason}) / iframe-message({type,payload}) / iframe-ready / iframe-dirty({dirty}) / iframe-submit-success
545
+ - slots: 默认 / footer { close }
546
+ - methods: open() / sendToIframe(type, payload?)
547
+ - 行为: url 模式 data 拼 query,iframe ready 后下发 `wd-container:init`;内嵌 iframe 高度 drawer = 100%(min 400px)、dialog = 60vh;append-to-body。
548
+
549
+ ### 9.18 WdIframe
550
+ - props: src / height = '480px' / autoHeight / origin / refreshKey = 0
551
+ - emits: load / message(data)
552
+ - methods: send(message) / refresh()
553
+ - 行为: autoHeight 依赖子页 postMessage 上报 `{ type: 'wd-iframe-height', height }`。
554
+
555
+ ### 9.19 WdPanel
556
+ - props: title / description / collapsible = false / opened = true / shadow = 'hover' / border = true(1.1.1 新增,`:border="false"` 关闭外边框,加 wd-panel--no-border 类)
557
+ - emits: update:opened / change
558
+ - slots: title / extra(内部 @click.stop)/ 默认 / footer
559
+ - 行为: title 属性或 title 插槽存在才渲染头部。
560
+
561
+ ### 9.20 WdSelect
562
+ - props: modelValue / multiple = false / remote = false / filterable = true(默认开启)/ keywordKey = 'keyword' + optionsProps
563
+ - 数据形态: OptionItem 支持对象或基本类型;内部标准化 NormalizedOption { text, value, tips, raw };dataSource 优先于 api;响应 data 为 `{ list }` 结构时自动取 list。
564
+ - emits: optionsEmits
565
+ - slots: 默认 { option, text, value }(自定义选项)
566
+
567
+ ### 9.21 WdAutoComplete
568
+ - props: modelValue = string / valueKey = 'value' / labelKey = 'text' / keywordKey = 'keyword' + optionsProps
569
+ - emits: optionsEmits + select(raw)
570
+ - 行为: api + active = true → 输入即远程搜索;否则首次输入加载一次后本地过滤。
571
+
572
+ ### 9.22 WdCheckboxList
573
+ - props: modelValue = array / buttonStyle = false + optionsProps
574
+ - emits: optionsEmits
575
+
576
+ ### 9.23 WdRadioList
577
+ - props: modelValue = any / buttonStyle = false + optionsProps
578
+ - emits: optionsEmits
579
+
580
+ ### 9.24 WdSwitch
581
+ - props: modelValue = false / api / apiMethod = 'post' / apiParam / paramKey = 'status' / activeValue = true / inactiveValue = false / tips / headRefreshDatagrid / filter
582
+ - 行为: 切换即请求 `{ ...apiParam, [paramKey]: 当前值 }`;[关键] 失败自动回滚(apiFail / apiException 均回滚);无 api 时退化为普通开关。
583
+
584
+ ### 9.25 WdUpload
585
+ - props: api(自动拼 urlPrefix;完整 http(s):// 不拼)/ deleteApi / deleteMethod = 'post' / primaryKey = 'id' / submitButtonText = '开始上传' / buttonText = '点击上传' / accept / limit / multiple = false / autoUpload = true / name = 'file' / data = {} / disabled / showFileList = true / maxSize = 0(MB,0 = 不限)/ modelValue = array / headRefreshDatagrid / filter
586
+ - 记录结构 UploadFileRecord: { name, url, [primaryKey], ...其他 }
587
+ - 行为 [关键]: 走 el-upload 原生 XHR(不经 axios),但自动拼 urlPrefix 并透传 token 头(Authorization: Bearer);上传成功后整个响应 data 挂在文件对象 biz 上,取 data.url / data.path 回显;删除先二次确认,再按 `{ ...data, [primaryKey]: 值 }` 调 deleteApi。
588
+ - methods: submitUpload() / clearFiles()(仅本地)/ addFile(UploadUserFile) / uploadRef(逃生舱 → el-upload)
589
+
590
+ ### 9.26 WdImageUpload
591
+ - props: api / deleteApi / deleteMethod = 'post' / primaryKey = 'id' / maxCount = 8 / thumbnailSize = 100 / preview = true(el-image-viewer)/ accept(默认 image/*)/ maxSize = 5(MB)/ tip / modelValue = string[] / headRefreshDatagrid / filter
592
+ - 行为: [关键] 强制 image/* 校验(改 accept 也绕不过);data 为对象取 data.url/data.path,为字符串直接用;上传失败条目自动移除;达 maxCount 隐藏加号。
593
+ - methods: clearFiles() / uploadRef
594
+
595
+ ### 9.27 WdTips
596
+ - props: tips / type = 'word' | 'box'(默认 word)/ icon / color = '#909399'
597
+ - icon: 仅内置 InfoFilled / WarningFilled / QuestionFilled 三个,其他值回退 InfoFilled。
598
+ - 行为: word 模式 tooltip 固定 dark + top;默认插槽仅 box 模式生效。
599
+
600
+ ### 9.28 WdStation(管理台布局)
601
+ - 类型:
602
+ ```ts
603
+ StationMenuGroup = { key, title, icon?, menus }
604
+ StationMenuItem = { title, icon?, path?, name?, badge?, disabled?, affix?, group?, groupKey?, groupIcon?, children?, [key: string]: any }
605
+ StationTab = { key, title, path?, affix? }
606
+ StationToolbarConfig = { refresh?, settings?, user?, login? } // 各项: 'left' | 'right' | 'none',默认 'right'
607
+ ```
608
+ - props(20):
609
+ ```
610
+ title, logo, menuGroups(array | JSON 字符串,优先), menus(array | JSON 字符串),
611
+ headerMode = 'nav' | 'title', menuMode = 'side' | 'top' | 'none',
612
+ contentMode = 'page' | 'tabs', routerMode = 'auto' | 'router' | 'html',
613
+ collapsible = true, collapsed(v-model), activeGroup, activeMenu,
614
+ openTabs(v-model 受控), userName, userAvatar, copyright,
615
+ footerInfo(v-model), keepAlive = false, toolbarConfig(object | JSON 字符串), filter
616
+ ```
617
+ - 菜单 key 规则 [关键]: `分组key:name||path||title`(内部称 _key,按此优先级取 name → path → title 生成)。
618
+ - emits(13): 含 menu-select / group-change / tab-click / tab-close / update:collapsed / update:openTabs / update:footerInfo 等。
619
+ - slots(12): 默认 / logo { collapsed } / menu-top / menu-bottom / header-left / header-center / header-right / top-menu-left / top-menu-right / tabs-left / tabs-right / footer
620
+ - methods: refresh() / openTab(tab) / closeTab(key)
621
+ - 行为: [陷阱] 父容器必须提供确定高度否则塌陷;affix 标签固定不可关闭;分导台仅 headerMode = 'nav' 且分组数 > 1 时显示;group-change 不触发路由;menuGroups / menus 可直接传 JSON 字符串(HTML 场景)。
622
+
623
+ ================================================================================
624
+ ## 10. 跨 iframe 协议(POSTMESSAGE PROTOCOL)
625
+ ================================================================================
626
+ 宿主(WdDrawer/WdIframe)与 iframe 子页通过 postMessage 通信:
627
+ ```
628
+ wd-container:ready 子页 → 宿主:子页就绪
629
+ wd-container:init 宿主 → 子页:下发初始化数据(Drawer url 模式 data)
630
+ wd-container:dirty 子页 → 宿主:表单脏状态 { dirty: boolean }
631
+ wd-container:submit-success 子页 → 宿主:提交成功(宿主据此关闭/联动刷新)
632
+ wd-iframe-height 子页 → 宿主(WdIframe):高度上报 { type, height },autoHeight 依赖
633
+ ```
634
+ 宿主 API: WdDrawer.sendToIframe(type, payload?) / WdIframe.send(message)。
635
+ 宿主事件: iframe-message({type,payload}) / iframe-ready / iframe-dirty({dirty}) / iframe-submit-success(WdDrawer);message(data)(WdIframe)。
636
+
637
+ ================================================================================
638
+ ## 11. 陷阱清单(PITFALLS — 开发前必读)
639
+ ================================================================================
640
+ 1. API 类按钮(ApiButton 系):外部透传 `loading` 无效,组件内部接管;控制用 `buttonLoading`。
641
+ 2. WdDrawerButton / WdDialogButton:`size` 是弹层宽度;按钮自身尺寸用 `buttonSize`。
642
+ 3. `active` 默认值不一致:optionsProps.active = true;WdDataGrid.active / WdViewer.active / WdDataForm.active = false(需远程加载时显式开启)。
643
+ 4. WdSwitch:请求失败自动回滚状态(apiFail / apiException 都回滚),无需手动恢复。
644
+ 5. WdStation:菜单 key 规则 `分组key:name||path||title`;父容器必须给定确定高度(flex/定高),否则塌陷。
645
+ 6. WdSearchPanel:defaultExpand 元数据标注 true 与源码 false 不一致 → 需要默认展开时显式 `:default-expand="true"` 或 v-model:expand。
646
+ 7. WdUpload:上传走 el-upload 原生 XHR(不经 axios 实例拦截器),但自动拼 urlPrefix + 透传 Authorization: Bearer token;删除有二次确认。
647
+ 8. WdEditableGrid:翻页清空未保存编辑态;静态 dataSource 会被深拷贝(改源数据不生效,需重新赋值);saveAll/validate 只处理脏行。
648
+ 9. WdViewer:data(静态)优先于 api;apiParam 变化自动重拉。
649
+ 10. WdPromptButton:API 失败弹窗保留不关闭(成功才关)。
650
+ 11. WdPopconfirmButton:无独立子路径入口,仅主入口导出。
651
+ 12. 全局配置在组件挂载时缓存:运行中改配置只影响新挂载组件;已挂载组件用 :key 强制重建。
652
+ 13. WdDataForm:底部操作按钮仅在宿主环境(Drawer/iframe 弹层)显示;独立页面内使用需自建按钮并用 methods。
653
+ 14. WdConfirmButton:ElMessageBox type 固定 warning;「确定」按钮文案固定不可配(cancelText 置空可隐藏取消按钮)。
654
+ 15. WdImageUpload:强制 image/* 校验,accept 改为非图片也绕不过;modelValue 为 string[](非对象数组)。
655
+ 16. 业务失败(code 未达 successCode)Promise 仍然 resolve(success=false),只有网络/运行异常才 reject — 不要用 try/catch 捕获业务失败。
656
+ 17. WdTips.icon 仅支持 3 个内置图标名,其他值静默回退 InfoFilled。
657
+ 18. optionsProps 中的 `tipsProp` 是「选项 tips 字段名」(string),与按钮的 tipsProp 组(tips/tipsType/placement)同名不同义。
658
+ 19. WdRequester:method / reqOptions 支持 page.componentDefault.WdRequester 全局覆盖;新请求自动中断旧请求。
659
+ 20. 并发去重 dedup 默认开启:method+url+params 完全一致的并发请求只发一次;需要强制多次时传 `dedup: false`。
660
+ 21. theme.skin 未知值不抛错:仅 console.warn 并忽略 skin(§4.4);排查「皮肤没生效」先看控制台告警。
661
+
662
+ ================================================================================
663
+ ## 12. 典型组合模式(USAGE PATTERNS)
664
+ ================================================================================
665
+ ### 12.1 搜索 + 表格 + 操作按钮(同组联动)
666
+ ```vue
667
+ <wd-search-panel filter="user" head-refresh-datagrid>
668
+ <wd-search-item label="姓名" prop="name"><el-input v-model="m.name" /></wd-search-item>
669
+ </wd-search-panel>
670
+ <wd-data-grid ref="grid" api="/user/list" :active="true" filter="user" :row-actions="[{text:'删除',command:'del'}]" @row-action="onAction" />
671
+ <wd-api-button label="新增" api="/user/save" head-refresh-datagrid />
672
+ ```
673
+ ### 12.2 弹层表单(按钮 → Drawer → DataForm → 自动回刷)
674
+ ```vue
675
+ <wd-drawer-button label="编辑" url="/form.html" :data="{ id: row.id }" head-refresh-datagrid />
676
+ <!-- 弹层内: <wd-data-form submit-api="/user/save" @submit-success="..."> -->
677
+ ```
678
+ ### 12.3 命令式请求
679
+ ```vue
680
+ <wd-requester v-model="trigger" url="/api/refresh" method="post" @api-success="onOk" />
681
+ ```
682
+
683
+ ================================================================================
684
+ ## 版本变化
685
+ ================================================================================
686
+ - V_1.2(2026-09-24 13:44:41):对齐 workdesktop-ai@1.1.1 —— §1 版本号更新;§2.4 导出面补 SKIN_PRESETS/getSkinPreset/listSkins/SkinPreset;§4.2 theme 扩展为 ThemeConfig(新增 skin 键);新增 §4.4 预设皮肤(11 套 SkinName、SkinPreset 结构、3 个 API、覆盖优先级、El 派生色阶自动推导、组件级令牌回退链);§9.19 WdPanel 补 border prop;§11 陷阱清单 20 → 21 条。
687
+ - V_1.1(2026-09-16 22:03:47):校正 §4.2 配置结构 —— ResponseConfig.props 键名更正为 codeName/messageName/dataName(对齐 src/lib/configs/default-config.ts);request 配置块补全 urlPrefix/throwException/dedup/loading/axiosConfig/transform;theme 明确 colors/cssVars 结构。
688
+ - V_1.0(2026-09-16 19:45:30):首版。覆盖 workdesktop-ai@1.0.2 全量事实:包结构、3 种引入方式(27 子路径 + 14 独立样式对照)、WorkDesktopConfig 完整结构与 6 配置 API、统一响应协议、RequestAPI/request/useRequest、声明式联动(6 + 3 函数)、共享 Props/Emits 组、28 组件详目(含 api-meta 缺失的 WdDialogButton,源自源码核对)、跨 iframe 协议、20 条陷阱清单、3 个典型组合模式。