@qilitt-mickey/vue3-temp-skill 1.1.40 → 1.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +10 -1
- package/mapping/scenes/admin/content.json +50 -5
- package/mapping/scenes/admin/layout.json +80 -8
- package/package.json +1 -1
- package/references/code-quality.md +10 -6
- package/references/crud-pages.md +35 -9
- package/references/design-apply.md +83 -8
- package/parser/regression-run.log +0 -0
package/SKILL.md
CHANGED
|
@@ -83,6 +83,7 @@ tags: [vue3, typescript, element-plus, pinia, vite, unocss, crud, demo, code-qua
|
|
|
83
83
|
使用者默认**不懂设计也不懂代码**,交互遵守四条:
|
|
84
84
|
|
|
85
85
|
1. **全自动默认**:识别为设计文件落地后**直接开始执行 parser match → 结构 → 样式 → 闸门全流程**,不等用户逐步确认,不询问"是否继续";唯一停顿点是文件缺失/版本不匹配/parser 报错——此时用大白话报告并给选择题。
|
|
86
|
+
**禁止以「待确认」搁置可落地项**:词典缺 ID / 缺字段枚举 / 缺 form 属**能力缺口**,当场补临时映射并落地(出厂文件仅在补通道时可动,交付说明单列申报);只有「设计侧没给值」才是**意图缺口**,去向是回流设计侧补齐,不是问用户要不要做。
|
|
86
87
|
2. **术语不对用户出现**:对用户不说"变更集/语义 ID/三级匹配/pending/令牌"——说"设计方案/设计点位/自动适配/新增点位/全局样式"。这些词只出现在内部文档与交付说明里。
|
|
87
88
|
3. **无文件时的引导**:用户说"全系统改成 XX 风格"但没给设计文件 → 提示一句话:"请先在设计助手(project-ui-design 技能)里说『我要 XX 风格的全系统设计』拿到设计文件,再回来发给我"。如果本机同时装有设计技能,可直接引导用户回到设计会话完成设计,再回本项目落地。
|
|
88
89
|
4. **交付话术**:完成后用大白话总结(改了哪些页面/哪些地方变了/怎么验收),不输出施工坐标等技术细节;验收引导统一为"运行 `pnpm dev` 打开页面对照看效果,哪里不满意直接说"。
|
|
@@ -93,6 +94,14 @@ tags: [vue3, typescript, element-plus, pinia, vite, unocss, crud, demo, code-qua
|
|
|
93
94
|
- 在目标项目执行 `pnpm lint:fix`、`pnpm type-check`;改动构建配置时再执行 `pnpm build`。
|
|
94
95
|
- 最终说明:命中能力组、修改文件、功能验证、命令结果、未解决问题和下一步。
|
|
95
96
|
|
|
97
|
+
## 出厂中性 · 变更集驱动(design-apply 架构红线)
|
|
98
|
+
|
|
99
|
+
目标项目源码 = **中性初始化**,只提供能力通道(CSS 变量的消费者挂载点、form 枚举、DOM/属性钩子、正确的层叠优先级),**不预置任何具体设计的结论**(某个颜色、某句问候语、某个方位的指示条、某个硬编码尺寸)。
|
|
100
|
+
|
|
101
|
+
- 一切设计决策由设计变更集驱动,经 `design-apply` 动态落到「设计层文件 `src/styles/design-shell.scss` / 页面级 scoped 样式 / DOM 属性与配置」,不落到出厂样式文件与出厂组件里。
|
|
102
|
+
- 判据:换一张效果图只需换变更集、不必改源码 ⇒ 架构正确;需要改源码才能换 ⇒ 设计结论被烧进源码,必须回退为通道。
|
|
103
|
+
- 出厂文件仅在「通道缺失」时可动(补变量消费者 / 补 form 枚举 / 修层叠优先级),且必须在交付说明中单列「补通道」条目写明缺失点。
|
|
104
|
+
|
|
96
105
|
## 项目事实优先级
|
|
97
106
|
|
|
98
107
|
`目标项目当前源码` > `目标项目 package.json / 锁文件` > `本 Skill reference` > `通用 Vue 习惯`。
|
|
@@ -118,5 +127,5 @@ tags: [vue3, typescript, element-plus, pinia, vite, unocss, crud, demo, code-qua
|
|
|
118
127
|
- 功能:...
|
|
119
128
|
- `pnpm lint:fix`:通过 | 失败(原因)
|
|
120
129
|
- `pnpm type-check`:通过 | 失败(原因)
|
|
121
|
-
-
|
|
130
|
+
- 缺口回流:无 | 仅限「设计侧未给值」的维度(列出维度名,注明已回流设计侧补齐)
|
|
122
131
|
```
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"admin.content.container": {
|
|
12
12
|
"type": "element",
|
|
13
13
|
"selector": ".main-content[data-content-mode='fixed'], .main-content[data-content-mode='scroll'], .main-content:has(.vts-page-card), .main-content:has(.vts-page-fill)",
|
|
14
|
-
"file": "src/layout/components/lay-content/index.vue
|
|
14
|
+
"file": "src/layout/components/lay-content/index.vue(滚动归属:data-content-mode 显式优先,自动探测带 :not([data-content-mode]) 守卫兜底)+ src/styles/element-plus.scss(填满通道:中性属性 [data-fill])",
|
|
15
15
|
"style_scope": ":global(壳层样式,非 scoped 页面样式)",
|
|
16
16
|
"css_vars": {
|
|
17
17
|
"content_padding": "--vts-margin",
|
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
"modes": {
|
|
27
27
|
"fixed": "data-content-mode='fixed':display:flex; flex:1 1 auto; height:100%; min-height:0; overflow:hidden(收回 el-scrollbar__view/.grow 祖先链)",
|
|
28
28
|
"scroll": "data-content-mode='scroll':flex:0 0 auto; min-height:100%; overflow:visible(整页滚动)",
|
|
29
|
-
"auto": ":has(.vts-page-card|.vts-page-fill) 自动定高;未标记且无钩子类 →
|
|
30
|
-
}
|
|
29
|
+
"auto": ":has(.vts-page-card|.vts-page-fill) 自动定高;未标记且无钩子类 → 滚动页(向后兼容)。自动分支带 :not([data-content-mode]) 守卫,与显式声明互斥"
|
|
30
|
+
},
|
|
31
|
+
"$note": "⚠列表区保命通道(**结构层**,设计还原禁止改写):**滚动归属** = 页面根节点 data-content-mode(fixed/scroll 优先;未声明走 :has() 自动探测兜底,自动分支带 :not([data-content-mode]) 守卫与显式声明互斥——显式 scroll 的页面内含 .vts-page-card 时定高分支不得反压,否则整页滚动断裂)。**填满剩余高度** = 中性属性 data-fill(element-plus.scss 已实现:display:flex; flex:1 1 auto; min-height:0; overflow:hidden;data-fill=\"row\" 横向分栏),从页面根到表格/画布容器之间**每个需填满的层级节点**都要挂。⚠**结构/视觉解耦(本通道存在的意义)**:定高链只认属性不认类名 ⇒ 视觉容器可被设计层整体替换(el-card.vts-page-card → 通栏 div / 自绘容器),换容器时把 data-fill 平移到新容器及其「体」层即可,高度链不断、useTableSearch 几何实测照常、表格自滚动正常。双向禁止:① 改写壳层结构层规则(lay-content 的 .main-content[data-content-mode]、element-plus.scss 的 [data-fill])来换还原效果;② 以「保高度」为由拒绝设计改容器/内边距/去卡片。⚠壳层 lay-content 禁止硬编码 data-content-mode(曾因壳层代打 scroll 压掉自动探测,vts-page-card 列表页定高链断裂、useTableSearch 高度失准、列表区整体崩坏——已实证回退)。出厂 DOM 不带模式属性(中性),换设计只换页面根节点的声明值与 data-fill 挂载点。"
|
|
31
32
|
},
|
|
32
33
|
"admin.content.page_header": {
|
|
33
34
|
"type": "element",
|
|
@@ -102,9 +103,53 @@
|
|
|
102
103
|
"nowrap": "white-space",
|
|
103
104
|
"divider_width": "width",
|
|
104
105
|
"divider_height": "height",
|
|
105
|
-
"
|
|
106
|
+
"divider_margin_x": "margin-inline",
|
|
107
|
+
"more_arrow_size": "font-size",
|
|
108
|
+
"more_arrow_gap": "gap"
|
|
109
|
+
},
|
|
110
|
+
"$note": "设计意图(list-page §5/§26.14/§11.52-11.60):纯文字链接无图标、短分割线隔离(1px×14px、左右 margin 0 8px)、≥3 个折叠到更多(带 10px 下拉箭头、箭头↔文字 gap 2px)、列宽 160px + nowrap 禁止换行。⚠ **按钮之间的间距由分割线的 divider_margin_x 承载**(不是按钮自身 gap)——设计侧不声明该字段,项目侧无从还原图上间距,这是「操作列间距没还原」的根因。落地断言:form 即结构意图(design-apply 底线二豁免)——form=text_link 时必须删除业务页列定义 operateButtons 各项的 icon 字段,禁止只改 CSS 保留图标冒充落地;设计侧未声明 min_width/column_width 时 AI 施工必须回填出厂值 160px/nowrap 并在交付说明注明,禁止留空导致按钮换行"
|
|
111
|
+
},
|
|
112
|
+
"admin.content.table.header_cell": {
|
|
113
|
+
"type": "element",
|
|
114
|
+
"selector": ".vts-table-area .el-table__header th.el-table__cell",
|
|
115
|
+
"file": "src/styles/element-plus.scss(Element Plus 表头结构类,无业务定制类)",
|
|
116
|
+
"style_scope": ".vts-page-card",
|
|
117
|
+
"css_vars": {
|
|
118
|
+
"bg": "--el-table-header-bg-color",
|
|
119
|
+
"text": "--el-table-header-text-color"
|
|
120
|
+
},
|
|
121
|
+
"custom_style_map": {
|
|
122
|
+
"height": "height",
|
|
123
|
+
"padding": "padding",
|
|
124
|
+
"font_weight": "font-weight",
|
|
125
|
+
"font_size": "font-size",
|
|
126
|
+
"text_align": "text-align",
|
|
127
|
+
"border_bottom": "border-bottom",
|
|
128
|
+
"nowrap": "white-space"
|
|
129
|
+
},
|
|
130
|
+
"$note": "设计意图(list-page §11.39):高 48px、padding 16px、背景 #FAFAFA、字号 14px、**字重 500**、文字色 #000000E0、**左对齐**、底边框 1px solid #F0F0F0、nowrap、吸顶。⚠ 出厂 EP 默认表头是**居中 + 字重 400**,且只有底色/文字色可经 --el-table-* 令牌换 —— **font-weight 与 text-align 必须走本条目 custom_style_map 生成规则**,只改令牌落不了这两项,这是「表头样式不对」的根因。作用域前缀 .vts-page-card 保证只命中业务卡片内表格。"
|
|
131
|
+
},
|
|
132
|
+
"admin.content.table.cell_status": {
|
|
133
|
+
"type": "element",
|
|
134
|
+
"selector": ".vts-table-area .el-table__cell .el-tag",
|
|
135
|
+
"file": "业务 views(状态列,Element Plus el-tag 渲染)",
|
|
136
|
+
"style_scope": ".vts-page-card",
|
|
137
|
+
"forms": {
|
|
138
|
+
"filled": "浅色背景 + 浅边框 + 语义色文字(设计规范默认变体,list-page §7)",
|
|
139
|
+
"outlined": "透明背景 + 语义色边框 + 语义色文字",
|
|
140
|
+
"solid": "纯色填充 + 白字",
|
|
141
|
+
"with_icon": "filled + 16px 语义图标"
|
|
142
|
+
},
|
|
143
|
+
"css_vars": {},
|
|
144
|
+
"custom_style_map": {
|
|
145
|
+
"bg": "background-color",
|
|
146
|
+
"border_color": "border-color",
|
|
147
|
+
"text_color": "color",
|
|
148
|
+
"font_size": "font-size",
|
|
149
|
+
"icon_size": "font-size",
|
|
150
|
+
"radius": "border-radius"
|
|
106
151
|
},
|
|
107
|
-
"$note": "设计意图(list-page §
|
|
152
|
+
"$note": "设计意图(list-page §7 / §11.64-11.75):默认 **filled** 变体,五态取值 = success #F6FFED / 1px #D9F7BE / #52C41A / check-circle;processing 主色-1 / 主色-3 / 主色-5 / sync;warning #FFFBE6 / #FFE58F / #FAAD14 / exclamation-circle;error #FFF1F0 / #FFCCC2 / #FF4D4F / close-circle;default rgba(0,0,0,0.04) / #F0F0F0 / #000000A6 / clock-circle(图标 16px)。⚠ 出厂 demo 该列多为**纯文本或 el-tag 默认色**——变体与五态配色必须由变更集显式声明,否则停留在默认蓝/灰,这是「列中状态样式不对」的根因。通用 Tag 规范见 component.tag.status;≥3 个 Tag 列时按「四选二」逐列分配(list-page §8)。"
|
|
108
153
|
},
|
|
109
154
|
"admin.content.table.cell_amount": {
|
|
110
155
|
"type": "element",
|
|
@@ -53,6 +53,13 @@
|
|
|
53
53
|
"selector": ".sidebar-container .el-menu",
|
|
54
54
|
"file": "src/layout/components/lay-sidebar/NavVertical.vue",
|
|
55
55
|
"style_scope": ".sidebar-container",
|
|
56
|
+
"forms": {
|
|
57
|
+
"pill": "出厂默认:整块胶囊底色高亮(sidebar.scss 消费 --vts-theme-menu-active-bg,带 !important)",
|
|
58
|
+
"indicator_left": "左侧竖条指示:先在本作用域覆写 --vts-theme-menu-active-bg: transparent 关胶囊,再于设计层新建 ::after 竖条(left:0)消费 --vts-theme-menu-active-before",
|
|
59
|
+
"indicator_right": "右侧竖条指示:同上关胶囊后 ::after 挂 right:0;不要用 factory 残留锚点 --menu-active-border-right(出厂未定义该令牌)",
|
|
60
|
+
"indicator_underline": "底部横线指示:关胶囊后 ::after 挂 bottom:0(宽取 100% 或指定宽度,厚取 indicator_thickness)",
|
|
61
|
+
"none": "无指示:胶囊与竖条均关闭,仅文字变色"
|
|
62
|
+
},
|
|
56
63
|
"css_vars": {
|
|
57
64
|
"menu_bg": "--vts-theme-menu-bg",
|
|
58
65
|
"menu_text": "--vts-theme-menu-text",
|
|
@@ -67,9 +74,10 @@
|
|
|
67
74
|
},
|
|
68
75
|
"custom_style_map": {
|
|
69
76
|
"active_indicator_width": "width",
|
|
77
|
+
"active_indicator_thickness": "height",
|
|
70
78
|
"active_indicator_style": "border-radius"
|
|
71
79
|
},
|
|
72
|
-
"$note": "侧栏配色挂载点为 html[data-theme='xxx'](theme.scss 8 套预设);设计输出深色侧栏 → Theme=default + Version++(useTheme 规则),浅色 → Theme=light
|
|
80
|
+
"$note": "侧栏配色挂载点为 html[data-theme='xxx'](theme.scss 8 套预设);设计输出深色侧栏 → Theme=default + Version++(useTheme 规则),浅色 → Theme=light。⚠文本完整性红线:菜单项名称必须完整显示(el-menu 自带 ellipsis 折叠溢出菜单),禁止改 menu 文本截断/隐藏策略;item_height 加大时确认行高不挤压文字。宽度类改动(--sidebar-width)后必须目视验证长菜单名显示。⚠激活态出厂中性基线(禁止把某张图的结论写进源码):出厂形态 = pill 胶囊高亮;--vts-theme-menu-active-before 出厂默认 transparent 且**全项目无消费者**(死通道)。因此 form=indicator_* 时必须在本条目 style_scope 内成对落地两件事才算施工完成——① 覆写 --vts-theme-menu-active-bg: transparent 关胶囊;② 在设计层文件(不可写出厂 sidebar.scss)新建 ::after 消费者引用 var(--vts-theme-menu-active-before)。缺任一项 = 「映射了却没效果」。所有几何参数(方位/粗细/长度/圆角/内缩)取自变更集 style 字段,禁止写死 left:0 / 3px 等常量。"
|
|
73
81
|
},
|
|
74
82
|
"admin.layout.sidebar.collapse_trigger": {
|
|
75
83
|
"type": "element",
|
|
@@ -206,13 +214,15 @@
|
|
|
206
214
|
"selector": ".set-icon",
|
|
207
215
|
"file": "src/layout/components/lay-navbar/index.vue",
|
|
208
216
|
"style_scope": ".navbar",
|
|
217
|
+
"visible_prop": "无出厂配置开关(出厂常显)",
|
|
209
218
|
"css_vars": {
|
|
210
219
|
"height": "--vts-bar-height"
|
|
211
220
|
},
|
|
212
221
|
"custom_style_map": {
|
|
213
222
|
"icon_size": "font-size",
|
|
214
223
|
"width": "width"
|
|
215
|
-
}
|
|
224
|
+
},
|
|
225
|
+
"$note": "存在性收口默认对象:效果图未出现该按钮时,变更集以 visible:false 声明 → 落地为设计层文件内 .navbar .set-icon { display:none }(禁止删出厂代码行、禁止直接改 lay-navbar/index.vue 表达「这张图不要按钮」)。反向:设计需要该按钮时不声明即可(出厂已常显)。同一 DOM(含 v-tippy 提示)通用,图标/尺寸经本条目 style 字段动态覆盖。"
|
|
216
226
|
},
|
|
217
227
|
"admin.layout.header.user_profile": {
|
|
218
228
|
"type": "component",
|
|
@@ -220,8 +230,15 @@
|
|
|
220
230
|
"selector": ".navbar-right .el-dropdown-link",
|
|
221
231
|
"file": "src/layout/components/lay-navbar/index.vue",
|
|
222
232
|
"style_scope": ".navbar",
|
|
233
|
+
"forms": {
|
|
234
|
+
"avatar_name": "出厂默认:22×22 头像 + 用户名(window.userName),无问候语",
|
|
235
|
+
"greeting_avatar_name": "问候语 + 用户名 + 头像(问候节点出厂不存在 → 由 AI 按本 form 在 lay-navbar 用户区增量插入,属结构通道施工)",
|
|
236
|
+
"greeting_name": "问候语 + 用户名,无头像",
|
|
237
|
+
"avatar_only": "仅头像",
|
|
238
|
+
"name_only": "仅用户名"
|
|
239
|
+
},
|
|
223
240
|
"sub_selectors": {
|
|
224
|
-
"$comment": "avatar/name 为点位内部部件,不设独立语义 ID(符合 4 段 ID
|
|
241
|
+
"$comment": "avatar/name 为点位内部部件,不设独立语义 ID(符合 4 段 ID 上限);样式字段按前缀路由到对应选择器。form 含 greeting 时新增节点统一用 class 前缀 vts-header-greeting / vts-header-username(插入前先查重名)",
|
|
225
242
|
"avatar": ".navbar-right .el-dropdown-link img",
|
|
226
243
|
"name": ".navbar-right .el-dropdown-link p"
|
|
227
244
|
},
|
|
@@ -235,8 +252,11 @@
|
|
|
235
252
|
"avatar_radius": "border-radius",
|
|
236
253
|
"name_font_size": "font-size",
|
|
237
254
|
"name_font_weight": "font-weight",
|
|
255
|
+
"greeting_font_size": "font-size",
|
|
256
|
+
"greeting_font_weight": "font-weight",
|
|
238
257
|
"gap": "gap"
|
|
239
|
-
}
|
|
258
|
+
},
|
|
259
|
+
"$note": "⚠出厂中性基线:出厂 DOM 只有「头像 img + 用户名 p」,**没有任何问候语节点**(词典曾误记 .header-welcome 已实现,属虚假前提)。因此 form 含 greeting 时必须走结构增量新增 DOM,且节点文案模板(时段问候语 + 用户名)由业务层提供,本点位只承载组合形态与样式——禁止把具体问候文案写进组件。反向同理:设计只要纯头像/纯用户名时以 form=avatar_only/name_only 声明,出厂多余节点同样按收口处理(隐藏不删)。"
|
|
240
260
|
},
|
|
241
261
|
"admin.layout.tabs": {
|
|
242
262
|
"type": "module",
|
|
@@ -246,8 +266,9 @@
|
|
|
246
266
|
"visible_prop": "HideTabs(platform-config.json)",
|
|
247
267
|
"children": ["admin.layout.tabs.home_tab", "admin.layout.tabs.item", "admin.layout.tabs.context_menu"],
|
|
248
268
|
"forms": {
|
|
249
|
-
"chrome": "谷歌页签(出厂 ShowModel=chrome
|
|
250
|
-
"card": "卡片页签(ShowModel=card)"
|
|
269
|
+
"chrome": "谷歌页签(出厂 ShowModel=chrome):SVG 梯形外形 + .chrome-tab-divider(1px×14px 深色)+ 关闭钮 16px 主色;激活态白字 + box-shadow",
|
|
270
|
+
"card": "卡片页签(ShowModel=card):圆角卡片底 + --vts-tag-card-* 整组令牌 + 关闭钮 hover 才显现(出厂 opacity:0)",
|
|
271
|
+
"flat": "平面页签(设计规范口径,出厂无此形态):ShowModel 仍设 card(复用 card 结构 = 图标槽 + 关闭钮 + resolveCardTabIcon 数据驱动),平面观感全部由设计层覆写达成 —— ① --vts-tag-card-idle-bg/hover-bg/active-bg 置 transparent;② --vts-tag-card-radius 与 --vts-tag-card-gap 置 0;③ 激活态仅文字/图标变主色 + font-weight 500,不加 border-bottom / box-shadow;④ 关闭钮 opacity 覆写为常显值(出厂 card 为 0);⑤ 首页页签项宽=高=--vts-tag-card-height 居中呈方块;⑥ 页签间 1px×100% 贯穿分割线(card 无该元素,需设计层 ::after/::before 新建)。几何与色值一律取自变更集 style 字段,禁止写死常量"
|
|
251
272
|
},
|
|
252
273
|
"css_vars": {
|
|
253
274
|
"height": "--tabs-height",
|
|
@@ -273,7 +294,11 @@
|
|
|
273
294
|
"selector": ".tags-view .scroll-item:nth-child(1)",
|
|
274
295
|
"file": "src/layout/components/lay-tag/index.vue(首页页签 = multiTags 首项;真实 DOM 无 .home-item 类)",
|
|
275
296
|
"style_scope": ".tags-view",
|
|
276
|
-
"
|
|
297
|
+
"forms": {
|
|
298
|
+
"icon_only": "出厂默认:首位渲染 home 图标(meta.icon 缺省回退 'home'),无标题文字",
|
|
299
|
+
"text": "纯文字首位页签(隐藏图标且不占位)"
|
|
300
|
+
},
|
|
301
|
+
"$comment": "真实 DOM:.scroll-item(首项)> .card-tab,图标经 resolveCardTabIcon 渲染 svg-icon.card-tab-icon。出厂解析规则是数据驱动的:index===0 回退 'home',其余按 meta.icon 有无渲染(空则不渲染不占位)——因此「有无图标」是-menu 数据/变更集可动态决定的,不是源码常量。尺寸类意图(如 40×40)由变更集 style 字段给出,词典不预设具体设计值。",
|
|
277
302
|
"css_vars": {
|
|
278
303
|
"width": "--vts-tag-card-height",
|
|
279
304
|
"height": "--vts-tag-card-height"
|
|
@@ -290,7 +315,11 @@
|
|
|
290
315
|
"selector": ".tags-view .scroll-item:not(:nth-child(1))",
|
|
291
316
|
"file": "src/layout/components/lay-tag/index.vue(业务页签 = multiTags 非首项;真实 DOM 无 .tags-view-item 类)",
|
|
292
317
|
"style_scope": ".tags-view",
|
|
293
|
-
"
|
|
318
|
+
"forms": {
|
|
319
|
+
"text_only": "出厂默认:业务页签纯文字(meta.icon 为空 → 不渲染不占位)",
|
|
320
|
+
"with_icon": "业务页签带图标(由路由 meta.icon 驱动显示)"
|
|
321
|
+
},
|
|
322
|
+
"$comment": "真实 DOM:.scroll-item.is-closable > .card-tab(title + el-icon-close),激活态类 .is-active。⚠出厂中性基线:图标显隐由 resolveCardTabIcon 按 meta.icon 数据驱动,不是源码写死;「某张图要求业务页签无图标」必须以 form=text_only 显式声明后由变更集落地(隐藏 .card-tab-icon 且不占位),词典不预置任何设计的结论。间距/关闭钮尺寸/激活态表现等参数一律由当次变更集 style 字段给出。",
|
|
294
323
|
"css_vars": {
|
|
295
324
|
"card_height": "--vts-tag-card-height",
|
|
296
325
|
"card_radius": "--vts-tag-card-radius",
|
|
@@ -305,11 +334,54 @@
|
|
|
305
334
|
"custom_style_map": {
|
|
306
335
|
"padding_x": "padding-inline",
|
|
307
336
|
"divider_color": "border-left-color",
|
|
337
|
+
"title_gap": "gap",
|
|
308
338
|
"close_size": "font-size",
|
|
339
|
+
"close_opacity": "opacity",
|
|
309
340
|
"close_hover_color": "color"
|
|
310
341
|
},
|
|
311
342
|
"$note": "card 形态专属令牌挂在父级 admin.layout.tabs 的 css_vars(整组切换);本条目为页签项级字段补充。chrome 形态梯形样式为模板结构样式,不走样式映射"
|
|
312
343
|
},
|
|
344
|
+
"admin.layout.tabs.item_active": {
|
|
345
|
+
"type": "element",
|
|
346
|
+
"selector": ".tags-view .scroll-item.is-active",
|
|
347
|
+
"file": "src/layout/components/lay-tag/index.vue",
|
|
348
|
+
"style_scope": ".tags-view",
|
|
349
|
+
"forms": {
|
|
350
|
+
"text_color_only": "仅文字/图标变色 + 字重加重(设计规范口径,unified-framework §6.46:font-weight 500、无下划线、无 border-bottom、无 box-shadow)",
|
|
351
|
+
"with_bg": "带底色块(出厂 card 形态即此:--vts-tag-card-active-bg)",
|
|
352
|
+
"with_underline": "带下划线/底线(出厂未实现,需设计层 ::after 新建并取变更集几何字段)"
|
|
353
|
+
},
|
|
354
|
+
"sub_selectors": {
|
|
355
|
+
"title": ".tags-view .scroll-item.is-active .tag-title",
|
|
356
|
+
"icon": ".tags-view .scroll-item.is-active .card-tab-icon"
|
|
357
|
+
},
|
|
358
|
+
"css_vars": {
|
|
359
|
+
"active_text": "--vts-tag-card-active-text",
|
|
360
|
+
"active_bg": "--vts-tag-card-active-bg"
|
|
361
|
+
},
|
|
362
|
+
"custom_style_map": {
|
|
363
|
+
"text_color": "color",
|
|
364
|
+
"font_weight": "font-weight",
|
|
365
|
+
"underline_height": "height",
|
|
366
|
+
"underline_color": "background-color"
|
|
367
|
+
},
|
|
368
|
+
"$note": "⚠出厂中性基线:chrome 形态激活态 = 白字 + box-shadow + 主色底(.scroll-item.is-active:not(.card-item)),card 形态 = --vts-tag-card-active-bg 底 + active-text 文字;**两者都不等于设计规范的「仅文字变色 + 字重 500、无下划线」**。form=text_color_only 时必须在设计层显式覆写出厂的 box-shadow / 背景块,缺任一项 = 激活态样式不对。card 形态专属令牌挂在父级 admin.layout.tabs 的 css_vars(整组切换)。"
|
|
369
|
+
},
|
|
370
|
+
"admin.layout.tabs.divider": {
|
|
371
|
+
"type": "element",
|
|
372
|
+
"selector": "chrome 形态:.chrome-tab .chrome-tab-divider;card / flat 形态:无独立元素(需设计层新建)",
|
|
373
|
+
"file": "src/layout/components/lay-tag/index.vue",
|
|
374
|
+
"style_scope": ".tags-view",
|
|
375
|
+
"$comment": "真实 DOM:chrome 形态有 .chrome-tab-divider(position:absolute; right:7px; width:1px; height:14px; background-color:#2b2d2f;激活时 opacity:0),card 形态无分割线元素、用 --vts-tag-card-gap 间距代替。设计规范要求页签之间 1px×100% 贯穿分割线(unified-framework §6.47),与出厂两种形态都不符。",
|
|
376
|
+
"css_vars": {},
|
|
377
|
+
"custom_style_map": {
|
|
378
|
+
"width": "width",
|
|
379
|
+
"height": "height",
|
|
380
|
+
"bg": "background-color",
|
|
381
|
+
"opacity": "opacity"
|
|
382
|
+
},
|
|
383
|
+
"$note": "落地口径:chrome 形态可直接覆写 .chrome-tab-divider 的 background-color / height(含激活态 opacity 还原);card / flat 形态须在设计层用 .tags-view .scroll-item:not(:first-child)::before 新建竖线并消费变更集 width/height/bg。禁止把某张图的分割线参数(如 1px×100% #F0F0F0)写进出厂源码——那是单张图的结论。"
|
|
384
|
+
},
|
|
313
385
|
"admin.layout.tabs.context_menu": {
|
|
314
386
|
"type": "element",
|
|
315
387
|
"selector": ".tags-view .el-dropdown-menu(页签栏右侧 arrow-down 触发的下拉菜单;el-dropdown 挂 body)",
|
package/package.json
CHANGED
|
@@ -25,7 +25,7 @@ tags: [code-review, quality, checklist, lint, typescript, vue3, security, perfor
|
|
|
25
25
|
- 硬失败:无 | 已拦截并修正:…
|
|
26
26
|
- 已修正:…(无则写「无」)
|
|
27
27
|
- 命令:`pnpm lint:fix` → …;`pnpm type-check` → …
|
|
28
|
-
-
|
|
28
|
+
- 待确认:仅限新依赖审批 / 需用户决策的外部动作(无则写「无」);设计变更集落地项一律不得列此(见 design-apply「零缺口交付」)
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
## 硬失败(对照落盘文件;命中即未通过)
|
|
@@ -125,10 +125,12 @@ lint / type-check **过了也不能放过**下列项。发现即改代码,禁
|
|
|
125
125
|
|
|
126
126
|
### 高度模式与结构约束(改动内容区高度 / DOM 结构时强制)
|
|
127
127
|
|
|
128
|
-
- [ ] 定高页靠 `
|
|
129
|
-
- [ ] `data-content-mode` 声明在路由组件根节点(`class="main-content"` 处),值仅 `fixed` / `scroll
|
|
130
|
-
- [ ]
|
|
131
|
-
- [ ]
|
|
128
|
+
- [ ] 定高页靠 `data-content-mode="fixed"` / `vts-page-card` / `vts-page-fill` 三通道之一,禁止 `calc(100vh - …)` / JS 测顶栏
|
|
129
|
+
- [ ] `data-content-mode` 声明在路由组件根节点(`class="main-content"` 处),值仅 `fixed` / `scroll`;未声明时走自动探测兜底(自动分支带 `:not([data-content-mode])` 守卫,与显式声明互斥)
|
|
130
|
+
- [ ] **填满链完整**:定高页从页面根到表格/画布容器,每层需填满的节点都带 `data-fill`(横向分栏用 `data-fill="row"`);换了视觉容器时属性已平移到新容器,未丢失
|
|
131
|
+
- [ ] **结构层零改动**:`lay-content/index.vue` 的 `.main-content[data-content-mode]` 与 `element-plus.scss` 的 `[data-fill]` 未被设计还原改写(换容器走属性平移,不重写结构层);亦无「为保高度而放弃设计还原」
|
|
132
|
+
- [ ] `useTableSearch` 结构约束不破坏:`content` 绑定定高容器(换容器后仍绑);`otherRef` 在表格上方;分页与表格同容器且在其下方;`multipleTableRef` 绑定 el-table(详见 hook 源码 JSDoc「结构约束」节)
|
|
133
|
+
- [ ] 设计变更集(`admin.content.container` 的 `form` 字段,`fixed` / `scroll` / `auto`)翻译为 `data-content-mode` 属性,不得改用其他自定义属性名
|
|
132
134
|
|
|
133
135
|
### 设计变更集合规(design-apply 时强制,禁止以 N/A 跳过)
|
|
134
136
|
|
|
@@ -138,7 +140,9 @@ lint / type-check **过了也不能放过**下列项。发现即改代码,禁
|
|
|
138
140
|
- [ ] 两层样式全部落在条目 `style_scope` 作用域内,无全局泄漏、无 `!important` 新增
|
|
139
141
|
- [ ] 无内联硬编码色值;全部走 CSS 变量(css_vars 层)或 `:deep()` 隔离(custom_style_map 层)
|
|
140
142
|
- [ ] 新增视觉规则在 `dark.scss` `html.dark` 有对应覆盖
|
|
141
|
-
- [ ]
|
|
143
|
+
- [ ] 能力缺口(词典缺 ID / 缺字段枚举 / 缺 form)已当场落地并写临时映射,未进清单;`缺口清单` 只含意图缺口(设计侧未给值 / 值非法)且已注明回流设计侧;mapping 临时新增后 `node parser/index.js build --dry` 通过
|
|
144
|
+
- [ ] 设计层落点文件 `src/styles/design-shell.scss` 存在且经 `index.scss` 末位 `@use` 加载(缺失即自举重建并申报补通道)
|
|
145
|
+
- [ ] **模板源码注释中性**:对模板文件的改动中,注释只描述「这段代码做什么」;语义 ID / 协议步骤号 / 缺口·自举·申报等面向 AI 的纪律条款不得写入模板源码注释(一律留在技能侧文档)
|
|
142
146
|
|
|
143
147
|
## 代码风格
|
|
144
148
|
|
package/references/crud-pages.md
CHANGED
|
@@ -34,31 +34,56 @@ useTableSearch(formQuery, searchFn, url)
|
|
|
34
34
|
| 长表单 / 详情 / 说明类 | 根节点 `min-height: 100%`(或 `:style="{ minHeight: '100%' }"`);**禁止** `vts-page-fill` / `h-full` / `overflow-hidden`;超出由 `.app-main` 内 `el-scrollbar` 滚动 |
|
|
35
35
|
| 非 Card 整页填满(地图/流程图/大屏) | 根节点加 `class="vts-page-fill"` + `height: 100%` / `h-full`;**仅此类定高场景** |
|
|
36
36
|
| Card 内边距 | 一律走 `--vts-card-padding`(桥接 `--card-padding`);换规范 / `--vts-margin` 变化由壳层 flex 链 + Hook 自动跟随 |
|
|
37
|
+
| 设计还原换容器(卡 → 通栏 / 自绘) | 根节点声明 `data-content-mode="fixed"`;新容器及其「体」层挂 `data-fill`;`content` ref 仍绑该容器;视觉(底色/圆角/边框/内边距)全落设计层——**不得因换容器而放弃设计还原,也不得为保高度而拒绝换容器** |
|
|
37
38
|
|
|
38
|
-
##
|
|
39
|
+
## 高度模式(结构通道:`data-content-mode` + `data-fill`)
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
### 两个通道,一条链
|
|
42
|
+
|
|
43
|
+
| 通道 | 落在哪 | 管什么 |
|
|
44
|
+
|------|--------|--------|
|
|
45
|
+
| `data-content-mode` | 页面根节点(`class="main-content"` 所在节点,即路由组件根) | **滚动归属**:整页滚动还是内容区内部滚动 |
|
|
46
|
+
| `data-fill` | 从根到表格/画布容器之间,每个「需要吃掉父级剩余高度」的层级节点 | **填满剩余高度**(`flex:1 1 auto; min-height:0`);`data-fill="row"` 为横向分栏 |
|
|
47
|
+
|
|
48
|
+
```scss
|
|
49
|
+
/* 出厂已实现(element-plus.scss),页面只需挂属性 */
|
|
50
|
+
[data-fill] { display:flex; flex:1 1 auto; flex-direction:column; min-height:0; overflow:hidden; }
|
|
51
|
+
[data-fill='row'] { flex-direction: row; }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 滚动归属
|
|
55
|
+
|
|
56
|
+
壳层(`lay-content`)在页面根元素上识别 `data-content-mode`,**优先级高于 `:has()` 钩子类自动探测**:
|
|
41
57
|
|
|
42
58
|
| 声明 | 效果 | 适用 |
|
|
43
59
|
|------|------|------|
|
|
44
|
-
| `data-content-mode="fixed"` |
|
|
45
|
-
| `data-content-mode="scroll"` |
|
|
46
|
-
| 不声明 | 走 `:has(.vts-page-card \| .vts-page-fill)`
|
|
60
|
+
| `data-content-mode="fixed"` | 定高页:收回 `el-scrollbar__view` / `.grow` 祖先链,内容区仅内部滚动 | 设计变更集指定定高、或页面结构特殊需绕过 `:has()` 探测 |
|
|
61
|
+
| `data-content-mode="scroll"` | 滚动页:整页滚动,**防止内部误用钩子类触发定高** | 页面含 `vts-page-card` 但实际想整页滚动等冲突场景 |
|
|
62
|
+
| 不声明 | 走 `:has(.vts-page-card \| .vts-page-fill)` 自动探测(默认,向后兼容存量页) | 绝大多数页面 |
|
|
47
63
|
|
|
48
64
|
规则:
|
|
49
65
|
|
|
50
66
|
1. 新建列表页**不需要**显式声明——`vts-page-card` 钩子类自动触发定高;
|
|
51
|
-
2. 设计变更集(语义 ID `admin.content.container`,`
|
|
52
|
-
3.
|
|
67
|
+
2. 设计变更集(语义 ID `admin.content.container`,`form: fixed \| scroll`)通过 parser 翻译为本属性;
|
|
68
|
+
3. 显式声明与自动探测**互斥**(自动分支带 `:not([data-content-mode])` 守卫)——显式 `scroll` 的页面内含 `.vts-page-card` 时,定高分支不得反压;
|
|
53
69
|
4. `useTableSearch` 几何实测要求 `content` 容器处于定高链上——用 `data-content-mode="fixed"` 替代 `vts-page-card` 时同样成立。
|
|
54
70
|
|
|
55
|
-
|
|
71
|
+
### 结构 / 视觉解耦(设计还原保命口径)
|
|
72
|
+
|
|
73
|
+
定高链 = 「**谁定高**」(`data-content-mode`,根节点)+「**谁吸收剩余高度**」(`data-fill`,逐层节点),**只认属性、不认类名**。因此:
|
|
74
|
+
|
|
75
|
+
- **视觉容器可以整体替换**:`el-card.vts-page-card` → 通栏 `div` / 自绘容器都行,只要把 `data-fill` 平移到新容器(及其「体」层)上,高度链不断、`tableHeight` 实测照常;
|
|
76
|
+
- **视觉改(底色 / 圆角 / 边框 / 内边距 / 阴影 / 内部排布)落在设计层**(`src/styles/design-shell.scss` 或页面 scoped),**禁止改写**壳层结构层(`lay-content` 的 `.main-content[data-content-mode]`、`element-plus.scss` 的 `[data-fill]`)来换取还原效果;
|
|
77
|
+
- **禁止反向妥协**:「为了保证高度正常所以保留出厂卡片/内边距不改」= 放弃设计还原,同样不接受。正确做法是换容器 + 平移 `data-fill`。
|
|
78
|
+
|
|
79
|
+
> **壳层原理**(`lay-content`):`.main-content` 用 `padding: var(--vts-margin)`(不用 margin);默认可滚动页 `el-scrollbar__view` / `.grow` 为 `min-height:100%; height:auto`;定高页 `.main-content[data-content-mode='fixed']`(或未声明时 `:has(.vts-page-card|.vts-page-fill)` 兜底)为 `height: 100%` 并收回祖先链;`.vts-page-card` 与其 `el-card__body` 是 `data-fill` 的出厂实施例,填满。`html/body/#app/.app-wrapper/.main-container/.app-main` 均为 `height:100%; overflow:hidden`。禁止业务页 `100vh` 减顶栏定高。
|
|
80
|
+
|
|
56
81
|
|
|
57
82
|
## 列表标准样板(唯一完整示例)
|
|
58
83
|
|
|
59
84
|
| # | 必须 |
|
|
60
85
|
|---|------|
|
|
61
|
-
| L1 | `el-card` + `class="vts-page-card"` + `ref="content"`(禁止挂 `div`) |
|
|
86
|
+
| L1 | `el-card` + `class="vts-page-card"` + `data-fill`(定高链挂载点,换容器时随容器平移)+ `ref="content"`(禁止挂 `div`) |
|
|
62
87
|
| L2 | 不要写 `height: calc(100vh - …)` / 不要用 JS 测顶栏定高(壳层 + `.vts-page-card` 已填满) |
|
|
63
88
|
| L3 | 查询区 `class="vts-filter-area"`(含容器感+分隔线,等效旧 `bg-bg_color p-5`);展示区 `ReTableBar` 外包 `.vts-table-area` |
|
|
64
89
|
| L4 | `ReGrid` `:gap="[0,20]"` + cols;表单项 `w-[100%] !mr-0`;`@should-show-collapse` |
|
|
@@ -146,6 +171,7 @@ function handleSizeChange(size: number) {
|
|
|
146
171
|
<div>
|
|
147
172
|
<el-card
|
|
148
173
|
ref="content"
|
|
174
|
+
data-fill
|
|
149
175
|
class="vts-page-card"
|
|
150
176
|
shadow="never"
|
|
151
177
|
>
|
|
@@ -30,6 +30,30 @@ parser match(确定性翻译)→ 施工坐标 → AI 按坐标改代码 →
|
|
|
30
30
|
|
|
31
31
|
无论哪条来路,落地流程一律走下文「执行流程」。
|
|
32
32
|
|
|
33
|
+
## 出厂中性 · 变更集驱动(架构红线,违反即返工)
|
|
34
|
+
|
|
35
|
+
**同一份模板源码,换一份变更集 = 换一套外观。** 任何「本次设计的结论」都不许固化进源码:
|
|
36
|
+
|
|
37
|
+
| | 允许 | 禁止 |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| 模板源码 | 只提供**能力通道**:CSS 变量的消费者挂载点、form 枚举、DOM/属性钩子、正确的层叠优先级 | 预置**设计结论**:某个具体颜色、某句问候语、某个方位的指示条、某个硬编码尺寸 |
|
|
40
|
+
| 设计产出 | AI 按本协议写入**设计层文件 / 页面级 scoped 样式 / DOM 属性与配置** | 为表达某张效果图而改写出厂样式文件与出厂组件(换设计即失效,且污染模板) |
|
|
41
|
+
|
|
42
|
+
**判据(一句话)**:换一张效果图只需要换变更集、不需要改源码 ⇒ 架构正确;需要改源码才能换 ⇒ 设计结论被烧进了源码,必须回退为通道。
|
|
43
|
+
|
|
44
|
+
- ❌ 反例:把「菜单激活指示条 = 左侧 3px」写死进 `sidebar.scss` / `element-plus.scss`;把问候语 DOM 直接加进 `lay-navbar/index.vue`;出厂 `<component>` 上硬编码 `data-content-mode="scroll"`。
|
|
45
|
+
- ✅ 正例:`admin.layout.sidebar.menu` 暴露 `forms`(pill/indicator_left/indicator_right/indicator_underline/none)+ 几何字段,方位与粗细由变更集驱动;高度模式出厂不带任何属性,由页面根节点按变更集声明。
|
|
46
|
+
|
|
47
|
+
**落地三落点判据**(每个变更字段先判落点再动手):
|
|
48
|
+
|
|
49
|
+
1. **有非样式通道**(DOM 属性 / 组件配置 / `platform-config.json`)→ 必须走该通道(form=scroll/fixed → 页面根节点 `data-content-mode`;form=card → `ShowModel`)。降级写成 SCSS = 未施工。
|
|
50
|
+
2. **无通道且需改 DOM**(新增节点,如问候语欢迎区)→ 结构增量施工(AI 在组件模板内按 `form` 插入,保形插入、不删原代码)。
|
|
51
|
+
3. **纯视觉表达**(颜色/圆角/间距/指示条几何)→ 设计层文件(见第 3 步)。
|
|
52
|
+
|
|
53
|
+
**出厂文件仅在「通道缺失」时才可改动**,且须同时满足:① 补的是能力不是结论(补变量消费者、补 form 枚举、修层叠优先级);② 在交付说明中单列「补通道」条目写明缺失点与修复内容。
|
|
54
|
+
|
|
55
|
+
**模板源码注释保持中性(防污染)**:源码注释只写「这段代码做什么」——给后续维护者看。**禁止把面向 AI 的规范写进模板源码**:语义 ID、变更条目、本协议步骤号、缺口 / 自举 / 申报 / 「设计还原禁止改写本段」这类纪律条款,一律留在技能侧(`crud-pages.md` 结构通道 / `code-quality.md` 清单 / 本节),不得写进 `lay-*.vue`、`element-plus.scss`、`sidebar.scss`、`index.scss`、`design-shell.scss` 等模板文件。判据:**技能侧改了内容不需要动模板 ⇒ 正确**;改一条纪律还要去改模板注释 ⇒ 放错层。落地时技能侧只承诺「这四类通道的能力」(`data-content-mode` / `data-fill` / `design-shell.scss` 落点 / 构图钩子),具体契约与纪律全部由技能文档承载。
|
|
56
|
+
|
|
33
57
|
## 输入契约(变更集 Schema v1.0)
|
|
34
58
|
|
|
35
59
|
```jsonc
|
|
@@ -85,8 +109,17 @@ node parser/index.js match --batch <changesets-dir>
|
|
|
85
109
|
|------|------|------|
|
|
86
110
|
| **L1 完整命中** | ID 在词典中直接命中 | 按条目施工坐标直接落地(预期 100% 还原) |
|
|
87
111
|
| **L2 父级命中** | ID 的父模块命中 | 继承父模块样式约定,按子级定位施工(85-90% 还原) |
|
|
88
|
-
| **L3 未命中** |
|
|
89
|
-
|
|
|
112
|
+
| **L3 未命中** | 词典无此 ID(新增点位) | **当场按第 4 步定制布局落地**并写入 mapping 临时映射;只有设计侧未给完整意图(无值 / 值非法)才进缺口清单 |
|
|
113
|
+
| **字段级未命中** | ID 命中但 `style` 某字段两层映射都查不到 | 值合法且选择器可定位 → **当场生成作用域内自定义规则落设计层文件并申报**;只有「值非法 / 无法定位」才进缺口清单 |
|
|
114
|
+
|
|
115
|
+
**零缺口交付(禁止中途停顿)**:落地一次跑完,**不得因「词典没建这个 ID / 这个字段没枚举 / 这个值要不要确认」而停下来问用户**。缺口只有两类,去向各不相同:
|
|
116
|
+
|
|
117
|
+
| 缺口类型 | 判据 | 处理 |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| **能力缺口**(词典缺 ID / 缺字段枚举 / 缺 form) | 设计侧意图完整、值合法 | **项目侧当场落地**:按 L3 定制布局施工并写 mapping 临时映射;出厂文件仅在「补通道」时可动,交付说明单列申报。**进清单 = 把可落地项搁置 = 交付失败** |
|
|
120
|
+
| **意图缺口**(设计侧没给值 / 值非法) | 变更集里本就没有这个值 | 才可进「缺口清单」,交付说明写明「回流设计侧补齐」——**不是问用户要不要做** |
|
|
121
|
+
|
|
122
|
+
`缺口清单` 只承载第二类,且必须给出点位 ID + 缺失字段名。
|
|
90
123
|
|
|
91
124
|
### 第 2 步 · 结构先行(visible / position / form)
|
|
92
125
|
|
|
@@ -95,8 +128,24 @@ node parser/index.js match --batch <changesets-dir>
|
|
|
95
128
|
- `visible: false` → 按条目 `visible_prop`(如 `platform-config.json` 的 `HideTabs`)或组件 `v-if` 隐藏;无现成通道时 `display: none`,作用域限定在条目 `style_scope` 内。**不删除任何代码行。**
|
|
96
129
|
- `position` → 优先用 flex 顺序(`order` / DOM 位置调整),禁止绝对定位像素坐标。
|
|
97
130
|
- `form` → 按条目 `forms` 枚举切换(如 tabs 的 `chrome`/`card` 走 `platform-config.json ShowModel`;内容区滚动模式走 `admin.content.container` 的 form(`fixed`/`scroll`/`auto` → 路由组件根节点 `data-content-mode` 属性,`auto` 为省略即钩子类探测)。枚举外的形态 → 报告,不猜。
|
|
131
|
+
- **结构维度缺失即申报,禁止「只改令牌冒充落地」**:变更集把结构/方位/有无类意图写进 `style`(如指示条只在 `style.menu_active_indicator` 出现、无对应 `form`)时,按「结构意图缺失」处理——交付说明申报「设计侧需补 form + 几何 + 色值」,不得只覆盖颜色令牌交差(历史事故:竖条只换令牌 → 图上有、页面上没有)。
|
|
132
|
+
- `form` 的落点按上文「落地三落点判据」执行:**有 DOM/配置通道走通道,无通道需新节点走结构增量,纯视觉形态走设计层样式文件**。当某形态在本项目只有样式表达(如菜单指示条方位)时,该 form 允许落到样式层——这与「禁止把内容区高度模式降级成 SCSS」不冲突,判据是**该形态有没有非样式通道**。
|
|
98
133
|
- `layout_type` → 改 `platform-config.json Layout` 字段,值域 `vertical/horizontal/mix`。**大屏全屏沉浸式等独立页不走此通道**(设计侧不填 `layout_type`,点位走 L3 落地)。
|
|
99
134
|
|
|
135
|
+
**存在性收口(通用机制,第 2 步随结构处理)**:变更集未声明的**出厂多余元素**(设计效果图上不存在的按钮/图标/入口,如顶栏设置按钮)→ 按各条目口径处理:有条目者在对应点位上以 `visible:false` 收口(代码保留,`v-if`/`display:none`);无条目者列入缺口清单申报「设计侧未声明,按无此元素收口」,同样以隐藏通道落地。禁止既不声明也不收口、让出厂元素顶替设计效果(顶栏设置按钮漏收口已实证:效果图无此按钮,落地后仍显示)。反向同理:**设计声明了而出厂没有的元素**(如欢迎区问候语)必须按条目 `$note`/设计规范补齐结构(结构通道豁免底线二),缺失 = 未交付。
|
|
136
|
+
|
|
137
|
+
**结构/样式图层分工**:`form`(高度模式、形态枚举)是**结构意图**,必须落到 DOM 属性/组件开关/配置字段(如 `data-content-mode`、`ShowModel`);**禁止把结构意图降级翻译成 SCSS 变量写进样式文件**(form=scroll 只写 `--vts-margin` = 未施工,已实证)。样式文件(如 design-shell.scss)只承载 css_vars/custom_style_map 翻译产物;壳层通用文件禁止代打页面级结构属性(lay-content 硬编码 `data-content-mode="scroll"` 曾压掉 `:has()` 自动定高探测,useTableSearch 高度链断裂致列表区整体崩坏——已回退,禁止复活)。
|
|
138
|
+
|
|
139
|
+
**结构链不可侵(高度链保命红线)**:内容区高度链是**结构层**,已与视觉解耦,两侧各有边界——
|
|
140
|
+
|
|
141
|
+
| 结构层(禁止改写) | 视觉层(设计自由落点) |
|
|
142
|
+
|---|---|
|
|
143
|
+
| `data-content-mode`(滚动归属,**页面根节点属性**) | 页面容器形态(卡 / 通栏 / 自绘)、底色、圆角、边框、内边距、阴影 |
|
|
144
|
+
| `data-fill`(填满剩余高度,**逐层节点属性**) | 容器内部排布(标题区 / 筛选区 / 表格区的位置与间距) |
|
|
145
|
+
|
|
146
|
+
- 设计要求换掉出厂卡片容器(去卡片、改通栏、改内部排布)→ **照做,不打折**:页面根声明 `data-content-mode`,把 `data-fill` **平移**到新容器及其「体」层,视觉全落设计层文件。此路径下 `tableHeight` 几何实测照常成立。
|
|
147
|
+
- **双向禁止**:① 以「保高度」为由拒绝改容器/内边距/去卡片(= 放弃设计还原);② 为凑还原效果改写壳层结构层规则、或在视觉层重写/压掉 `[data-fill]` / `.main-content[data-content-mode]`(= 高度链断裂,返工项)。
|
|
148
|
+
|
|
100
149
|
### 第 3 步 · 样式落地(两层转换 + 语义值译表)
|
|
101
150
|
|
|
102
151
|
对每个 `style` 字段,按 parser 转换指令执行(parser 已把语义值解析为精确值,如 `钴蓝-5` → `#245BFF`)。**冲突裁决规则(免问):凡变更集声明与项目出厂现状/模板既有口径冲突,一律按变更集执行——变更集是唯一施工依据,不反问、不逐次确认。**
|
|
@@ -114,14 +163,26 @@ node parser/index.js match --batch <changesets-dir>
|
|
|
114
163
|
.navbar :deep(.el-dropdown-link img) { width: 36px; height: 36px; }
|
|
115
164
|
```
|
|
116
165
|
`sub_selectors` 有定义的字段(如 `avatar_*` → img、`name_*` → p)按对应选择器路由。
|
|
117
|
-
3. **两层都未命中** →
|
|
118
|
-
4. **值未命中译表且非 hex**(parser 会提示)→
|
|
166
|
+
3. **两层都未命中** → 值合法且选择器可定位时,当场生成作用域内自定义规则落设计层文件并在交付说明申报;仅「值非法 / 无法定位」才进缺口清单。
|
|
167
|
+
4. **值未命中译表且非 hex**(parser 会提示)→ 能按数值字面量 / hex / 上下文判定的当场落地并申报;仅完全无法判定时进缺口清单、回流设计侧补齐(**不向用户反问**)。
|
|
119
168
|
|
|
120
169
|
全局令牌(`global` 字段,**整套主题切换优先通道**)→ `design-tokens.scss` 对应变量(`basic/` 词典翻译,语义值走 `mapping/basic/semantic-values.json` 译表),主色走 `setEpThemeColor()` 链路。**壳层模块底色注意**:顶栏底色不走 global(无独立令牌),须以 `{"id": "admin.layout.header", "style": {"bg": "<值>"}}` 场景条目声明(scoped 覆盖 .navbar 底色);侧栏底色两者皆可——global 走 `sidebar_bg`(--sidebar-bg 令牌链),场景条目走 `admin.layout.sidebar` 的 `bg`(--vts-theme-menu-bg)。
|
|
121
170
|
|
|
171
|
+
### 第 3 步附加 · 设计层落点文件(强制)
|
|
172
|
+
|
|
173
|
+
所有「新增的 CSS 规则」一律写入 **`src/styles/design-shell.scss`**(出厂空文件,经 `index.scss` 末位 `@use` 加载 → 后置压出厂,无需 `!important`),或写入页面级 `<style scoped>`;**不得**写进 `sidebar.scss` / `element-plus.scss` / `theme.scss` / `lay-*.vue` 等出厂文件去表达某张效果图的结论。
|
|
174
|
+
|
|
175
|
+
写入纪律:
|
|
176
|
+
|
|
177
|
+
- 每条规则带来源标注(`/* <语义 ID> · <变更条目> */`),换设计时整段可替换;
|
|
178
|
+
- 本文件内新增的 CSS 变量必须**定义 + 引用成对出现**(出厂已有消费者也算),避免死通道;
|
|
179
|
+
- 出厂元素需关闭时(存在性收口)也在这里做:令牌置 `transparent` 或 `display:none`,**绝不删出厂代码行**;
|
|
180
|
+
- 出厂 `--vts-theme-menu-active-before` 默认 `transparent` 且无消费者 → 声明 `form=indicator_*` 时必须在此文件内**同时**落地「关胶囊令牌 `menu_active_bg: transparent`」与「新建 `::after` 消费者」,缺一即未施工成功。
|
|
181
|
+
- **自举(项目被还原到出厂时必做,幂等)**:文件不存在 → 新建(仅保留文件头纪律注释,无任何设计结论)+ 在 `src/styles/index.scss` **末位**补 `@use 'design-shell';`(必须末位,靠后置压出厂)。此动作属「补通道」,交付说明单列申报。**文件缺失时径直把设计规则写进 `element-plus.scss` / `sidebar.scss` / `theme.scss` = 污染出厂文件,禁止**(这也是「设计还原度为零」的常见成因:规则无处可落)。
|
|
182
|
+
|
|
122
183
|
### 第 4 步 · L3 新模块处理(分级布局)
|
|
123
184
|
|
|
124
|
-
-
|
|
185
|
+
- **L3 是施工指令,不是待办**:词典未命中的点位一律当场落地、交付说明申报「补映射」,不留待确认。新模块按「定制布局」三步走:① 基于全局规范生成结构(继承命名/作用域/组件规范)② 原子层字段(色彩/圆角/组件级)从 `basic/` + `component/` 词典借力 ③ 场景专属点位生成后**立即写入 mapping/ 对应场景域**(临时映射),累计复用 ≥3 次建议升级标准(由人工评审)。
|
|
125
186
|
- 生成的新页面必须带构图钩子(`vts-page-card` / `vts-filter-area` / `vts-table-area` 等),保证后续变更集可命中。
|
|
126
187
|
|
|
127
188
|
### 第 5 步 · 合规闸门(变更集专属检查)
|
|
@@ -135,21 +196,35 @@ node parser/index.js match --batch <changesets-dir>
|
|
|
135
196
|
- [ ] 未改动业务逻辑层(API/状态/事件——**底线二**;样式与结构通道内的 DOM 调整除外)
|
|
136
197
|
- [ ] 两层样式全部落在 `style_scope` 作用域内,无全局泄漏
|
|
137
198
|
- [ ] **类名冲突检查(AI 施工硬性步骤)**:新增 class 之前先在目标文件与同作用域全局样式中检索同名类——已存在时禁止直接追加重复定义,按三选一处理并在交付说明申报:① 语义相同 → **合并**进既有规则;② 语义不同 → 改用带点位前缀的新类名(如 `vts-<语义id末段>`);③ 确需覆盖 → 走作用域内更高优先级(不写 `!important`)。重复类名(尤其跨 `<style>` 块的 scoped 样式重复定义)会触发编辑器/构建报错,**本项不通过不得交付**
|
|
199
|
+
- [ ] **出厂中性检查(架构红线,不通过必须回退重做)**:diff 中不得出现「为表达本次设计而改写出厂文件」的产物——典型症状:把指示条方位/问候语 DOM/某个具体尺寸直接写进 `sidebar.scss`、`element-plus.scss`、`lay-navbar/index.vue`、`lay-content/index.vue` 等出厂载体;在出厂 `<component>` 上硬编码 `data-content-mode`/样式钩子。出厂文件若被改动,只能是「补通道」(补变量消费者 / 补 form 枚举 / 修层叠优先级,如已修的 `:has()` 与显式模式优先级反转),且必须在交付说明单列「补通道」条目写明缺失点;非此情形一律回退,改由 `design-shell.scss` + 变更集驱动。**模板源码注释保持中性**:diff 中不得出现「语义 ID / 本协议步骤号 / 面向 AI 的纪律条款」写进模板源码注释(如 `lay-content/index.vue`、`element-plus.scss`、`design-shell.scss` 的文件头与段落注释);这类内容只允许存在于技能侧文档
|
|
138
200
|
- [ ] **文本溢出回归检查**:改动侧栏菜单/顶栏/页签等含文字的模块后,必须确认「长文本显示」未被破坏(菜单项名称完整可见,必要时保留 ellipsis 溢出策略而不是隐藏/截断);宽度相关字段(width/min-width/padding)改动后逐项目视验证
|
|
139
201
|
- [ ] **形态与存在性目视验证(历史漏还原高发区,声明即必须验证,没做视同未交付)**:变更集声明了以下意图时,逐项在页面上确认真实生效——
|
|
140
202
|
- 语言切换 form=inline_switch → 顶栏出现「中|EN」并排文字(不再是纯图标)
|
|
141
203
|
- 折叠按钮 form=header_inline → 顶栏最左出现 40×40 折叠按钮且与首页页签左对齐;**同时侧栏底部出厂折叠条按设计隐藏(visible:false 声明时)**,避免双折叠按钮并存
|
|
204
|
+
- 侧栏 `menu_active_*` / `form=indicator_*` → **按变更集声明的 form 逐项核对**(indicator_left → 左侧竖条;indicator_right → 右侧竖条;indicator_underline → 底部横线;pill → 胶囊底色;none → 无指示):方位/粗细/长度/圆角与变更集 style 字段一致,且出厂胶囊已关闭(`--vts-theme-menu-active-bg: transparent`)、`--vts-theme-menu-active-before` 消费者真实建成。**禁止用「左侧 3px」这类历史/词典结论替代当次声明**——设计换了就必须是新的方位与数值
|
|
205
|
+
- 顶栏未声明点位(设置按钮等)→ 已收口不显示;用户区 → 按 `form` 核对组合形态(`avatar_name` / `greeting_avatar_name` / `greeting_name` / `avatar_only` / `name_only`),其中 greeting 为结构增量节点(出厂无此 DOM,需 AI 按 form 插入后再验)
|
|
206
|
+
- 页签图标 → 按 `form` 核对(item 的 `text_only`/`with_icon`,home_tab 的 `icon_only`/`text`),出处是路由 `meta.icon` 数据或本次隐藏规则,不是源码常量
|
|
207
|
+
- 内容区 form=scroll/fixed → `data-content-mode` 属性落在**页面根节点**(不是样式文件、不是壳层组件),列表页自动定高未被压掉;填满链逐层带 `data-fill`(详见下方「高度链存活检查」)
|
|
142
208
|
- 操作栏 form=with_tools/left_batch → 刷新/密度/列设置三件套齐全;批量删除红底/导出白底/未选中置灰
|
|
143
209
|
- 操作列 form=text_link → **业务列定义的 icon 字段已移除**(纯文字无图标,只改 CSS 保留图标 = 未还原);按钮单行不换行(列宽 ≥160px + nowrap);删除项红色;≥3 个折叠「更多」带箭头
|
|
144
|
-
- tabs form → 页签形态切换生效(chrome/card
|
|
210
|
+
- tabs form → 页签形态切换生效(chrome/card);激活态表现(有无下划线 / 是否仅文字变色 / 字重)按当次变更集 style 字段核对,**不以历史设计稿口径为准**
|
|
211
|
+
- [ ] **高度链存活检查(结构层不被设计改动压垮,也不被"保高度"绑架)**:定高页(`form=fixed` 或列表页自动定高)还原后逐项确认——
|
|
212
|
+
- `data-content-mode` 落在**页面根节点**;从页面根到表格/画布容器**每层需填满的节点都带 `data-fill`**(换了视觉容器时属性已平移;横向分栏用 `data-fill="row"`);
|
|
213
|
+
- `content` ref 仍绑在定高容器上(换容器后未丢),`otherRef` 仍在表格上方、分页仍在表格正下方;
|
|
214
|
+
- 表头 / 行 / 分页都在视口内,仅表格体内滚动,无外层滚动条、无拉伸 / 塌陷 / 双滚动条,`tableHeight > 0`;
|
|
215
|
+
- **结构层 diff 为空**:`lay-content/index.vue` 的 `.main-content[data-content-mode]` 与 `element-plus.scss` 的 `[data-fill]` 未被改动;同时确认没有「为保高度而放弃设计还原」(出厂卡片 / 内边距 / 内部排布原样未动而变更集声明了改动)——两个方向任一命中即返工
|
|
216
|
+
- [ ] **映射通道活性检查(杂必查)**:样式落地引用的每个 CSS 变量必须在项目样式中**存在消费者**(`变量名` 有 `var(--xxx)` 引用点);只定义不消费的变量 = 通道死路,翻译再准也不生效(menu_active_indicator 曾因 --vts-theme-menu-active-before 无消费者而「映射了却没效果」)。施工时 grep 核对,无消费者时改走消费者存在的作用域或补挂载点并申报。
|
|
145
217
|
- [ ] **dark.scss 暗色同步**:新增视觉规则在 `html.dark` 有对应覆盖
|
|
146
|
-
- [ ]
|
|
218
|
+
- [ ] **缺口清单只含意图缺口**:清单每一项都必须是「设计侧未给值 / 值非法」且已注明「回流设计侧补齐」;能力缺口(词典缺 ID / 缺字段枚举 / 缺 form)不得出现在清单里——出现即把可落地项搁置
|
|
219
|
+
- [ ] **台账逐行兑现对账(对账闸门)**:把设计侧交付的提取台账逐行过一遍,每行必须有落地结论——已落地(写明落在哪个文件/选择器)或已入缺口清单(写明缺失字段)。存在「台账有行、落地无结论」的行 = 交付不完整,与红线同级
|
|
220
|
+
- [ ] **零搁置交付**:最终回复不含「待确认」类停顿项;交付说明的「补映射 / 补通道 / 缺口回流」三段齐全(无内容写「无」)
|
|
147
221
|
- [ ] `node parser/index.js build --dry` 通过(mapping 若有临时新增)
|
|
148
222
|
|
|
149
223
|
## 词典维护纪律
|
|
150
224
|
|
|
151
225
|
- mapping/ 是唯一事实源:施工前 `parser query <id>` 精读条目,**不凭记忆施工**。
|
|
152
|
-
-
|
|
226
|
+
- **禁止编造的是「既有条目的映射」**(改既有 selector / css_vars / 变量指向 = 静默篡改,绝对禁止)。**词典缺 ID / 缺字段枚举不属编造**——那是新点位,按 L3 当场落地并写**新增的**临时映射条目,交付说明申报,等人工评审转正。
|
|
227
|
+
- 「宁可不做,不做错」只适用于**设计侧未给值 / 值非法**的意图缺口;用它搁置能力缺口 = 交付失败。
|
|
153
228
|
- 临时映射转正须人工评审;禁止静默修改既有映射条目的 selector/css_vars。
|
|
154
229
|
|
|
155
230
|
## 环境备注
|
|
File without changes
|