import SwiftUI struct OrderSourcePicker: View { let selection: OrderSourceSelection? let people: [OrderSourcePerson] let leadsForPerson: (OrderSourcePerson) -> [OrderSourceLead] let leadsLoading: Bool let onSheetOpen: () -> Void let onPersonClick: (OrderSourcePerson) -> Void let onSelectionChange: (OrderSourceSelection) -> Void let callPhone: (String) -> Void @State private var sheetVisible = false @State private var navigationPath = NavigationPath() @State private var previewImages: [String] = [] @State private var previewIndex: Int? var body: some View { VStack(alignment: .leading, spacing: 10) { HStack(alignment: .center) { VStack(alignment: .leading, spacing: 4) { Text("订单来源") .font(.system(size: 14, weight: .medium)) .foregroundStyle(OrderSourceColors.text563) if let selection { HStack(spacing: 10) { Text(selection.person.name) .font(.system(size: 13, weight: .medium)) .foregroundStyle(OrderSourceColors.text333) if !selection.person.phone.isEmpty { Text(selection.person.phone) .font(.system(size: 13)) .foregroundStyle(OrderSourceColors.text666) } } } else { Text("选择获客员及其创建的带客单") .font(.system(size: 13)) .foregroundStyle(OrderSourceColors.text666) } } Spacer(minLength: 0) Image(systemName: "chevron.right") .font(.system(size: 12, weight: .semibold)) .foregroundStyle(OrderSourceColors.primary) .frame(width: 20, height: 20) } if let selection { Divider().overlay(OrderSourceColors.divider) SourceLeadContent( lead: selection.lead, compact: true, enablePhoneCall: false, onCall: callPhone, onImageTap: { images, index in previewImages = images previewIndex = index } ) } } .padding(12) .frame(maxWidth: .infinity, alignment: .leading) .background(OrderSourceColors.entryBg, in: RoundedRectangle(cornerRadius: 8)) .overlay( RoundedRectangle(cornerRadius: 8) .stroke(OrderSourceColors.border, lineWidth: 1) ) .contentShape(RoundedRectangle(cornerRadius: 8)) .onTapGesture { openSheet() } .sheet(isPresented: $sheetVisible) { sheetContainer .presentationDetents([.medium, .large]) .presentationDragIndicator(.visible) } .sheet(item: previewBinding) { item in SimpleImagePreviewSheet( imageUrls: item.urls, startIndex: item.index, onDismiss: { previewIndex = nil } ) } } private func openSheet() { onSheetOpen() navigationPath = NavigationPath() sheetVisible = true } private var previewBinding: Binding { Binding( get: { guard let previewIndex else { return nil } return ImagePreviewItem(urls: previewImages, index: previewIndex) }, set: { newValue in if newValue == nil { previewIndex = nil } } ) } private var sheetContainer: some View { NavigationStack(path: $navigationPath) { personSheetContent .navigationDestination(for: OrderSourcePerson.self) { person in leadSheetContent(person: person) } .navigationDestination(for: OrderSourceImagePreviewRoute.self) { route in SimpleImagePreviewScreen( imageUrls: route.urls, startIndex: route.startIndex ) } } .background(Color.white) } private var personSheetContent: some View { ScrollView { VStack(alignment: .leading, spacing: 0) { Text("选择人员后,再选择该人员创建的带客单") .font(.system(size: 13)) .foregroundStyle(OrderSourceColors.text666) .padding(.bottom, 14) if people.isEmpty { Text("暂无合作获客员") .font(.system(size: 14)) .foregroundStyle(OrderSourceColors.text666) .frame(maxWidth: .infinity) .padding(.vertical, 32) } else { LazyVStack(spacing: 10) { ForEach(people) { person in SourcePersonRow( person: person, selected: selection?.person.key == person.key, onCall: callPhone, onTap: { onPersonClick(person) navigationPath.append(person) } ) } } } } .padding(.horizontal, 16) .padding(.top, 8) .padding(.bottom, 24) } .navigationTitle("选择获客员") .navigationBarTitleDisplayMode(.inline) } private func leadSheetContent(person: OrderSourcePerson) -> some View { ScrollView { VStack(alignment: .leading, spacing: 0) { if !person.phone.isEmpty { HStack(spacing: 6) { Text(person.phone) .font(.system(size: 13)) .foregroundStyle(OrderSourceColors.primary) .onTapGesture { callPhone(person.phone) } AcquirerCallButton(phone: person.phone, onCall: callPhone) } .padding(.bottom, 14) } if leadsLoading { ProgressView() .tint(OrderSourceColors.primary) .frame(maxWidth: .infinity) .padding(.top, 32) } else { let leads = leadsForPerson(person) if leads.isEmpty { Text("暂无可绑定带客单") .font(.system(size: 14)) .foregroundStyle(OrderSourceColors.text666) .frame(maxWidth: .infinity) .padding(.vertical, 24) } else { LazyVStack(spacing: 12) { ForEach(leads) { lead in SourceLeadCard( lead: lead, selected: selection?.person.key == person.key && selection?.lead.key == lead.key, onCall: callPhone, onImageTap: { images, index in navigationPath.append( OrderSourceImagePreviewRoute(urls: images, startIndex: index) ) }, onSelect: { onSelectionChange(OrderSourceSelection(person: person, lead: lead)) sheetVisible = false } ) } } } } } .padding(.horizontal, 16) .padding(.top, 8) .padding(.bottom, 24) } .navigationTitle("\(person.name)创建的带客单") .navigationBarTitleDisplayMode(.inline) } } private struct ImagePreviewItem: Identifiable { let urls: [String] let index: Int var id: String { "\(index)-\(urls.joined())" } } private struct OrderSourceImagePreviewRoute: Hashable { let urls: [String] let startIndex: Int }