From e1fdb816ab7f837c530892b0baed631ddadccba3 Mon Sep 17 00:00:00 2001 From: csj <2073278411@qq.com> Date: Sun, 13 Sep 2026 10:12:35 +0800 Subject: [PATCH] 1 --- PROJECT-ADMIN.md | 6 ++++++ reimburse/AdminStore.swift | 7 +++++-- reimburse/AdminView.swift | 21 ++++++++++----------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/PROJECT-ADMIN.md b/PROJECT-ADMIN.md index e5a49a7..36827dc 100644 --- a/PROJECT-ADMIN.md +++ b/PROJECT-ADMIN.md @@ -1,5 +1,11 @@ # 管理端接入 +## 删除材料与不使用 + +“报销类型”中的垃圾桶会确认后调用材料类型删除接口,立即从全局材料列表及所有报销类型的材料规则中删除该材料,不删除历史报销附件。即使材料已选“不使用”,也保留删除入口。删除失败不会在本机假装移除;成功后保留其他尚未保存的规则编辑。 + +“不使用”只改变当前报销类型是否需要此材料,需要点击“保存规则”生效,不删除材料类型。 + ## 多附件兼容 项目管理详情现在展示每个材料分类下的全部附件,并支持逐份预览、下载和 ZIP 导出。新版本同时解码旧服务的单附件对象和新服务的附件数组;多附件服务上线时需同步重新构建 Mac 应用。本地 OCR 和 Office 导出不受此次改动影响。 diff --git a/reimburse/AdminStore.swift b/reimburse/AdminStore.swift index e113b81..a8146c8 100644 --- a/reimburse/AdminStore.swift +++ b/reimburse/AdminStore.swift @@ -386,8 +386,11 @@ private final class AdminRedirectGuard: NSObject, URLSessionTaskDelegate, @unche guard access?.platform == true else { throw AdminFailure(message: "只有平台管理员可以删除上传材料类型") } let encoded = kind.kind.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? kind.kind let _: Bool = try await request("/api/admin/upload-kinds/\(encoded)", method: "DELETE") - uploadKinds = try await request("/api/upload-kinds") - policies = try await request("/api/expense-policies") + uploadKinds.removeAll { $0.kind == kind.kind } + for index in policies.indices { + policies[index].materials.removeAll { $0.kind == kind.kind } + policies[index].requiredKinds.removeAll { $0 == kind.kind } + } } func export(_ ids: Set) async throws { guard !ids.isEmpty, ids.count <= 20 else { throw AdminFailure(message: "每次请选择 1 至 20 笔申请") } diff --git a/reimburse/AdminView.swift b/reimburse/AdminView.swift index ef71417..4f34044 100644 --- a/reimburse/AdminView.swift +++ b/reimburse/AdminView.swift @@ -636,14 +636,17 @@ struct AdminView: View { } label: { Image(systemName: "pencil") } .buttonStyle(.borderless) .help("编辑当前类型材料") - Button { - removeMaterial(policy: policy, kind: kind.kind) - if editingPolicyMaterialKind == kind.kind { resetPolicyMaterialEditor() } - } label: { Image(systemName: "trash") } - .buttonStyle(.borderless) - .tint(.red) - .help("从当前报销类型移除") } + Button { + confirm("删除材料类型“\(kind.name)”?将从所有报销类型的材料规则中移除,历史报销附件保留。此操作立即生效;仅暂停使用请选择“不使用”并保存规则。") { + try await model.deleteUploadKind(kind) + if editingPolicyMaterialKind == kind.kind { resetPolicyMaterialEditor() } + } + } label: { Image(systemName: "trash") } + .buttonStyle(.borderless) + .tint(.red) + .help("删除材料类型(所有报销类型生效,历史附件保留)") + .disabled(model.access?.platform != true) } } Divider() @@ -765,10 +768,6 @@ struct AdminView: View { } policy.wrappedValue.requiredKinds = policy.wrappedValue.materials.filter(\.required).map(\.kind) } - private func removeMaterial(policy: Binding, kind: String) { - policy.wrappedValue.materials.removeAll { $0.kind == kind } - policy.wrappedValue.requiredKinds = policy.wrappedValue.materials.filter(\.required).map(\.kind) - } private func resetPolicyMaterialEditor() { editingPolicyMaterialKind = "" newPolicyMaterialName = ""