@hupan56/wlkj 2.6.0 → 2.7.1

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 (125) hide show
  1. package/bin/cli.js +269 -11
  2. package/package.json +1 -1
  3. package/templates/qoder/agents/insight-planning.md +67 -0
  4. package/templates/qoder/agents/insight-research.md +61 -0
  5. package/templates/qoder/agents/prd-reference.md +8 -2
  6. package/templates/qoder/commands/optional/wl-insight.md +275 -0
  7. package/templates/qoder/commands/{wl-report.md → optional/wl-report.md} +13 -5
  8. package/templates/qoder/commands/{wl-spec.md → optional/wl-spec.md} +1 -1
  9. package/templates/qoder/commands/{wl-status.md → optional/wl-status.md} +28 -2
  10. package/templates/qoder/commands/wl-code.md +10 -2
  11. package/templates/qoder/commands/wl-commit.md +1 -1
  12. package/templates/qoder/commands/wl-design-draw.md +78 -0
  13. package/templates/qoder/commands/wl-design-scan.md +108 -0
  14. package/templates/qoder/commands/wl-design-spec.md +154 -0
  15. package/templates/qoder/commands/wl-design.md +32 -0
  16. package/templates/qoder/commands/wl-init.md +24 -3
  17. package/templates/qoder/commands/wl-prd-full.md +226 -0
  18. package/templates/qoder/commands/wl-prd-quick.md +134 -0
  19. package/templates/qoder/commands/wl-prd-review.md +104 -0
  20. package/templates/qoder/commands/wl-prd.md +17 -311
  21. package/templates/qoder/commands/wl-search.md +66 -30
  22. package/templates/qoder/commands/wl-task.md +290 -59
  23. package/templates/qoder/commands/wl-test.md +92 -24
  24. package/templates/qoder/config.yaml +51 -15
  25. package/templates/qoder/hooks/inject-workflow-state.py +2 -2
  26. package/templates/qoder/hooks/session-start.py +82 -51
  27. package/templates/qoder/rules/wl-pipeline.md +216 -105
  28. package/templates/qoder/scripts/__pycache__/search_index.cpython-39.pyc +0 -0
  29. package/templates/qoder/scripts/archive_prd.py +377 -0
  30. package/templates/qoder/scripts/autotest.py +1715 -0
  31. package/templates/qoder/scripts/autotest_batch.py +224 -0
  32. package/templates/qoder/scripts/autotest_run.py +297 -0
  33. package/templates/qoder/scripts/benchmark.py +210 -209
  34. package/templates/qoder/scripts/build_style_index.py +444 -4
  35. package/templates/qoder/scripts/check_carriers.py +238 -0
  36. package/templates/qoder/scripts/check_mcp.py +298 -0
  37. package/templates/qoder/scripts/check_qoderwork_consistency.py +166 -0
  38. package/templates/qoder/scripts/common/events.py +46 -0
  39. package/templates/qoder/scripts/common/extract.py +419 -0
  40. package/templates/qoder/scripts/common/graph_traverse.py +533 -0
  41. package/templates/qoder/scripts/common/paths.py +89 -0
  42. package/templates/qoder/scripts/common/pip_install.py +144 -0
  43. package/templates/qoder/scripts/common/platform_guard.py +61 -0
  44. package/templates/qoder/scripts/common/search_engine.py +205 -205
  45. package/templates/qoder/scripts/common/terms.py +57 -0
  46. package/templates/qoder/scripts/common/ts_extract.py +536 -0
  47. package/templates/qoder/scripts/context_pack.py +73 -13
  48. package/templates/qoder/scripts/enrich_prompt.py +226 -0
  49. package/templates/qoder/scripts/eval_prd.py +318 -231
  50. package/templates/qoder/scripts/export.py +487 -487
  51. package/templates/qoder/scripts/extract_api_params.py +246 -0
  52. package/templates/qoder/scripts/extract_routes.py +54 -0
  53. package/templates/qoder/scripts/extract_routes_tree.py +78 -0
  54. package/templates/qoder/scripts/fill_prototype.py +707 -0
  55. package/templates/qoder/scripts/gen_design_doc.py +394 -0
  56. package/templates/qoder/scripts/git_sync.py +27 -15
  57. package/templates/qoder/scripts/init_doctor.py +292 -40
  58. package/templates/qoder/scripts/install_qoderwork.py +366 -9
  59. package/templates/qoder/scripts/kg.py +708 -0
  60. package/templates/qoder/scripts/kg_auto_login.py +196 -0
  61. package/templates/qoder/scripts/kg_build.py +612 -0
  62. package/templates/qoder/scripts/kg_build_db.py +327 -0
  63. package/templates/qoder/scripts/kg_duckdb.py +549 -0
  64. package/templates/qoder/scripts/kg_incremental.py +393 -0
  65. package/templates/qoder/scripts/kg_link_db.py +224 -0
  66. package/templates/qoder/scripts/kg_mcp_server.py +801 -0
  67. package/templates/qoder/scripts/kg_semantic.py +150 -0
  68. package/templates/qoder/scripts/kg_test_runner.py +241 -0
  69. package/templates/qoder/scripts/lanhu_stdio_wrapper.py +119 -0
  70. package/templates/qoder/scripts/learn.py +118 -39
  71. package/templates/qoder/scripts/learn_aggregate.py +201 -0
  72. package/templates/qoder/scripts/mcp_launcher.py +359 -0
  73. package/templates/qoder/scripts/mysql_mcp_server.py +396 -0
  74. package/templates/qoder/scripts/repo_root.py +106 -0
  75. package/templates/qoder/scripts/role.py +12 -0
  76. package/templates/qoder/scripts/run_weekly_update.bat +5 -0
  77. package/templates/qoder/scripts/run_weekly_update.sh +5 -0
  78. package/templates/qoder/scripts/search_index.py +307 -60
  79. package/templates/qoder/scripts/secure-ls.js +5640 -0
  80. package/templates/qoder/scripts/setup.py +706 -641
  81. package/templates/qoder/scripts/setup_lanhu.py +963 -0
  82. package/templates/qoder/scripts/status.py +250 -11
  83. package/templates/qoder/scripts/sync_carriers.py +259 -0
  84. package/templates/qoder/scripts/syncgate.py +2 -2
  85. package/templates/qoder/scripts/task.py +75 -0
  86. package/templates/qoder/scripts/team_sync.py +60 -4
  87. package/templates/qoder/scripts/workspace_init.py +1 -1
  88. package/templates/qoder/skills/design-import/SKILL.md +226 -0
  89. package/templates/qoder/skills/design-import/figma-workflow.md +81 -0
  90. package/templates/qoder/skills/design-review/SKILL.md +82 -25
  91. package/templates/qoder/skills/prd-generator/SKILL.md +184 -60
  92. package/templates/qoder/skills/prd-review/SKILL.md +18 -1
  93. package/templates/qoder/skills/prompt-enrich/SKILL.md +90 -0
  94. package/templates/qoder/skills/prototype-generator/SKILL.md +256 -141
  95. package/templates/qoder/skills/prototype-generator/SKILL.md.zcode-79180-2af4721f-f9a6-412c-88db-c0af680d211b.tmp +0 -0
  96. package/templates/qoder/skills/spec-coder/SKILL.md +18 -1
  97. package/templates/qoder/skills/spec-generator/SKILL.md +18 -1
  98. package/templates/qoder/skills/test-generator/SKILL.md +15 -2
  99. package/templates/qoder/skills/wl-code/SKILL.md +55 -36
  100. package/templates/qoder/skills/wl-commit/SKILL.md +89 -76
  101. package/templates/qoder/skills/wl-design/SKILL.md +55 -0
  102. package/templates/qoder/skills/wl-init/SKILL.md +76 -67
  103. package/templates/qoder/skills/wl-insight/SKILL.md +201 -81
  104. package/templates/qoder/skills/wl-prd-full/SKILL.md +69 -0
  105. package/templates/qoder/skills/wl-prd-quick/SKILL.md +49 -0
  106. package/templates/qoder/skills/wl-prd-review/SKILL.md +34 -0
  107. package/templates/qoder/skills/wl-report/SKILL.md +131 -107
  108. package/templates/qoder/skills/wl-search/SKILL.md +141 -75
  109. package/templates/qoder/skills/wl-spec/SKILL.md +49 -39
  110. package/templates/qoder/skills/wl-status/SKILL.md +83 -61
  111. package/templates/qoder/skills/wl-task/SKILL.md +132 -58
  112. package/templates/qoder/skills/wl-test/SKILL.md +406 -40
  113. package/templates/qoder/templates/prototype-app.html +13 -8
  114. package/templates/qoder/templates/prototype-web.html +376 -93
  115. package/templates/root/AGENTS.md +89 -34
  116. package/templates/root/requirements.txt +21 -0
  117. package/templates/root//344/275/277/347/224/250/350/257/264/346/230/216.md +259 -259
  118. package/templates/root//346/226/260/346/211/213/346/214/207/345/215/227.md +186 -186
  119. package/templates/qoder/agents/prd-planning.md +0 -57
  120. package/templates/qoder/agents/prd-research.md +0 -34
  121. package/templates/qoder/commands/wl-insight.md +0 -51
  122. package/templates/qoder/scripts/__pycache__/init_doctor.cpython-39.pyc +0 -0
  123. package/templates/qoder/scripts/__pycache__/setup.cpython-39.pyc +0 -0
  124. package/templates/qoder/scripts/common/__pycache__/developer.cpython-39.pyc +0 -0
  125. package/templates/qoder/skills/wl-prd/SKILL.md +0 -92
@@ -6,86 +6,307 @@
6
6
  <title>{{TITLE}} - Web 管理端</title>
7
7
  <style>
8
8
  :root {
9
- /* Vben Admin Design Tokens */
10
- --primary: 212 100% 45%;
11
- --primary-light: 212 100% 95%;
12
- --destructive: 359.33 100% 65.1%;
13
- --success: 144 57% 58%;
14
- --warning: 42 84% 61%;
15
-
9
+ /* Vben Admin Design Tokens. These mirror
10
+ data/index/style-index.json layout_fingerprint.color_primary
11
+ (ICS = hsl(214.58, 86.34%, 59.8%)). DO NOT hardcode #1890ff. */
12
+ --primary: 214.58 86.34% 59.8%;
13
+ --primary-light: 214.58 86.34% 95%;
14
+ --destructive: 0 100% 68.04%;
15
+ --success: 100.15 53.97% 49.41%;
16
+ --warning: 36 100% 63.73%;
17
+
16
18
  --background: 0 0% 100%;
17
19
  --background-deep: 216 20.11% 95.47%;
18
20
  --card: 0 0% 100%;
19
-
21
+
20
22
  --foreground: 210 6% 21%;
21
23
  --muted-foreground: 240 3.8% 46.1%;
22
-
24
+
23
25
  --border: 240 5.9% 90%;
24
26
  --input: 240deg 5.88% 90%;
25
-
26
- --radius: 0.5rem;
27
+
28
+ --radius: 0.25rem;
27
29
  --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
30
+
31
+ /* mixed-nav shell widths (mirror ICS sidebar.width=160) */
32
+ --topbar-height: 56px;
33
+ --sidebar-width: 160px;
28
34
  }
29
-
35
+
30
36
  * { margin: 0; padding: 0; box-sizing: border-box; }
31
-
37
+
32
38
  body {
33
39
  font-family: var(--font-family);
34
40
  background: hsl(var(--background-deep));
35
41
  color: hsl(var(--foreground));
36
42
  min-height: 100vh;
37
43
  }
38
-
39
- .layout {
44
+
45
+ /* ============================================================
46
+ mixed-nav layout shell (Vben 'mixed-nav'):
47
+ 顶部栏 = logo + 一级菜单 + 右侧操作
48
+ 左侧栏 = 当前一级下的二级菜单 (可折叠出三级)
49
+ 主区 = 面包屑 + 标签页 tab(三四级) + 内容
50
+ 这是 ICS 的真实布局骨架。生成时务必保留三段式结构,
51
+ 不要退化成扁平单级 sidebar。
52
+ ============================================================ */
53
+ .app-shell {
40
54
  display: flex;
55
+ flex-direction: column;
41
56
  min-height: 100vh;
42
57
  }
43
-
58
+
59
+ /* --- 顶部栏 --- */
60
+ .topbar {
61
+ height: var(--topbar-height);
62
+ display: flex;
63
+ align-items: center;
64
+ background: hsl(var(--background));
65
+ border-bottom: 1px solid hsl(var(--border));
66
+ padding: 0 16px;
67
+ flex-shrink: 0;
68
+ gap: 16px;
69
+ }
70
+
71
+ .topbar-logo {
72
+ display: flex;
73
+ align-items: center;
74
+ gap: 8px;
75
+ font-weight: 600;
76
+ font-size: 15px;
77
+ white-space: nowrap;
78
+ color: hsl(var(--foreground));
79
+ }
80
+
81
+ .topbar-logo .logo-mark {
82
+ width: 28px;
83
+ height: 28px;
84
+ border-radius: 6px;
85
+ background: hsl(var(--primary));
86
+ display: inline-flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ color: #fff;
90
+ font-size: 14px;
91
+ }
92
+
93
+ /* 一级菜单:横向 tab */
94
+ .top-menu {
95
+ display: flex;
96
+ align-items: center;
97
+ gap: 4px;
98
+ flex: 1;
99
+ height: 100%;
100
+ overflow-x: auto;
101
+ }
102
+
103
+ .top-menu-item {
104
+ height: 100%;
105
+ display: flex;
106
+ align-items: center;
107
+ padding: 0 14px;
108
+ cursor: pointer;
109
+ color: hsl(var(--muted-foreground));
110
+ font-size: 14px;
111
+ white-space: nowrap;
112
+ border-bottom: 2px solid transparent;
113
+ transition: all 0.2s;
114
+ }
115
+
116
+ .top-menu-item:hover {
117
+ color: hsl(var(--primary));
118
+ }
119
+
120
+ .top-menu-item.active {
121
+ color: hsl(var(--primary));
122
+ border-bottom-color: hsl(var(--primary));
123
+ font-weight: 500;
124
+ }
125
+
126
+ .topbar-right {
127
+ display: flex;
128
+ align-items: center;
129
+ gap: 12px;
130
+ flex-shrink: 0;
131
+ }
132
+
133
+ .topbar-right .icon-btn {
134
+ width: 32px;
135
+ height: 32px;
136
+ display: inline-flex;
137
+ align-items: center;
138
+ justify-content: center;
139
+ border-radius: var(--radius);
140
+ cursor: pointer;
141
+ color: hsl(var(--muted-foreground));
142
+ }
143
+
144
+ .topbar-right .icon-btn:hover {
145
+ background: hsl(var(--background-deep));
146
+ }
147
+
148
+ .topbar-right .avatar {
149
+ width: 30px;
150
+ height: 30px;
151
+ border-radius: 50%;
152
+ background: hsl(var(--primary) / 0.15);
153
+ color: hsl(var(--primary));
154
+ display: inline-flex;
155
+ align-items: center;
156
+ justify-content: center;
157
+ font-size: 13px;
158
+ font-weight: 500;
159
+ }
160
+
161
+ /* --- 主体 = 左侧栏 + 主区 --- */
162
+ .body-area {
163
+ display: flex;
164
+ flex: 1;
165
+ min-height: 0;
166
+ }
167
+
44
168
  .sidebar {
45
- width: 200px;
169
+ width: var(--sidebar-width);
46
170
  background: hsl(var(--background));
47
171
  border-right: 1px solid hsl(var(--border));
48
- padding: 16px 0;
172
+ padding: 8px 0;
173
+ flex-shrink: 0;
174
+ overflow-y: auto;
49
175
  }
50
-
176
+
177
+ /* 二级菜单项 */
51
178
  .sidebar-item {
52
- padding: 12px 24px;
179
+ padding: 10px 16px;
53
180
  cursor: pointer;
54
181
  color: hsl(var(--muted-foreground));
182
+ font-size: 14px;
55
183
  transition: all 0.2s;
184
+ display: flex;
185
+ align-items: center;
186
+ gap: 8px;
56
187
  }
57
-
188
+
58
189
  .sidebar-item:hover,
59
190
  .sidebar-item.active {
60
191
  background: hsl(var(--primary-light));
61
192
  color: hsl(var(--primary));
62
193
  }
63
-
194
+
195
+ .sidebar-item.active {
196
+ font-weight: 500;
197
+ border-left: 3px solid hsl(var(--primary));
198
+ }
199
+
200
+ /* 三级菜单:用原生 <details> 折叠,零 JS 依赖 */
201
+ .sidebar-group > summary {
202
+ list-style: none;
203
+ cursor: pointer;
204
+ padding: 10px 16px;
205
+ color: hsl(var(--muted-foreground));
206
+ font-size: 14px;
207
+ display: flex;
208
+ align-items: center;
209
+ justify-content: space-between;
210
+ transition: all 0.2s;
211
+ }
212
+
213
+ .sidebar-group > summary::-webkit-details-marker { display: none; }
214
+
215
+ .sidebar-group > summary:hover {
216
+ background: hsl(var(--primary-light));
217
+ color: hsl(var(--primary));
218
+ }
219
+
220
+ .sidebar-group > summary::after {
221
+ content: '›';
222
+ transform: rotate(90deg);
223
+ transition: transform 0.2s;
224
+ font-size: 14px;
225
+ }
226
+
227
+ .sidebar-group[open] > summary::after {
228
+ transform: rotate(-90deg);
229
+ }
230
+
231
+ /* 三级菜单子项(缩进) */
232
+ .sidebar-sub {
233
+ padding-left: 16px;
234
+ }
235
+
236
+ .sidebar-sub .sidebar-item {
237
+ font-size: 13px;
238
+ padding-left: 20px;
239
+ }
240
+
241
+ /* --- 主区 --- */
64
242
  .main-content {
65
243
  flex: 1;
66
- padding: 24px;
244
+ display: flex;
245
+ flex-direction: column;
246
+ min-width: 0;
67
247
  }
68
-
248
+
249
+ /* 标签页 tabbar(承载三四级页面切换) */
250
+ .tabbar {
251
+ display: flex;
252
+ align-items: center;
253
+ gap: 4px;
254
+ padding: 6px 12px;
255
+ background: hsl(var(--background));
256
+ border-bottom: 1px solid hsl(var(--border));
257
+ overflow-x: auto;
258
+ flex-shrink: 0;
259
+ }
260
+
261
+ .tab-item {
262
+ padding: 5px 12px;
263
+ font-size: 13px;
264
+ color: hsl(var(--muted-foreground));
265
+ cursor: pointer;
266
+ border-radius: var(--radius);
267
+ white-space: nowrap;
268
+ display: inline-flex;
269
+ align-items: center;
270
+ gap: 6px;
271
+ transition: all 0.2s;
272
+ }
273
+
274
+ .tab-item.active {
275
+ background: hsl(var(--primary-light));
276
+ color: hsl(var(--primary));
277
+ }
278
+
279
+ .tab-item .tab-close {
280
+ opacity: 0.5;
281
+ font-size: 12px;
282
+ }
283
+
284
+ .content-scroll {
285
+ flex: 1;
286
+ overflow-y: auto;
287
+ padding: 20px 24px;
288
+ }
289
+
69
290
  .breadcrumb {
70
291
  margin-bottom: 16px;
71
292
  color: hsl(var(--muted-foreground));
72
293
  font-size: 14px;
73
294
  }
74
-
295
+
75
296
  .breadcrumb span { color: hsl(var(--primary)); }
76
-
297
+
77
298
  .page-header {
78
299
  display: flex;
79
300
  justify-content: space-between;
80
301
  align-items: center;
81
302
  margin-bottom: 16px;
82
303
  }
83
-
304
+
84
305
  .page-title {
85
306
  font-size: 20px;
86
307
  font-weight: 600;
87
308
  }
88
-
309
+
89
310
  .card {
90
311
  background: hsl(var(--card));
91
312
  border-radius: var(--radius);
@@ -93,17 +314,17 @@
93
314
  padding: 16px;
94
315
  margin-bottom: 16px;
95
316
  }
96
-
317
+
97
318
  /* VxeGrid Table Style */
98
319
  .vxe-table {
99
320
  width: 100%;
100
321
  border-collapse: collapse;
101
322
  }
102
-
323
+
103
324
  .vxe-table-header {
104
325
  background: hsl(220deg 13% 95%);
105
326
  }
106
-
327
+
107
328
  .vxe-table-header th {
108
329
  padding: 12px 16px;
109
330
  text-align: left;
@@ -111,16 +332,16 @@
111
332
  color: hsl(0deg 0% 12%);
112
333
  border-bottom: 1px solid hsl(0deg 0% 94%);
113
334
  }
114
-
335
+
115
336
  .vxe-table-body td {
116
337
  padding: 12px 16px;
117
338
  border-bottom: 1px solid hsl(var(--border));
118
339
  }
119
-
340
+
120
341
  .vxe-table-body tr:hover {
121
342
  background: hsl(var(--primary) / 0.05);
122
343
  }
123
-
344
+
124
345
  /* Search Form */
125
346
  .search-form {
126
347
  display: flex;
@@ -132,19 +353,19 @@
132
353
  border-radius: var(--radius);
133
354
  border: 1px solid hsl(var(--border));
134
355
  }
135
-
356
+
136
357
  .form-item {
137
358
  display: flex;
138
359
  align-items: center;
139
360
  gap: 8px;
140
361
  }
141
-
362
+
142
363
  .form-item label {
143
364
  font-size: 14px;
144
365
  color: hsl(var(--muted-foreground));
145
366
  white-space: nowrap;
146
367
  }
147
-
368
+
148
369
  .form-item input,
149
370
  .form-item select {
150
371
  height: 32px;
@@ -155,14 +376,14 @@
155
376
  font-size: 14px;
156
377
  min-width: 200px;
157
378
  }
158
-
379
+
159
380
  .form-item input:focus,
160
381
  .form-item select:focus {
161
382
  outline: none;
162
383
  border-color: hsl(var(--primary));
163
384
  box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
164
385
  }
165
-
386
+
166
387
  /* Buttons */
167
388
  .btn {
168
389
  height: 32px;
@@ -173,59 +394,59 @@
173
394
  border: 1px solid transparent;
174
395
  transition: all 0.2s;
175
396
  }
176
-
397
+
177
398
  .btn-primary {
178
399
  background: hsl(var(--primary));
179
400
  color: white;
180
401
  }
181
-
402
+
182
403
  .btn-primary:hover {
183
404
  background: hsl(var(--primary) / 0.9);
184
405
  }
185
-
406
+
186
407
  .btn-outline {
187
408
  background: transparent;
188
409
  border-color: hsl(var(--border));
189
410
  color: hsl(var(--foreground));
190
411
  }
191
-
412
+
192
413
  .btn-outline:hover {
193
414
  border-color: hsl(var(--primary));
194
415
  color: hsl(var(--primary));
195
416
  }
196
-
417
+
197
418
  .btn-danger {
198
419
  background: hsl(var(--destructive));
199
420
  color: white;
200
421
  }
201
-
422
+
202
423
  .actions {
203
424
  display: flex;
204
425
  gap: 8px;
205
426
  }
206
-
427
+
207
428
  .tag {
208
429
  display: inline-block;
209
430
  padding: 2px 8px;
210
431
  border-radius: 4px;
211
432
  font-size: 12px;
212
433
  }
213
-
434
+
214
435
  .tag-success {
215
436
  background: hsl(var(--success) / 0.1);
216
437
  color: hsl(var(--success));
217
438
  }
218
-
439
+
219
440
  .tag-warning {
220
441
  background: hsl(var(--warning) / 0.1);
221
442
  color: hsl(var(--warning));
222
443
  }
223
-
444
+
224
445
  .tag-danger {
225
446
  background: hsl(var(--destructive) / 0.1);
226
447
  color: hsl(var(--destructive));
227
448
  }
228
-
449
+
229
450
  .pagination {
230
451
  display: flex;
231
452
  justify-content: flex-end;
@@ -233,7 +454,7 @@
233
454
  gap: 8px;
234
455
  margin-top: 16px;
235
456
  }
236
-
457
+
237
458
  .page-btn {
238
459
  width: 32px;
239
460
  height: 32px;
@@ -245,13 +466,13 @@
245
466
  background: hsl(var(--background));
246
467
  cursor: pointer;
247
468
  }
248
-
469
+
249
470
  .page-btn.active {
250
471
  background: hsl(var(--primary));
251
472
  color: white;
252
473
  border-color: hsl(var(--primary));
253
474
  }
254
-
475
+
255
476
  /* Highlight changed areas */
256
477
  .highlight-new {
257
478
  border: 2px dashed hsl(var(--primary));
@@ -260,51 +481,113 @@
260
481
  </style>
261
482
  </head>
262
483
  <body>
263
- <div class="layout">
264
- <div class="sidebar">
265
- <div class="sidebar-item active">{{MODULE_NAME}}</div>
266
- <div class="sidebar-item">其他模块...</div>
267
- </div>
268
-
269
- <div class="main-content">
270
- <div class="breadcrumb">
271
- 首页 / {{MODULE_NAME}} / <span>{{PAGE_NAME}}</span>
484
+ <div class="app-shell">
485
+
486
+ <!-- ===================== 顶部栏 + 一级菜单 ===================== -->
487
+ <!-- layout=mixed-nav: 一级菜单横向排在顶部。{{TOP_MENU}} 填一级菜单项,
488
+ 当前模块用 class="top-menu-item active"。 -->
489
+ <header class="topbar">
490
+ <div class="topbar-logo">
491
+ <span class="logo-mark">I</span>
492
+ <span>{{LOGO_TEXT}}</span>
272
493
  </div>
273
-
274
- <div class="page-header">
275
- <h1 class="page-title">{{PAGE_NAME}}</h1>
276
- <div class="actions">
277
- <button class="btn btn-outline">导出</button>
278
- <button class="btn btn-primary">新增</button>
494
+
495
+ <nav class="top-menu">
496
+ {{TOP_MENU}}
497
+ <!-- 示例(替换为你的一级菜单,当前模块加 active):
498
+ <div class="top-menu-item">概览</div>
499
+ <div class="top-menu-item active">{{MODULE_NAME}}</div>
500
+ <div class="top-menu-item">系统管理</div>
501
+ -->
502
+ </nav>
503
+
504
+ <div class="topbar-right">
505
+ <div class="icon-btn" title="搜索">
506
+ <svg width="16" height="16" viewBox="0 0 1024 1024" fill="currentColor"><path d="M909.6 854.5L649.9 594.8C690.2 538.6 714 470.2 714 396c0-176.7-143.3-320-320-320S74 219.3 74 396s143.3 320 320 320c74.2 0 142.6-23.8 198.8-64.1l259.7 259.6c9.4 9.4 24.6 9.4 33.9 0l22.7-22.7c9.3-9.3 9.3-24.5.5-33.3zM154 396c0-132.1 107.9-240 240-240s240 107.9 240 240-107.9 240-240 240S154 528.1 154 396z"/></svg>
507
+ </div>
508
+ <div class="icon-btn" title="通知">
509
+ <svg width="16" height="16" viewBox="0 0 1024 1024" fill="currentColor"><path d="M880 112c-30.9 0-56 25.1-56 56v320c0 159.1-128.9 288-288 288S248 647.1 248 488V168c0-30.9-25.1-56-56-56s-56 25.1-56 56v320c0 206.1 156.9 375.1 358 396.7V928H328c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h416c13.3 0 24-10.7 24-24v-16c0-13.3-10.7-24-24-24H570V884.7C771.1 863.1 928 694.1 928 488V168c0-30.9-25.1-56-56-56z"/></svg>
279
510
  </div>
511
+ <div class="avatar">U</div>
280
512
  </div>
281
-
282
- <div class="card">
283
- <div class="search-form">
284
- {{SEARCH_FORM_FIELDS}}
513
+ </header>
514
+
515
+ <div class="body-area">
516
+
517
+ <!-- ===================== 左侧栏:二级 + 三级菜单 ===================== -->
518
+ <!-- {{SIDEBAR_MENU}} 填当前一级模块下的二级菜单。
519
+ 三级用 <details class="sidebar-group"><summary>..</summary>
520
+ <div class="sidebar-sub">三级项</div></details> 折叠(原生,零JS)。
521
+ 当前页对应的项加 class="sidebar-item active"。 -->
522
+ <aside class="sidebar">
523
+ {{SIDEBAR_MENU}}
524
+ <!-- 示例多级结构(替换为你的真实菜单层级):
525
+ <div class="sidebar-item active">{{PAGE_NAME}}</div>
526
+ <details class="sidebar-group">
527
+ <summary>二级菜单A</summary>
528
+ <div class="sidebar-sub">
529
+ <div class="sidebar-item">三级菜单A-1</div>
530
+ <div class="sidebar-item">三级菜单A-2</div>
531
+ </div>
532
+ </details>
533
+ <div class="sidebar-item">二级菜单B</div>
534
+ -->
535
+ </aside>
536
+
537
+ <!-- ===================== 主区:标签页 + 内容 ===================== -->
538
+ <main class="main-content">
539
+
540
+ <!-- 标签页 tabbar(承载三四级页面切换) -->
541
+ <div class="tabbar">
542
+ {{TABS}}
543
+ <!-- 示例(当前页加 active):
544
+ <div class="tab-item active">{{PAGE_NAME}} <span class="tab-close">×</span></div>
545
+ <div class="tab-item">其他页签 <span class="tab-close">×</span></div>
546
+ -->
285
547
  </div>
286
-
287
- <table class="vxe-table">
288
- <thead class="vxe-table-header">
289
- <tr>
290
- {{TABLE_HEADERS}}
291
- </tr>
292
- </thead>
293
- <tbody class="vxe-table-body">
294
- {{TABLE_ROWS}}
295
- </tbody>
296
- </table>
297
-
298
- <div class="pagination">
299
- <span>共 100 条</span>
300
- <div class="page-btn">1</div>
301
- <div class="page-btn">2</div>
302
- <div class="page-btn">3</div>
303
- <div class="page-btn">...</div>
304
- <div class="page-btn">10</div>
548
+
549
+ <div class="content-scroll">
550
+ <div class="breadcrumb">
551
+ 首页 / {{MODULE_NAME}} / <span>{{PAGE_NAME}}</span>
552
+ </div>
553
+
554
+ <div class="page-header">
555
+ <h1 class="page-title">{{PAGE_NAME}}</h1>
556
+ <div class="actions">
557
+ <button class="btn btn-outline">导出</button>
558
+ <button class="btn btn-primary">新增</button>
559
+ </div>
560
+ </div>
561
+
562
+ <div class="card">
563
+ <div class="search-form">
564
+ {{SEARCH_FORM_FIELDS}}
565
+ </div>
566
+
567
+ <table class="vxe-table">
568
+ <thead class="vxe-table-header">
569
+ <tr>
570
+ {{TABLE_HEADERS}}
571
+ </tr>
572
+ </thead>
573
+ <tbody class="vxe-table-body">
574
+ {{TABLE_ROWS}}
575
+ </tbody>
576
+ </table>
577
+
578
+ <div class="pagination">
579
+ <span>共 100 条</span>
580
+ <div class="page-btn">1</div>
581
+ <div class="page-btn active">2</div>
582
+ <div class="page-btn">3</div>
583
+ <div class="page-btn">...</div>
584
+ <div class="page-btn">10</div>
585
+ </div>
586
+ </div>
305
587
  </div>
306
- </div>
588
+ </main>
589
+
307
590
  </div>
308
591
  </div>
309
592
  </body>
310
- </html>
593
+ </html>