#![cfg_attr(all(windows, not(debug_assertions)), windows_subsystem = "windows")]
use std::{env, fs};
use zsui::{
native_window, NativeWindowSmokeRunOptions, Point, ZsActionAreaSpec, ZsActionButtonSpec,
ZsGroupCardSpec, ZsIcon, ZsNavItemSpec, ZsRowAccessory, ZsShellContentRowSpec,
ZsShellLayoutSpec,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = env::args().skip(1).collect::<Vec<_>>();
let shell = invoice_shell();
let audit = shell.audit();
assert!(audit.valid, "{:?}", audit.issues);
let builder = if args.iter().any(|argument| argument == "--benchmark-empty") {
native_window("发票工具 · ZSUI")
.size(1000, 700)
.min_size(820, 560)
.release_view_when_hidden()
} else {
native_window("发票工具 · ZSUI")
.size(1000, 700)
.min_size(820, 560)
.release_view_when_hidden()
.shell_layout(shell)
};
if args.iter().any(|arg| arg == "--smoke") {
let artifact_dir = "target/invoice-ui-comparison";
fs::create_dir_all(artifact_dir)?;
let screenshot = args
.windows(2)
.find(|pair| pair[0] == "--screenshot")
.map(|pair| pair[1].clone())
.unwrap_or_else(|| format!("{artifact_dir}/zsui.png"));
let report = builder.run_smoke(
NativeWindowSmokeRunOptions::new(1_800)
.screenshot_file(screenshot)
.require_screenshot(true)
.native_view_click(Point { x: 120, y: 184 })
.native_view_scroll(Point { x: 820, y: 430 }, 48),
)?;
println!("{}", serde_json::to_string_pretty(&report)?);
return Ok(());
}
builder.run()?;
Ok(())
}
fn invoice_shell() -> ZsShellLayoutSpec {
ZsShellLayoutSpec::new("invoice-tool", "发票重命名")
.app_title("票据工坊")
.selected_nav("rename")
.nav_item(ZsNavItemSpec::new("merge", "发票合并打印").semantic_icon(ZsIcon::Copy))
.nav_item(ZsNavItemSpec::new("extract", "发票信息提取").semantic_icon(ZsIcon::Search))
.nav_item(ZsNavItemSpec::new("rename", "发票重命名").semantic_icon(ZsIcon::Edit))
.nav_item(ZsNavItemSpec::new("folders", "发票划分文件夹").semantic_icon(ZsIcon::Folder))
.card(
ZsGroupCardSpec::new("rule", "自定义重命名规则")
.description("使用发票字段生成清晰、稳定的文件名")
.row(
ZsShellContentRowSpec::new("rule-template", "销售方名称_税额")
.description("示例:示例销售方_28.30.pdf")
.accessory(ZsRowAccessory::value("已启用")),
)
.row(
ZsShellContentRowSpec::new("conflict", "重名处理")
.description("保留原文件,并为重名文件追加序号")
.accessory(ZsRowAccessory::dropdown(
"追加序号",
["追加序号".to_string(), "覆盖".to_string()],
)),
),
)
.card(
ZsGroupCardSpec::new("files", "待处理发票 · 2")
.row(
ZsShellContentRowSpec::new("invoice-1", "示例销售方_28.30.pdf")
.description("原文件:20260714_001.pdf · 电子发票")
.accessory(ZsRowAccessory::button("移除", "invoice.remove.1")),
)
.row(
ZsShellContentRowSpec::new("invoice-2", "示例发票_16.80.pdf")
.description("原文件:扫描件_0714.pdf · 已识别销售方和税额")
.accessory(ZsRowAccessory::button("移除", "invoice.remove.2")),
),
)
.card(
ZsGroupCardSpec::new("output", "输出设置")
.row(
ZsShellContentRowSpec::new("output-folder", "输出文件夹")
.description("处理后的文件保存在原文件旁的“已重命名”目录")
.accessory(ZsRowAccessory::accent_button("选择文件夹", "output.choose")),
)
.row(
ZsShellContentRowSpec::new("keep-source", "保留原始文件")
.description("完成后仍可从原始名称追溯发票")
.accessory(ZsRowAccessory::toggle(true)),
),
)
.card(
ZsGroupCardSpec::new("confirmation", "输出确认").row(
ZsShellContentRowSpec::new("confirmation-summary", "将重命名 2 张发票")
.description("保留原始文件,结果写入“已重命名”目录")
.accessory(ZsRowAccessory::value("待确认")),
),
)
.action_area(
ZsActionAreaSpec::new()
.secondary(ZsActionButtonSpec::secondary("invoice.add", "添加发票"))
.primary(ZsActionButtonSpec::primary("invoice.rename", "开始重命名")),
)
}