Files
reimburse/界面优化方案.md
T
2026-09-20 16:31:24 +08:00

15 KiB
Raw Blame History

贴票台 · 界面优化方案

依据当前代码(reimburse/ 下 26 个 Swift 视图文件)整理,只提优化建议,不改动代码。 应用结构:顶层 TabView(项目管理 AdminView + 本地贴票 ContentView),本地贴票内含 材料扫描 ScanPage人工配对 PairPage已核对 MatchedPage 三个页面,以及报销单模板、收款信息、报销单预览等弹窗。


一、现状盘点

信息架构

层级 内容 现状评价
顶层 Tab 项目管理 / 本地贴票 应用名为"贴票台"且主功能是本地贴票,但项目管理排在第一个 Tab,与产品定位略有错位
本地贴票 侧栏 3 页 + 顶栏统计 + 工具栏 3 按钮 结构清晰,导航合理
弹窗 报销模板(1000×700)、收款信息(宽 580)、个人报销单(870×620)、预览(动态)、材料预览(1000×700) 尺寸规格不统一,部分固定尺寸在小屏上有溢出风险

已做好的地方(应保留)

  • MaterialCard 卡片 + Canvas 贝塞尔连线的配对交互,直观且具辨识度;
  • MatchExplanationPopover 的 100 分制证据评分明细,透明度高;
  • 拖拽导入的 dropDestination 高亮反馈、.help() 悬停提示、accessibilityLabel 覆盖较全;
  • Table + 分组 Picker + 跨分组保留勾选的选择模型,业务逻辑扎实。

二、设计系统层面(全局问题)

2.1 颜色语义不统一 高优先级

  • 现状:teal 同时承担「品牌色、强调色、成功色、进行中状态」四种语义(侧栏图标、付款金额、匹配满分、通知横幅全是 teal);警告用 orange、错误用 red、AdminView 里成功又用 green。同一语义在两个 Tab 中颜色不同。
  • 建议
    1. 建立语义色枚举(如 AppTheme.success / warning / danger / accent),收敛到一处定义;
    2. teal 保留为品牌/强调色;成功态用系统 green、警告 orange、危险 red,与项目管理端对齐;
    3. 「自动匹配 ≥90 分」与「人工确认」目前用 teal / blue 区分,建议改为统一的徽章组件(形状+图标+色),而非仅靠文字前缀。
  • 金额显示可遵循国内财务习惯:发票与付款两列总额(topbar)目前一灰一 teal,对比弱,建议付款列加图标或用同色不同字重,避免用户误读为涨跌。

2.2 深色模式适配缺失 高优先级

  • 现状MaterialThumbnailColor.white 背景、SpreadsheetPreview / ExpenseTemplateManager 大量 .background(.white)、预览区 .black.opacity(0.04)。深色模式下会出现大面积刺眼的白色块与文字对比不足。
  • 建议:表格/缩略图区保留白底是合理的(还原纸张观感),但外层容器、边框、占位图标应改用 Color(nsColor: .textBackgroundColor) 或材质色;至少验证 Window 在深色外观下所有页面无纯白大色块、无低对比 caption。

2.3 排版与间距 token 化

  • 现状padding(28) / (26) / (22) / (20)cornerRadius 16 / 13 / 12 / 10 / 9 / 8、字号 .title2 / .title3 / .system(size: 34 / 44 / 42) 混用,页面间无对应关系。
  • 建议:定义间距(4 的倍数:8/12/16/24/28)与圆角(8 卡片内、12 卡片、16 面板)两档规格;页面主标题统一为 .title2.bold()(当前 PairPage 是 title3、MatchedPage 是 title2)。

2.4 组件重复实现

  • AdminView 内自建了 statusBadge / sectionCard / searchField / emptyStateContentView 一侧有 Panel / EmptyPanel,两套体系风格接近但参数不同。
  • 建议:抽出共享组件库(Badge、Card、SearchField、EmptyState、StatNumber),两个 Tab 复用,减少后续维护分叉。

三、页面级优化

3.1 材料扫描 ScanPage

问题 建议 优先级
空工作区时仍显示全部统计面板(全是 0),首屏信息密度高但价值低 无材料时展示「导入引导」大空状态:仅保留拖拽卡片 + 模板卡片,统计面板在导入后再出现 P1
单列滚动太长:导入卡、模板卡、警告、3 个统计卡、2 个金额面板、分类汇总、底部计数,关键动作「前往人工配对」沉底 ① 统计卡片改为一行 4 列紧凑指标条;②「前往人工配对」在有待配对材料时上浮为醒目入口(如导入完成后的成功横幅内嵌跳转按钮);③ 分类汇总与金额概览合并为一个「金额」面板 P1
拖拽高亮 opacity 0→1 突变 withAnimation(.easeInOut(duration: 0.15)),并让图标/文字随 targeted 状态做位移或缩放微动效 P2
warnings 面板无法关闭、数量多时占据大量空间 逐条可关闭 + 超过 3 条折叠为「N 条提醒」;每条加对应的跳转动作(如跳转到识别失败的材料) P2
三个统计卡数字 size: 34 硬编码,视觉与「金额概览」面板重复 数字统一走 StatNumber 组件(.rounded 数字字体 + tabular),金额面板可考虑用小图表(分类占比条)替代纯文本 P3

3.2 人工配对 PairPage

问题 建议 优先级
材料多时无法定位:无搜索、无排序切换、无金额/日期过滤 每栏顶部加搜索框(文件名/商户/金额)+ 排序菜单(日期/金额/文件名),复用 AdminView 的 searchField 样式 P0
已选 N 张发票 × N 张付款为全连接,选 5×5 时 25 条虚线交叉难以阅读 连线改为:hover/聚焦某卡片时只高亮与它相关的连线;或选中的卡片显示序号,连线带序号标签 P1
只有 Return 键可操作选中,无方向键导航 利用现有 .focusable() 补充 ↑↓ 移动焦点、Space 选中,形成完整键盘流;说明文字中标注快捷键 P1
缩略图固定 180pt 网格,看不清细节需逐个开预览 增加缩放滑杆(紧凑/标准/大图三档),或双击卡片直接放大预览后可从预览中「选中此材料」 P2
确认配对按钮位于右上角,与底部的选中信息分离 选中数 >0 时在两栏之间显示居中的「确认配对(N×M)」悬浮按钮,动线更短 P2
空状态文案两栏雷同 左栏空时提示「所有发票已处理或已核对」,右栏提示对应付款文案,并可放「撤销上一组」入口 P3

3.3 已核对 MatchedPage

问题 建议 优先级
无搜索/过滤:几十组材料时找特定金额/商户困难 表格上方加搜索框(金额、商户、日期),支持过滤后再勾选 P0
MaterialCell 只列前 2 个文件名链接,「还有 N 份」不可展开 点击单元格弹出 popover 缩略图网格,与 PairPage 的卡片视觉统一;>2 份时显示「+N」叠图效果 P1
底部三行 caption 说明文字(勾选规则、PPT 版式)常驻 收敛为一个「导出说明」帮助按钮(questionmark.circle)弹出;常用信息已在按钮禁用态与选中计数中体现 P2
分组多时 segmented Picker 挤压变形 分类 ≥5 个时改用 Menu + 下拉,或横向滚动 chips P2
「操作」列撤销仅图标按钮,与分类 Picker 挤在一列 撤销改为 hover 行时出现的 trailing 按钮或右键菜单;分类修改也可考虑双击单元格弹出,减少列宽 P2
表格无小计:分组切换后看不到当前分组金额合计 表格底部(或分组标题旁)显示「本分组合计:发票 X · 付款 Y」 P2
评分 <90 分为橙色但没有聚合入口(「哪些组需要人工复核」) 增加「需关注」过滤(评分 <90 或识别失败),配合 P0 搜索框;侧栏「已核对」徽标可显示低分组数量 P1

3.4 个人报销单 ExpenseSheet 与预览

问题 建议 优先级
固定 frame(width: 870, height: 620),小屏(MacBook Air 13" 缩放)可能顶出屏幕 改为 min 上限策略(参照 ExpensePreviewSheetmin(1200, visibleFrame - 80) 写法) P1
费用行用途 TextField 无校验反馈(空值、重复用途不易发现) 空用途时行内灰字提示;重复用途合并提示 P3
签字岗位 minus.circle 无确认,误触即删 删除加轻量确认或支持撤销 toast;输入框加默认岗位快选 Menu P3
expenseSelectionValid 失效只显示一行红字,动作指引弱 失效时禁用预览按钮并把红字放进醒目横幅,附「返回重新选择」按钮 P2
预览弹窗已较好;「返回修改」与「确认并保存」并排但视觉主次不明 确认按钮保持 prominent 即可;建议保存成功后用横幅告知保存路径并提供「在访达中显示」 P2

3.5 报销模板管理 ExpenseTemplateManager / ExpenseTemplateFields

问题 建议 优先级
模板字段调整(列字母/单元格地址)要求用户手工填 "C" "C23",认知门槛高 ① 输入框支持点选:在左侧表格预览上点击单元格即回填地址(SwiftUI 可用 onTapGesture + 布局信息);② 输入时实时校验字母/地址格式并给出示例反馈 P1
「查看单元格地址与原文」DisclosureGroup 是纯文本行,对照困难 与左侧预览联动:hover 某行时高亮预览中对应行;保留行号列 P3
未识别完整时只有一行橙色警告,确认按钮置灰原因不直观 每个缺失必填项(用途/金额列)在对应输入框旁标橙点,按钮旁注明「还差 N 项」 P2
模板卡片(ExpenseTemplateSummary)与导入卡片视觉相似,都是 teal 虚线框 模板卡片改为普通卡片 + 右上「模板」徽标,虚线拖拽样式只留给导入场景,减少误拖 P3

3.6 收款信息 PayeeProfileSheet

  • 现状已经较好(SecureField + 显隐切换 + 删除确认)。可补充:保存成功后 toast 确认;PayeeProfileSummary 中「尾号 XXXX」处加复制按钮。
  • 优先级 P3。

3.7 项目管理 AdminView

问题 建议 优先级
单文件 1364 行、50+ 个 @State,六个页签全部内联 拆分为独立 View 文件(AdminExpensesTab 等);这不是纯界面问题,但直接影响后续所有 UI 迭代效率 P1(技术债)
自绘 tab 条(navigationItem)与 macOS 惯例不符,窗口宽度不足时六个标签挤压 采用 macOS 15 可用的 TabView 新样式或保留但允许横向滚动 + 更多收纳进 Menu P2
登录页固定 400 宽输入区 + ScrollView,视觉重心偏上 居中卡片式布局;服务地址输入记忆历史地址下拉;微信扫码过期自动刷新提示 P2
报销审批表无分页指示、无列排序 Table 补充排序(金额/日期);行数多时显示计数 P2
错误横幅红色整条较突兀 收敛为顶部统一通知组件(同本地贴票端的 notice 样式),成功/警告/错误三态 P2

四、全局交互与反馈

  1. 统一通知体系(P1):目前成功提示是自定义 teal 横幅、错误是 alert、Admin 是红横幅。建议统一为三态通知条(成功/警告/错误),支持多条堆叠与自动消失(错误不自动消失),并复用 macOS 15 的 SymbolEffect
  2. 菜单栏与快捷键(P2):已有 ⌘O 导入。建议补充:⌘Z 撤销最近核对组(复用 store.undo)、⌘F 聚焦搜索(配合 P0 搜索项)、⌘1/2/3 切换三个页面、⌘, 打开设置类弹窗(模板/收款信息)。
  3. 空状态体系P1):EmptyPanel 目前只有图标+标题+说明,可按页面补一个行动按钮(如「选择文件夹」「前往人工配对」),形成闭环。
  4. 进度反馈P2):busy 时是整页 disabled + 顶部进度条;扫描大目录时建议在 Dock 图标显示进度(NSApp.dockTile.progress),并保留页面滚动可读。
  5. 危险操作确认(P2):「清空重置」的 confirmationDialog 文案已很详细,但「恢复内置模板」「删除收款信息」等破坏性操作可统一加「需要输入确认/二次点击」模式中的轻量档:按钮文字改为具体后果(如「移除本机模板副本」)。

五、性能相关(影响体感的界面项)

问题 建议 优先级
MaterialPreviewNSImage(contentsOf:) 在主线程同步解码整图,大图/PDF 首页可能卡顿 改为 task 异步加载 + 占位 ProgressView;预览窗口打开先显示缩略图再换全图 P1
Workspace.sortedMatchesmatches(for:)groups、表格行的 index(of:) 都是每次重算的 computed 属性,匹配组多时 Table 滚动会重复计算 在 Store 层缓存排序结果(matches 变更时失效);index(of:)Dictionary(id→index) 替代 P2
ScanPage 分类汇总对每个 category 全量 filter7 × N 一次遍历 reduce 成字典再渲染 P3
MaterialThumbnail 700px 缩略图生成已异步(好);但 task(id: previewURL) 取消旧任务的行为依赖 detached task,建议显式检查 Task.isCancelled 补充取消检查,避免快速滚动时旧图覆盖新图 P2

六、无障碍与本地化细节

  • caption / caption2 + .tertiary 的组合在浅色模式下对比度偏低(如「支持图片和 PDF · PDF 处理首页」),建议 tertiary 只用于辅助信息,主说明用 secondary。
  • MatchConfidenceCell 的颜色(teal/orange)承载了语义,建议在 accessibilityLabel 中补充「评分高/需关注」文字(目前已有百分比,可再补状态词)。
  • PairPage 连线是 Canvas 绘制,VoiceOver 完全不可见;建议在读出的标签中描述配对关系(已有 accessibilityLabel 基础,补充「已与 N 张付款连线」)。

七、实施路线图

阶段 内容 预期收益
P0(先做) PairPage / MatchedPage 搜索与排序;低分组「需关注」过滤 解决材料量大时的核心查找痛点
P1 颜色语义统一 + 深色模式适配;语义色/间距 token 化;空状态行动按钮;ScanPage 信息层级重组;MaterialPreview 异步加载;AdminView 拆分 视觉一致性与小屏/深色体验
P2 统一通知组件;键盘快捷键;表格 MaterialCell 缩略图 popover;分组小计;模板字段可视化点选;拖拽动效;进度 Dock 反馈 效率与细节打磨
P3 统计卡组件化、金额小图表、模板卡片徽标、签字岗位快选 锦上添花

约束提醒:以上均为界面层建议,实施时须保持 README 中列明的业务口径不变(PPT 版式、金额计算口径、勾选保留规则等),尤其 P1 中 ScanPage 重组不要改变「再次导入替换工作区」的确认流程。