From 66ae382b55e43afd6738f61cacd76d19320f2ec5 Mon Sep 17 00:00:00 2001 From: zhanchao Date: Thu, 3 Sep 2026 17:58:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9D=83=E7=9B=8A=E5=A2=9E=E5=8A=A0=E6=80=BB?= =?UTF-8?q?=E9=A2=9D=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/message/benefit-entry.vue | 269 ++++++++++++++++++++++++++++++-- 1 file changed, 255 insertions(+), 14 deletions(-) diff --git a/pages/message/benefit-entry.vue b/pages/message/benefit-entry.vue index a400db9..4771700 100644 --- a/pages/message/benefit-entry.vue +++ b/pages/message/benefit-entry.vue @@ -43,7 +43,7 @@ 折扣 - + {{ Number(entry.discount).toFixed(1) }} @@ -143,7 +143,7 @@ 折扣 - + {{ Number(entry.discount).toFixed(1) }} @@ -319,8 +319,40 @@ @@ -369,10 +401,67 @@ const todoExecutorPickerVisible = ref(false); const todoExecutorTarget = ref(null); const todoExecutorKeyword = ref(""); const todoExecutorRefreshing = ref(false); +const benefitDetailVisible = ref(false); const todoTypeOptions = Object.entries(TODO_EVENT_TYPE_LABELS).map(([value, label]) => ({ value, label })); let searchTimer = null; let entryKey = 0; +function toggleBenefitDetail() { + benefitDetailVisible.value = !benefitDetailVisible.value; +} + +const benefitDetailItems = computed(() => entries.value.flatMap((entry) => { + if (entry.isPackage) { + return (entry.projects || []) + .filter((project) => project.selected) + .map((project) => ({ + key: `${entry.key}_${project.key}`, + name: project.project?.projectName || "未命名权益", + quantity: Math.max(0, toNumber(project.usageCount, 1)), + discount: toNumber(project.discount), + totalAmount: Math.max(0, toNumber(project.totalPrice)), + isFree: false, + })); + } + + if (!entry.project?._id) return []; + return [{ + key: entry.key, + name: entry.project.projectName || "未命名权益", + quantity: Math.max(0, toNumber(entry.usageCount, 1)), + discount: toNumber(entry.discount), + totalAmount: Math.max(0, toNumber(entry.isFree ? 0 : entry.totalPrice)), + isFree: Boolean(entry.isFree), + }]; +})); + +const benefitSummary = computed(() => entries.value.reduce((summary, entry) => { + if (entry.isPackage) { + summary.selectedCount += 1; + const originalAmount = toNumber(entry.packagePrice || entry.price) * Math.max(0, toNumber(entry.usageCount, 1)); + const totalAmount = entry.isFree ? 0 : Math.max(0, toNumber(entry.totalPrice)); + summary.originalAmount += originalAmount; + summary.totalAmount += totalAmount; + summary.savedAmount += Math.max(0, originalAmount - totalAmount); + return summary; + } + + if (!entry.project?._id) return summary; + summary.selectedCount += 1; + const usageCount = Math.max(0, toNumber(entry.usageCount, 1)); + const originalAmount = toNumber(entry.price) * usageCount; + const totalAmount = entry.isFree ? 0 : Math.max(0, toNumber(entry.totalPrice)); + summary.originalAmount += originalAmount; + summary.totalAmount += totalAmount; + summary.savedAmount += Math.max(0, originalAmount - totalAmount); + return summary; +}, { + selectedCount: 0, + originalAmount: 0, + savedAmount: 0, + totalAmount: 0, +})); + function formatDate(date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); @@ -1755,6 +1844,18 @@ async function submitEntries() { width: 100%; } +.discount-picker.discount-disabled { + opacity: 0.62; + pointer-events: none; +} + +.discount-picker.discount-disabled .number-input { + border-color: #d1d5db; + background: #f3f4f6; + color: #9ca3af; + -webkit-text-fill-color: #9ca3af; +} + .field-row { display: flex; gap: 20rpx; @@ -1876,17 +1977,163 @@ async function submitEntries() { } .footer-bar { + position: relative; display: flex; + align-items: center; gap: 20rpx; - padding: 20rpx 24rpx; - background: rgba(245, 246, 248, 0.96); + padding: 14rpx 24rpx 18rpx; + background: #fff; border-top: 1rpx solid #eef2f7; - backdrop-filter: blur(12px); + box-shadow: 0 -4rpx 16rpx rgba(15, 23, 42, 0.04); box-sizing: border-box; + z-index: 10; } -.footer-bar button { +.footer-summary { flex: 1; + display: flex; + align-items: center; + gap: 14rpx; + min-width: 0; +} + +.total-summary { + display: flex; + flex-direction: row; + align-items: baseline; + gap: 6rpx; + min-width: 0; + white-space: nowrap; +} + +.summary-label { + color: #6b7280; + font-size: 22rpx; + line-height: 1.2; + white-space: nowrap; +} + +.summary-saving { + color: #16a34a; +} + +.summary-total-value { + color: #e85c2f; + font-size: 32rpx; + font-weight: 700; + line-height: 1.2; + white-space: nowrap; +} + +.detail-trigger { + flex-shrink: 0; + padding-left: 14rpx; + border-left: 1rpx solid #edf0f3; + color: #6b7280; + font-size: 24rpx; + line-height: 1.2; + white-space: nowrap; +} + +.benefit-detail-panel { + position: absolute; + right: 0; + bottom: 100%; + left: 0; + max-height: calc(100vh - 220rpx); + overflow: hidden; + padding: 20rpx 24rpx 18rpx; + border-top: 1rpx solid #eef2f7; + border-radius: 24rpx 24rpx 0 0; + background: #fff; + box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.08); + box-sizing: border-box; + opacity: 0; + visibility: hidden; + pointer-events: none; + transform: translateY(100%); + transform-origin: bottom center; + transition: + opacity 180ms ease, + transform 180ms ease, + visibility 180ms ease; +} + +.benefit-detail-panel-visible { + opacity: 1; + visibility: visible; + pointer-events: auto; + transform: translateY(0); +} + +.detail-header, +.detail-row { + display: flex; + align-items: center; + gap: 12rpx; + min-height: 60rpx; + color: #6b7280; + font-size: 27rpx; +} + +.detail-header { + min-height: 48rpx; + color: #9ca3af; + font-size: 24rpx; +} + +.detail-project-name { + flex: 1; + min-width: 0; +} + +.detail-project-name-value { + overflow: hidden; + color: #374151; + text-overflow: ellipsis; + white-space: nowrap; +} + +.detail-quantity, +.detail-discount { + flex: 0 0 72rpx; + text-align: center; + white-space: nowrap; +} + +.detail-amount { + flex: 0 0 130rpx; + color: #374151; + text-align: right; + white-space: nowrap; +} + +.detail-empty { + padding: 22rpx 0; + color: #9ca3af; + font-size: 26rpx; + text-align: center; +} + +.detail-row-total { + margin-top: 8rpx; + padding-top: 14rpx; + border-top: 1rpx solid #eef2f7; + color: #1f2937; + font-weight: 600; +} + +.detail-row-total .detail-amount { + color: #e85c2f; + font-weight: 700; +} + +.footer-actions { + flex: 0 0 250rpx; +} + +.footer-actions button { + width: 100%; min-height: 88rpx; padding: 0; display: flex; @@ -1897,12 +2144,6 @@ async function submitEntries() { line-height: 1.2; } -.cancel-button { - color: #0877f1; - background: #fff; - border: 1rpx solid #0877f1; -} - .submit-button { color: #fff; background: linear-gradient(135deg, #0f84ff 0%, #0877f1 100%);