24 KiB
2026-08-02
项目分析 + Skill 创建
- 深入分析了 fms-api(Spring Boot + SQL Server 通用数据接口)和 fms-vue(Vue 3 + antdv-next)的完整架构
- 创建了项目级 CodeBuddy Skill:
fms-dev,位置.workbuddy/skills/fms-dev/ - Skill 包含:
SKILL.md— 开发模式速查(后端 3 种模式、前端 4 种页面模式、迁移脚本模板、踩坑清单、后端/前端代码约定、多语言规范)+ ERP 前端样式规范(三条禁令、间距/颜色/字体体系、弹窗规则、组件选型表,共 8 个子章节)references/schema.md— 模块管理六表 + 扩展配置表完整 schemareferences/api-reference.md— 所有通用端点详细参数文档
fms-file 组件 UI 重构
- 第一次误删了卡片网格和预览面板,用户指出只要改 UI 风格不要砍功能 → 回退后重新改造。
正确改造(保留全部功能,仅调 UI)
FileCard.vue — 缩略图 110→80px,背景 gradient→纯色,去掉 transition/box-shadow/backdrop-filter/hover 遮罩,按钮始终可见,选中态改用 1px 描边 FilePreviewPanel.vue — 工具栏 44→36px,背景色调浅,图片去阴影、图标缩 96→72px FileListPanel.vue — Header/Footer 44→36px,grid gap 12→8px,padding 收紧 FmsFile.vue — 三面板 default-size 各缩 10%(240→220, 700→660),border-radius 6→4px FmsFileModal.vue — 宽 1400→1200px,高 620→580px,标题改"附件管理" Dashboard — 演示按钮文案更新
- 编译验证通过(vite build: 833ms, 0 errors)。
追加:卡片/列表双模式 + 缩略图自适应
FileCard.vue — object-fit: cover → contain,图片在固定卡片尺寸内完整展示不裁剪
FileListPanel.vue — 新增 viewMode(grid/list)双模式切换:
- Header 右侧加 LayoutGrid/List 两个图标按钮,active 态高亮
- 列表模式用
a-table(size=small),列:文件名(可点击预览)/大小/类型(tag)/操作(下载+删除) - 列表与卡片共享同一
selectedFileIds,切换模式时选中状态保持 - 列表模式待上传文件显示"待上传"tag,checkbox 禁用
ResizeObserver自适应表格滚动高度- 编译验证通过(vite build: 822ms, 0 errors)
追加:Modal 百分比布局 + 待上传文件 checkbox
FmsFileModal.vue — 宽度 80%,高度 calc(70vh - 55px),自适应屏幕分辨率
FileCard.vue — 去掉待上传文件 checkbox 的 v-if="!isPending" 限制,待上传文件也显示 checkbox
FileListPanel.vue — 修复 5 处阻止待上传文件选中的逻辑:
allChecked基于全部displayFiles而非仅uploadedFileslistRowSelection去掉disabled: !!record._pendingtoggleAll全选包含待上传onFileSelect去掉if (file._pending) return拦截- 模板
:selected去掉!f._pending &&条件 deleteSelected拆分为已上传(调接口)和待上传(从队列移除),降序删除防索引漂移- 编译验证通过(vite build: 792ms, 0 errors)
追加:UI 优化(按钮默认大小、模式切换右移、空状态居中、拖拽/粘贴/点击上传)
- 所有按钮去掉
size="small"(FileListPanel header/footer/列表 + FileCard 删除/下载),header/footer 高度 36→40px - 模式切换按钮移到 header 最右侧(位于删除按钮之后)
- 空状态仅显示"暂无相关文件"居中,去掉"选择文件"按钮和
#description模板 - 新增拖拽上传:
fl-main区域监听 dragenter/dragover/dragleave/drop,含蓝色虚线遮罩提示"释放文件到此处" - 新增粘贴上传:
document.addEventListener("paste", handlePaste)检测剪贴板文件 - 提取
addFiles(fileList)统一处理点击/拖拽/粘贴文件的入队逻辑 - 编译验证通过(vite build: 783ms, 0 errors)
fms-file 视觉优化(frontend-design skill 驱动,用户确认"全部落地")
- 新增
fileVisual.js:集中 EXT_COLOR 扩展名语义配色映射、extColor/extFromName/isImageType/formatSize,消除 FileCard/FileListPanel/FilePreviewPanel 三处重复 main.scss补充令牌:--fms-primary:#1677ff --fms-danger:#ff4d4f --fms-warning:#fa8c16- 令牌统一:fms-file 全部组件硬编码灰/蓝(#e5e7eb/#fafafa/#8b8f96/#1677ff/#cf1322/#91caff)替换为
--fms-*,与全站设计语言对齐 - 三栏顶部对齐:FilePreviewPanel 工具栏 36→44px;FileCategoryPanel 新增 44px"分类"标题条;三栏顶部齐平
- FileCard 去噪音:缩略图只留 checkbox;删除/下载改为 hover/选中才显现的底部操作条(不再四角浮动);"待上传"去掉 opacity 降透明度改左侧琥珀色边角标 + 文件名旁琥珀 tag;选中改 inset 2px 实色描边
- 彩色类型方块(签名元素):按扩展名语义着色(PDF红/DOC蓝/XLS绿/IMG紫/ZIP橙…),卡片缩略图、列表 ext chip、预览通用图标三处一致复用
- 间距/排版:
.fl-main四边统一 12px;网格 gap 8→10px;消灭 10–11px 极小字,卡片名 13px/500、meta 12px/400;空态 height:100% 居中 - 拖拽遮罩改
--fms-primary虚线 + color-mix 底色 - 编译验证通过(vite build: 769ms, 0 errors)
fms-file 允许重复上传同一文件
- 问题:上传一次后无法再次上传相同文件。排查结论:后端
FileService无任何同名去重(每次 INSERT 新 subid + UUID 磁盘名),唯一拦截点是前端addFiles()内的pendingFiles.some(name+size+lastModified)跨调用去重。 - 改动:移除
addFiles()中去重比较,允许同一文件在多次独立操作(重新选/再拖一次)里反复加入待上传队列并提交。拖拽重复入栈问题此前已由 dragenter/dragleave 的currentTarget判断修好,无需保留该去重。 - 验证:vite build 756ms 0 errors。
fms-file 修复 --fms-border is not defined + 删除分类标题节点
- 根因:
a-modal默认把内容 teleport 到<body>,脱离了.theme-root;而--fms-*令牌原先只定义在.theme-root,导致模态框内全部令牌未定义 → 报 "--fms-border is not defined",且卡片/面板边框、颜色全部失效(这也解释了上一轮用户问"卡片怎么没边框")。 - 修复
main.scss:把 10 个--fms-*令牌从.theme-root提升到:root,全局可用;.theme-root仅保留 color/background/overflow。 - 按要求删除 FileCategoryPanel.vue 的
<div class="fc-panel__header">分类</div>标题节点及其&__header样式块(该节点仅含未定义令牌引用,删除后fc-panel__tree以 flex:1 撑满,布局完整)。 - 验证:vite build 777ms 0 errors。
fms-file 卡片删除多余黄色竖线
- 来源:FileCard.vue 的
.fcard__stripe(width:3px / background:var(--fms-warning) 左侧琥珀竖条,仅待上传卡片渲染),表现为多余黄色线条。 - 删除模板
<span class="fcard__stripe" />节点及其.fcard__stripe样式块;待上传状态仍由「待上传」amber 文字标签(.fcard__tag)表达。 - 其余黄色(待上传 tag、ZIP/RAR ext 配色)为语义标记保留;无伪元素黄色线条。
- 验证:vite build 758ms 0 errors。
fms-file 卡片加常驻「下载/删除/更多」操作栏
- FileCard.vue:移除原本 hover/选中才出现的半透明浮层
.fcard__actions;改为卡片底部常驻.fcard__footer操作栏(下载 / 删除 / 更多 三等分,顶部 1px 分隔线,删除与更多之间加竖向分隔线)。 - 「更多」用
a-dropdown+a-menu,当前含「预览」一项(可扩展);onMoreClick按 menu key 分发。 - 待上传卡片:下载/更多 disabled,删除按钮文案变「移除」。
- 图标新增 Eye、ChevronDown。
- 验证:vite build 766ms 0 errors。
fms-file 卡片底部操作栏 hover 闪烁/错位修复
- 现象:hover 卡片「下载/删除/更多」操作栏时出现闪烁、错位、疑似多出边框。
- 根因:antdv-next 按钮自带的
::before/::after波纹伪元素 hover/点击时出现边框状残影并闪烁;按钮默认outline焦点环也表现为边框;且.ant-btn默认transition: all会在 hover 时引发微重排。 - 修复 FileCard.vue
.fcard__footer:关闭.ant-btn的::before/::after(display:none !important)、outline:none,固定box-sizing:border-box,并将 transition 限缩为background-color,color(去掉 all),hover 仅做纯背景/颜色切换。 - 验证:vite build 1.06s 0 errors。
fms-file 卡片取消 hover 放大 + 选中去 box-shadow
- 现象:hover 卡片时看似「放大」(实为
.fcard:hover边框由浅灰变蓝,视觉上像被框大);选中态box-shadow: inset 0 0 0 2px描边用户不想要。 - 改动 FileCard.vue:删除
.fcard的transition: border-color与&:hover { border-color: primary }(hover 不再改边框,仅 footer 按钮给反馈);&--selected去掉box-shadow,仅保留border-color: var(--fms-primary)纯蓝 1px 边框区分选中(不引起 1px 位移)。 - 验证:vite build 783ms 0 errors。
fms-file 卡片操作按钮 hover 收缩修复
- 现象:hover 底部操作栏「下载/移除」按钮时感觉收缩。
- 根因:上一轮去闪烁时把按钮基线
border设为none(宽度 0);而 antdv 按钮默认预留border: 1px solid transparent,hover 时边框宽度被补回 →box-sizing:border-box下内容区被挤 1px,视觉收缩。 - 修复 FileCard.vue
.fcard__footer:基线改为border: 1px solid transparent恒定预留;hover 显式border-color: transparent;分隔线按钮仅改border-left-color,宽度始终恒定,不再收缩。 - 验证:vite build 778ms 0 errors。
fms-file 空状态「暂无相关文件」垂直水平居中(两次修正)
- 现象:空状态仅在自身盒子内居中、贴顶,未在文件区整体垂直居中。
- 第一版(无效):
.fl-empty--fill改position:absolute; inset:0。错误假设定位上下文是.fl-main。 - 真实根因(查 antdv 编译 CSS 确认):
.ant-spin-container默认position:relative且高度auto。空状态绝对定位就近解析到.ant-spin-container(而非.fl-main),而它高度 auto → inset:0 只填满内容高度,仍贴顶。 - 正确修复:在
.fl-spin中追加:deep(.ant-spin-container){ height:100% },让容器撑满(高度链:.fl-main确定高 →.ant-spin/.fl-spinheight:100% →.ant-spin-containerheight:100%),空状态 inset:0 才真正铺满文件区并居中。.fl-empty--fill保持position:absolute; inset:0。 - 教训:antdv
a-spin的.ant-spin-container自带 relative + auto 高度,绝对定位子元素会被它截胡,必须显式撑满该容器。 - 验证:vite build 758ms 0 errors。
fms-file toolbar 重构:下载/删除移到左侧 + 模式切换改 a-segmented 图标模式
-
FileListPanel.vue header:把「下载」「删除」两个按钮从右侧(spacer 之后)移到「全选」checkbox 之后(左侧);
fl-header__spacer(flex:1)保留在按钮之后、把右侧推给模式切换。 -
右侧模式切换:去掉原先两个
a-button+a-tooltip文字按钮,改为a-segmented(v-model:value="viewMode"、:options="modeOptions"、size="small");modeOptions仅含{ value, icon }(grid→LayoutGrid、list→List),不含 label → 仅图标。 -
脚本:
import { h } from "vue",modeOptions用() => h(LayoutGrid,{size:14})渲染图标项(antdv-next 1.4.2 的 Segmented 支持 options 的 icon 字段,无 label 时仅渲染图标)。 -
样式:
.fl-header__modes去掉原is-active文字按钮激活样式,改为:deep(.ant-segmented-item-selected){ color: var(--fms-primary) }同步选中态主题色。 -
验证:vite build 798ms 0 errors。
-
后续修复:仅图标模式下 segmented 图标顶部被裁。根因:antdv
.ant-segmented-item-label默认overflow:hidden+ 基线对齐,inline svg 上移 1~2px 被裁。修复:对该 label 加:deep(.ant-segmented-item-label){ display:flex; align-items:center; justify-content:center; overflow:visible }(仅作用于.fl-header__modes内 segmented)。验证 vite build 802ms 0 errors。 -
按官方写法重做:用户要求不要特意改样式、参考 antdv 官方 Segmented 案例。改用 antdv 自带图标
AppstoreOutlined(grid)/BarsOutlined(list)(来自@antdv-next/icons),options直接icon: h(AppstoreOutlined)不传固定 size(图标按 1em 缩放,天然不裁切);删除上一版的.ant-segmented-item-labeloverflow 兜底样式与选中色覆盖,回归官方无定制外观。 -
依赖处理:
@antdv-next/icons原先只是 antdv-next 的传递依赖(pnpm 严格模式顶层无软链,裸导入会失败),已加入package.jsondependencies(^1.1.1);本机 pnpm 不可用(corepack pnpm install报 "packages field missing or empty" 环境错误),改用 PowerShellNew-Item -ItemType Junction把 store 内包软链到node_modules/@antdv-next/icons使其可解析。lockfile 已含该包,无需下载。验证 vite build 801ms 0 errors。 -
环境教训:本仓库 fms-vue 用 pnpm 但本机 pnpm 跑不起来(workspace 配置报错),需要新增/链接依赖时优先用 junction 软链到
.pnpmstore,而非强跑 pnpm install。 -
分区配色优化(fl-header/fl-footer/fp-toolbar/fp-content):用户反馈这些区域背景/文字色过近、边界模糊、融为一体。原状:三个工具条都用
--fms-hover(#f2f3f5 浅灰)、文件内容区白底、预览内容区--fms-bg(#f5f7fa),不一致且灰条贴白底对比弱。改法(ERP 克制、靠对比不靠重阴影):工具条统一改白--fms-surface+ 1px--fms-border分隔线(浮起条),内容区统一改浅灰画布--fms-bg(文件区.fl-main显式加 bg,预览区.fp-content本就灰)。白条夹灰画布,层次分明且整体协调。同步把.fl-main--dragover拖拽底色从混白改为混--fms-bg。验证 vite build 788ms 0 errors。 -
fl-header/fp-toolbar 高度统一 + 面板分隔:①
fp-toolbarheight 44→48px,与fl-header/fl-footer(均48px) 对齐;② 先给.fl-panel加了border-right做面板分隔,但用户指出不必逐个加边框,直接改 antdv splitter 分割条中线更通用。改法:撤回.fl-panel的 border-right,FmsFile.vue的.ff-splitter作用域内用:deep覆盖.ant-splitter-bar .ant-splitter-bar-dragger::before(及其 hover 态)的 background,由默认--ant-control-item-bg-hover(近乎隐形) 改为var(--fms-border),hover 也覆盖以免悬停时分隔变淡。验证 vite build 812ms 0 errors。 -
修正:splitter 分隔线全局 scss 方案:上一轮 scoped :deep 没生效的真因——a-splitter 渲染后 .ff-splitter 与 .ant-splitter 是同一元素(class 合并),选择器写成 .ff-splitter :deep(.ant-splitter > ...) 要求祖先-后代关系,同一节点永远匹配不上。用户要求改用全局 scss。做法:① 删除 FmsFile.vue 中失效的 :deep 块;② 在 main.scss 末尾追加全局规则,直接定位 .ant-splitter-bar .ant-splitter-bar-dragger::before(含 hover 态)background: var(--fms-border) !important。未采用全局改 --ant-control-item-bg-hover 令牌——该令牌被 19 处控件共用(级联菜单/树节点/上传列表/标签页下拉等),全局改会把这些 hover 底色全染灰,影响面过大。验证 vite build 784ms 0 errors。
-
fl-main 回白底 + 网格回两列 + 卡片操作栏纯图标:用户反馈三处:① 文件内容区背景不必灰色,
.fl-mainbackground 从--fms-bg改回--fms-surface(白),dragover 混色同步改 surface;② 宫格从一行三个(repeat(3,…))改回一行两个(repeat(2,…));③ 卡片底部操作栏(下载/删除/更多)原用中文文字按钮,等宽三列在其它语言下文字更长会撑破布局,对多语言不友好。改为纯图标按钮(Download/Trash2/MoreHorizontal,去掉文字),图标固定尺寸、等宽列不依赖文字长度,语言无关。更多触发器图标由 ChevronDown 换 MoreHorizontal。下拉菜单的「预览」仍为文字(菜单项属次级,不在本次操作行布局问题范围内)。验证 vite build 762ms 0 errors。 -
FmsFileModal 加边界约束:用户确认 modal 用百分比宽高(width 80% + body height calc(70vh-55px))而非固定值,但纯百分比在超宽屏/极小屏/矮屏有坑。在
.ff-modal作用域(.ant-modal)加max-width:1440px(超宽封顶)、min-width:960px(极小屏三栏保底),(.ant-modal-body)加min-height:520px(矮屏保底)。保留用户明确的 80%/70vh 不变。验证 vite build 811ms 0 errors。 -
卡片 checkbox 去重感:用户觉得
.fcard__check套层白底+阴影太重。移除该包裹层的 background(rgba白0.92) 和 box-shadow,及固定 20x20 圆角方框,改为仅绝对定位的透明壳,checkbox 直接浮在缩略图左上角。验证 vite build 790ms 0 errors。 -
fl-main 滚动失效修复:用户反馈上传多文件后 fl-main 不出现 Y 轴滚动条、底部 padding 像失效。根因:
.fl-spin与.ant-spin-container都被设成height:100%,把内层盒子锁死成等于 fl-main 可视高的固定盒,超长.fl-grid只是靠overflow:visible溢出绘制而不撑大盒子,fl-main(overflow:auto) 收不到超出高度 → 不滚动、底部留白也贴盒底。修复(FileListPanel.vue.fl-spin):① 去掉height:100%,改min-height:100%(内容短仍撑满、内容长自然溢出);②.ant-spin-container改height:auto; position:static(取消固定高度、把定位上下文让回.fl-mainposition:relative),使空态.fl-empty--fill(position:absolute;inset:0) 正确铺满居中、且 grid 溢出时由 fl-main 统一滚动。注意:改 position:static 后加载遮罩::after会绑定到 fl-main(覆盖整个文件区,属预期更佳效果);spinner 指示器.ant-spin-section仍绑定.ant-spin(fl-spin, antdv 自带 position:relative) 居中。验证 vite build 793ms 0 errors。
fms-file segmented 图标换 lucide + 居中修复 + 分隔线深浅答疑
- segmented 图标换 @lucide/vue:用户要求把右侧模式切换(
a-segmented)的图标从@antdv-next/icons(AppstoreOutlined/BarsOutlined) 换成@lucide/vue(LayoutGrid/List)。改动 FileListPanel.vue:移除 antdv 图标导入,改用h(LayoutGrid,{size:16})/h(List,{size:16})渲染图标项(size:16 保证在 segmented 内尺寸合适)。验证 vite build 769ms 0 errors。 - lucide 图标在 segmented 内顶部被裁/偏上根因与修复:antdv
.ant-segmented-item-label用固定minHeight+lineHeight做垂直居中并带overflow:hidden;而@antdv-next/icons的 svg 自带display:inline-block/vertical-align:-0.125em专为基线坐定,lucide 的裸<svg>无这些属性、按默认vertical-align:baseline对齐 → 顶部溢出被裁。先给.ant-segmented-item-icon加 inline-flex 居中(仍偏上,因 icon span 在 label 内仍基线对齐);最终让.ant-segmented-item-label自身display:flex; align-items:center; justify-content:center解决(此处仅放图标无文字,不影响文字模式)。 - 居中规则进 main.scss(opt-in 工具类):用户问是否把
.ant-segmented-item-label{flex居中}写进 main.scss 全局。结论:不直接 blanket 全局——该规则本质是 lucide 裸 svg 的 workaround,全局化会影响所有(含图文/纯文字)segmented 的overflow:hidden截断与横排方式。折中:在 main.scss 末尾加 opt-in 类.ant-segmented.fms-seg-icon .ant-segmented-item-label{display:flex;align-items:center;justify-content:center},组件里去掉 scoped:deep块、给<a-segmented>加fms-seg-icon类。既一处定义、零波及面,以后别处用图标模式只需加该类。验证 vite build 0 errors。 - splitter 分隔线 vs fl-header 边框"深浅不一"答疑:两者同用
--fms-border,颜色值一致,差异来自线宽+发丝线抗锯齿:分隔条中线.ant-splitter-bar-dragger::before是 2px 实心色带(splitBarSize 默认 2),fl-header 是 1px solid 发丝线——同色下实心 2px 接收更多纯色像素读起来更"实";1px 边框在 DPR=1 屏被抗锯齿淡化。Retina 下差异明显变小。结论:合理层次表现,非 bug,无需修;若强一致性可把 ::before 降 1px。
fms-file Splitter 默认宽度(像素固定 + 预览占余)
- 用户最终确认布局:分类区固定
220px、文件列表固定420px、预览区不指定default-size(autoPtgSizes 自动占剩余,min440 保底)。相对最初 220/420/660,实际只把预览区从固定 660 改为自动占剩余。 - 根因确认(读 antdv
useSizes.js+sizeUtil.js):Splitter 的default-size数字=px(折算 px/容器宽 的百分比)、字符串"%"=直接百分比、不传=由autoPtgSizes把1−已定义比例之和均分给未定义面板;混用 px+% 不溢出(超 100% 时按 scale 缩放、未定义项归 0)。 - 改动 FmsFile.vue 三面板:① 分类
:default-size="220"(min160/max320);② 文件列表:default-size="420"(min280);③ 预览去掉:default-size,仅留:min="440" collapsible。showTree=false 时仅剩列表 420px + 预览占剩余。 - 注意:最小屏(模态 min-width 960 − 两条分隔条≈4px)下 220+420=640 固定,预览得约 316px,会短暂低于其 440 min(仅出现在最小模态宽度);常规/较宽屏预览正常占余、主导显示。
- 验证 vite build 779ms 0 errors。
fms-file 空状态「暂无相关文件」可点击选择文件
- 用户要求:显示「暂无相关文件」时空状态要 cursor:pointer,点击即可选择文件。
- 改动 FileListPanel.vue:① 空状态 div(
.fl-empty.fl-empty--fill,仅!hasFiles && !loading渲染、本就position:absolute;inset:0铺满文件区)加@click="!readonly && triggerSelect()"——复用隐藏uploadInputRef唤起文件框(与底部「选择」按钮同一入口),点击文件区任意空白都能触发;② 新增.fl-empty--clickable{cursor:pointer},并用:class="{ 'fl-empty--clickable': !readonly }仅非只读时显示手型、点击才生效,只读模式不误导。 - 验证 vite build 777ms 0 errors。
fms-file 卡片操作列禁用态样式优化
- 用户反馈:卡片操作列(下载/更多按钮)在 pending(
_pending=true)禁用时,"禁用样式不明显"。 - 根因:
.fcard__footer :deep(.ant-btn)里无条件写了color: var(--fms-text-secondary)与恒定透明边框,把 antdv 自带:disabled(变淡灰 + not-allowed)覆盖掉;lucide 图标用currentColor,禁用与启用图标同色、且鼠标仍 pointer → 看不出禁用。 - 改动:①
main.scss:root 新增令牌--fms-disabled: #c9cdd4(浅灰,常见禁用色);②FileCard.vuefooter 的:deep(.ant-btn)内新增&:disabled, &[disabled]规则:color:var(--fms-disabled); background:transparent; border-color:transparent; cursor:not-allowed; opacity:1(特异性.fcard__footer .ant-btn:disabled=0,3,0 高于通用.ant-btn=0,2,0 与 antdv 默认,稳定生效)。图标因 currentColor 自动变浅灰。删除按钮(danger)始终启用不受影响;禁用时的竖向分隔线(border-left-color:var(--fms-border))保留。 - 验证 vite build 791ms 0 errors。
fms-file 卡片操作列「删除|更多」分隔线消失修复
- 用户反馈:下载|删除分隔线可见,但删除|更多分隔线看不到(尤其在 pending 卡片上)。
- 根因:原分隔线挂在按钮左边框上(
.ant-btn-dangerous命中删除、.ant-dropdown-trigger命中更多)。「更多」按钮在 pending 时禁用,而禁用规则&:disabled{border-color:transparent}特异性 (0,3,0) 高于分隔线.ant-dropdown-trigger(0,2,0),把其左边框也抹成透明 → 分隔线消失;且「更多」被 a-dropdown 包裹结构更脆。 - 修复:弃用按钮类名/border 方案,在模板
fcard__footer内下载/删除、删除/更多之间各插入独立<span class="fcard__divider" />;新增.fcard__divider{flex:none;width:1px;align-self:stretch;background:var(--fms-border)}(随 footer 撑满高度);删除原先:deep(.ant-btn-dangerous),:deep(.ant-dropdown-trigger){border-left-color}规则。分隔线不再受按钮禁用态/类名影响,稳定显示。 - 验证 vite build 784ms 0 errors。