# 应结账款页面重构方案 ## 需求概述 1. 将商户卡片中的"批量消账"按钮改为"消账" 2. 移除每个订单的"申请消账"按钮 3. 点击"消账"按钮后,进入选择模式,可以选择该商户下的多个订单 4. 选择订单后,按钮文本变为"进行消账(X)",X为选择的订单数量 5. 添加全选/取消全选功能 6. 显示已选订单的汇总金额 7. 限制只能选择未结和逾期状态的订单 8. 点击"进行消账"后,执行批量消账逻辑 ## 数据结构设计 ### 新增状态变量 ```typescript // 选择模式状态 const selectionMode = ref>({}) // 记录每个商户是否处于选择模式 const selectedOrders = ref>({}) // 记录每个商户选中的订单ID列表 ``` ### 计算属性 ```typescript // 计算每个商户选中的订单数量 const selectedCount = computed(() => { return (merchantId: string) => selectedOrders.value[merchantId]?.length || 0 }) // 计算每个商户选中的订单总金额 const selectedAmount = computed(() => { return (merchantId: string) => { const group = groupedByMerchant.value.find(g => g.merchantId === merchantId) if (!group) return 0 const selectedIds = selectedOrders.value[merchantId] || [] return group.settlements .filter(item => selectedIds.includes(item.id)) .reduce((sum, item) => sum + item.amount, 0) } }) // 计算每个商户是否全选 const isAllSelected = computed(() => { return (merchantId: string) => { const group = groupedByMerchant.value.find(g => g.merchantId === merchantId) if (!group) return false const selectableOrders = group.settlements.filter( item => item.status === SettlementStatus.UNSETTLED || item.status === SettlementStatus.OVERDUE ) const selectedIds = selectedOrders.value[merchantId] || [] return selectableOrders.length > 0 && selectableOrders.every(item => selectedIds.includes(item.id)) } }) ``` ## UI 设计 ### 1. 商户头部修改 ```vue 消账 ``` ### 2. 订单列表修改 ```vue ``` ## 功能实现 ### 1. 进入选择模式 ```typescript function enterSelectionMode(merchantId: string) { selectionMode.value[merchantId] = true selectedOrders.value[merchantId] = [] } ``` ### 2. 退出选择模式 ```typescript function exitSelectionMode(merchantId: string) { selectionMode.value[merchantId] = false selectedOrders.value[merchantId] = [] } ``` ### 3. 处理订单点击 ```typescript function handleOrderClick(merchantId: string, orderId: string, status: SettlementStatus) { // 只有在选择模式下且订单状态为未结或逾期时才能选择 if (!selectionMode.value[merchantId]) return if (status !== SettlementStatus.UNSETTLED && status !== SettlementStatus.OVERDUE) return const selected = selectedOrders.value[merchantId] || [] const index = selected.indexOf(orderId) if (index > -1) { // 取消选择 selected.splice(index, 1) } else { // 添加选择 selected.push(orderId) } selectedOrders.value[merchantId] = selected } ``` ### 4. 全选/取消全选 ```typescript function toggleSelectAll(merchantId: string) { const group = groupedByMerchant.value.find(g => g.merchantId === merchantId) if (!group) return const selectableOrders = group.settlements.filter( item => item.status === SettlementStatus.UNSETTLED || item.status === SettlementStatus.OVERDUE ) if (isAllSelected.value(merchantId)) { // 取消全选 selectedOrders.value[merchantId] = [] } else { // 全选 selectedOrders.value[merchantId] = selectableOrders.map(item => item.id) } } ``` ### 5. 批量消账 ```typescript function handleBatchWriteOff(merchantId: string) { const selectedIds = selectedOrders.value[merchantId] || [] if (selectedIds.length === 0) return const group = groupedByMerchant.value.find(g => g.merchantId === merchantId) if (!group) return // 获取选中的订单 const selectedSettlements = group.settlements.filter(item => selectedIds.includes(item.id)) currentSettlement.value = null currentMerchantSettlements.value = selectedSettlements isBatchMode.value = true writeOffVisible.value = true // 退出选择模式 exitSelectionMode(merchantId) } ``` ## 样式设计 ### 1. 选择模式样式 ```scss .order-item { &.selection-mode { display: flex; align-items: flex-start; gap: 20rpx; padding: 24rpx; .checkbox { width: 40rpx; height: 40rpx; border-radius: 50%; border: 2rpx solid #ddd; display: flex; align-items: center; justify-content: center; margin-top: 10rpx; flex-shrink: 0; .i-carbon-checkmark-outline { font-size: 24rpx; color: #999; } .i-carbon-checkmark-filled { font-size: 24rpx; color: $primary; } } &.selected .checkbox { background: rgba($primary, 0.1); border-color: $primary; } &.disabled { opacity: 0.5; pointer-events: none; } .order-content { flex: 1; } } } ``` ### 2. 选择控制区域样式 ```scss .selection-controls { display: flex; flex-direction: column; gap: 12rpx; align-items: flex-end; .select-all-btn { display: flex; align-items: center; gap: 6rpx; padding: 8rpx 16rpx; background: rgba($primary, 0.05); border-radius: 20rpx; color: $primary; font-size: 22rpx; .i-carbon-checkmark-outline, .i-carbon-checkmark-filled { font-size: 24rpx; } } .selected-info { text-align: right; font-size: 22rpx; .amount { display: block; font-size: 26rpx; font-weight: 600; color: $danger; } } .cancel-btn { padding: 8rpx 20rpx; background: rgba($text-2, 0.1); border-radius: 20rpx; color: $text-2; font-size: 24rpx; } .batch-btn-small.active { background: $primary; color: white; } } ``` ## 交互流程 1. 用户点击商户头部的"消账"按钮 2. 进入选择模式,显示选择框和全选按钮 3. 用户可以选择/取消选择符合条件的订单 4. 选择订单后,显示已选数量和汇总金额 5. 点击"进行消账"按钮,打开消账弹窗 6. 消账完成后退出选择模式,刷新列表 ## 注意事项 1. 只有未结和逾期状态的订单才能被选择 2. 选择模式下,其他商户的卡片保持正常状态 3. 消账弹窗需要支持批量处理多个订单 4. 需要处理选择状态的响应式更新