新增门店订单与核销管理列表,对齐 Android 订单能力并完善账号级缓存。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-29 14:46:10 +08:00
parent c4de3d17d0
commit 08492df6ce
51 changed files with 3668 additions and 102 deletions

View File

@ -0,0 +1,207 @@
//
// OrderDialogViews.swift
// suixinkan
//
// Created by Codex on 2026/6/29.
//
import SwiftUI
/// 退 Android OrderRefundDialog
struct OrderRefundDialogView: View {
@ObservedObject var viewModel: OrderRefundViewModel
let order: OrderEntity
let onDismiss: () -> Void
let onSuccess: () -> Void
@Environment(\.ordersAPI) private var ordersAPI
var body: some View {
NavigationStack {
Form {
Section("订单号") {
Text(order.orderNumber)
}
Section("退款方式") {
Picker("退款方式", selection: $viewModel.mode) {
ForEach(OrderRefundMode.allCases) { mode in
Text(mode.title).tag(mode)
}
}
.pickerStyle(.segmented)
if viewModel.mode == .partial {
TextField("退款金额", text: $viewModel.amount)
.keyboardType(.decimalPad)
} else {
Text("可退金额:¥\(viewModel.availableAmountText(for: order))")
.foregroundStyle(AppDesign.textSecondary)
}
}
Section("退款原因") {
TextField("请输入退款原因", text: $viewModel.reason, axis: .vertical)
.lineLimit(3...6)
}
if let errorMessage = viewModel.errorMessage {
Section {
Text(errorMessage)
.foregroundStyle(.red)
}
}
}
.navigationTitle("订单退款")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("取消", action: onDismiss)
}
ToolbarItem(placement: .confirmationAction) {
Button(viewModel.submitting ? "提交中" : "确认") {
Task {
let success = await viewModel.submit(api: ordersAPI, item: order)
if success {
onSuccess()
}
}
}
.disabled(viewModel.submitting)
}
}
}
}
}
/// / Android SendGiftDialog
struct SendGiftDialogView: View {
@State private var photoNum: Int
@State private var videoNum: Int
let context: OrdersViewModel.SendGiftContext
let onDismiss: () -> Void
let onConfirm: (Int, Int) -> Void
init(context: OrdersViewModel.SendGiftContext, onDismiss: @escaping () -> Void, onConfirm: @escaping (Int, Int) -> Void) {
self.context = context
self.onDismiss = onDismiss
self.onConfirm = onConfirm
_photoNum = State(initialValue: context.sendPhotoNum)
_videoNum = State(initialValue: context.sendVideoNum)
}
var body: some View {
NavigationStack {
Form {
Section {
stepperRow(
title: "修图张数(已有\(context.nowPhotoNum)张,最多赠20张)",
value: $photoNum,
range: 0...20
)
stepperRow(
title: "视频剪辑(已有\(context.nowVideoNum)条,最多赠5条)",
value: $videoNum,
range: 0...5
)
}
}
.navigationTitle("赠送修图/视频")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("取消", action: onDismiss)
}
ToolbarItem(placement: .confirmationAction) {
Button("确认") {
onConfirm(photoNum, videoNum)
}
}
}
}
}
private func stepperRow(title: String, value: Binding<Int>, range: ClosedRange<Int>) -> some View {
HStack {
Text(title)
.font(.system(size: 13))
.foregroundStyle(AppDesign.orderLabelColor)
Spacer()
Button("-") { value.wrappedValue = max(range.lowerBound, value.wrappedValue - 1) }
.buttonStyle(.plain)
Text("\(value.wrappedValue)")
.frame(minWidth: 30)
Button("+") { value.wrappedValue = min(range.upperBound, value.wrappedValue + 1) }
.buttonStyle(.plain)
}
}
}
/// 退/退
struct StoreOrderRefundDialogView: View {
let orderNumber: String
let actualPayAmount: String
let initialMode: OrderRefundMode
let onDismiss: () -> Void
let onConfirm: (OrderRefundMode, String, String) -> Void
@State private var mode: OrderRefundMode
@State private var amount = ""
@State private var reason = ""
init(
orderNumber: String,
actualPayAmount: String,
initialMode: OrderRefundMode,
onDismiss: @escaping () -> Void,
onConfirm: @escaping (OrderRefundMode, String, String) -> Void
) {
self.orderNumber = orderNumber
self.actualPayAmount = actualPayAmount
self.initialMode = initialMode
self.onDismiss = onDismiss
self.onConfirm = onConfirm
_mode = State(initialValue: initialMode)
_amount = State(initialValue: actualPayAmount)
}
var body: some View {
NavigationStack {
Form {
Section("订单号") {
Text(orderNumber)
}
Section("退款方式") {
Picker("退款方式", selection: $mode) {
ForEach(OrderRefundMode.allCases) { item in
Text(item.title).tag(item)
}
}
.pickerStyle(.segmented)
if mode == .partial {
TextField("退款金额", text: $amount)
.keyboardType(.decimalPad)
}
}
Section("退款原因") {
TextField("请输入退款原因", text: $reason, axis: .vertical)
.lineLimit(3...6)
}
}
.navigationTitle("申请退款")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("取消", action: onDismiss)
}
ToolbarItem(placement: .confirmationAction) {
Button("提交") {
let refundAmount = mode == .full ? actualPayAmount : amount
onConfirm(mode, refundAmount, reason)
}
.disabled(reason.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
}
}
}
}
}