63 lines
3.4 KiB
Swift
63 lines
3.4 KiB
Swift
import SwiftUI
|
|
|
|
struct ExpensePreviewSheet: View {
|
|
@EnvironmentObject var store: WorkspaceStore
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
var body: some View {
|
|
VStack(spacing: 0) {
|
|
HStack(alignment: .top) {
|
|
VStack(alignment: .leading, spacing: 5) {
|
|
Text("报销单预览").font(.title2.bold())
|
|
Text("已选 \(store.expenseMatchIDs.count) 组 · 合并为 \(store.expenseRows.count) 条费用 · \(store.expensePreview?.templateName ?? store.expenseTemplateName)")
|
|
.font(.caption).foregroundStyle(.secondary).lineLimit(2)
|
|
}
|
|
Spacer()
|
|
Text("合计 \(currency(store.expenseRows.reduce(0) { $0 + $1.amountValue }))")
|
|
.font(.title3.bold()).monospacedDigit()
|
|
}.padding(20)
|
|
Divider()
|
|
if store.busy {
|
|
VStack(spacing: 14) {
|
|
ProgressView()
|
|
Text("正在填入所选费用、收款资料和签字岗位…")
|
|
Button("取消生成", action: store.cancel)
|
|
}.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
} else if let preview = store.expensePreview, let layout = preview.layout {
|
|
ExpenseDocumentPreview(layout: layout).id(preview.file)
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
} else {
|
|
ContentUnavailableView("暂时无法生成预览", systemImage: "doc.badge.ellipsis",
|
|
description: Text("请检查模板及收款信息,或重试。"))
|
|
}
|
|
if let error = store.expensePreviewError {
|
|
Label(error, systemImage: "exclamationmark.triangle")
|
|
.font(.callout).foregroundStyle(.red).textSelection(.enabled)
|
|
.frame(maxWidth: .infinity, alignment: .leading).padding(.horizontal, 20).padding(.vertical, 10)
|
|
}
|
|
if let preview = store.expensePreview, !preview.uncalculatedCells.isEmpty {
|
|
Text("部分自定义公式尚未计算:\(preview.uncalculatedCells.prefix(5).joined(separator: "、"))。这些位置在预览中留空,Excel / WPS 打开后会重算。")
|
|
.font(.caption).foregroundStyle(.orange)
|
|
.frame(maxWidth: .infinity, alignment: .leading).padding(.horizontal, 20).padding(.bottom, 10)
|
|
}
|
|
Divider()
|
|
HStack {
|
|
Text("确认后保存此报销单")
|
|
.font(.caption).foregroundStyle(.secondary)
|
|
Spacer()
|
|
Button("返回修改") { dismiss() }.keyboardShortcut(.cancelAction)
|
|
if store.expensePreviewError != nil || store.expensePreview == nil {
|
|
Button("重新预览", action: store.prepareExpensePreview)
|
|
}
|
|
Button("确认并保存…", action: store.saveExpensePreview)
|
|
.buttonStyle(.borderedProminent)
|
|
.disabled(store.expensePreview == nil || store.expensePreviewError != nil)
|
|
}.padding(20).disabled(store.busy)
|
|
}
|
|
.frame(width: min(1200, (NSScreen.main?.visibleFrame.width ?? 1280) - 80),
|
|
height: min(820, (NSScreen.main?.visibleFrame.height ?? 900) - 80))
|
|
.interactiveDismissDisabled(store.busy)
|
|
.onDisappear { store.discardExpensePreview() }
|
|
}
|
|
}
|