shish 2 месяцев назад
Родитель
Сommit
7c8dc1b795
1 измененных файлов с 211 добавлено и 31 удалено
  1. 211 31
      hdPad/src/pages/home/components/selectPrice.vue

+ 211 - 31
hdPad/src/pages/home/components/selectPrice.vue

@@ -62,7 +62,10 @@
                     </view>
                     <view class="pay-submit-column">
                         <view class="pay-submit-btn" @tap.stop="submitGathering">提交</view>
-                        <view class="pay-submit-btn pay-submit-btn-secondary" @tap.stop="cancel">取消</view>
+                        <view class="pay-submit-row2">
+                            <view class="pay-submit-btn pay-submit-btn-secondary" @tap.stop="cancel">取消</view>
+                            <view class="pay-submit-btn pay-submit-btn-stash" @tap.stop="stashCurrent">暂存</view>
+                        </view>
                     </view>
                     </view>
                 </view>
@@ -119,16 +122,17 @@
                 <scroll-view scroll-y class="calc-history-popup-body">
                     <view
                         v-for="(row, idx) in calcHistory"
-                        :key="'hist-' + idx"
+                        :key="row.id || 'hist-' + idx"
                         class="history-item"
-                        :data-idx="idx"
-                        @tap.stop="onHistoryRowTap"
                     >
-                        <view class="history-line">
-                            <text class="history-time">{{ row.timeLabel }}</text>
-                            <text class="history-total">合计 {{ formatMoney(row.total) }}</text>
+                        <view class="history-item-body" :data-idx="idx" @tap.stop="onHistoryRowTap">
+                            <view class="history-line">
+                                <text class="history-time">{{ row.timeLabel }}</text>
+                                <text class="history-total">合计 {{ formatMoney(row.total) }}</text>
+                            </view>
+                            <text class="history-detail">{{ row.detailText }}</text>
                         </view>
-                        <text class="history-detail">{{ row.detailText }}</text>
+                        <text class="history-del" :data-idx="idx" @tap.stop="onHistoryDeleteTap">删除</text>
                     </view>
                     <view v-if="calcHistory.length === 0" class="history-empty">暂无记录</view>
                 </scroll-view>
@@ -137,6 +141,7 @@
     </view>
 </template>
 <script>
+const CALC_HISTORY_STORAGE_KEY = 'hdPad_selectPrice_calcHistory'
 export default {
     name: 'selectPrice',
     data() {
@@ -187,7 +192,53 @@ export default {
             immediate: true,
         },
     },
+    mounted() {
+        this.loadCalcHistoryFromStorage()
+    },
     methods: {
+        loadCalcHistoryFromStorage() {
+            try {
+                const raw = uni.getStorageSync(CALC_HISTORY_STORAGE_KEY)
+                if (raw === undefined || raw === null || raw === '') {
+                    return
+                }
+                const list = typeof raw === 'string' ? JSON.parse(raw) : raw
+                if (!Array.isArray(list) || !list.length) {
+                    return
+                }
+                const max = this.maxHistory
+                this.calcHistory = list.slice(0, max).map((row, i) => this.normalizeHistoryRow(row, i))
+            } catch (e) {
+                console.warn('[selectPrice] loadCalcHistoryFromStorage', e)
+            }
+        },
+        normalizeHistoryRow(row, idx) {
+            const r = row && typeof row === 'object' ? row : {}
+            const id =
+                r.id != null && String(r.id) !== ''
+                    ? String(r.id)
+                    : 'hist-' + Date.now() + '-' + idx
+            return {
+                id,
+                tokens: Array.isArray(r.tokens) ? r.tokens : null,
+                addends: Array.isArray(r.addends) ? r.addends : null,
+                calcInput: r.calcInput != null ? String(r.calcInput) : '',
+                total: r.total,
+                timeLabel: r.timeLabel != null ? String(r.timeLabel) : '--:--',
+                detailText: r.detailText != null ? String(r.detailText) : '',
+                cashSnapshot: r.cashSnapshot,
+                priceSnapshot: r.priceSnapshot,
+                orderOnly: !!r.orderOnly,
+                source: r.source === 'stash' ? 'stash' : 'submit',
+            }
+        },
+        persistCalcHistoryToStorage() {
+            try {
+                uni.setStorageSync(CALC_HISTORY_STORAGE_KEY, JSON.stringify(this.calcHistory))
+            } catch (e) {
+                console.warn('[selectPrice] persistCalcHistoryToStorage', e)
+            }
+        },
         /** 全页可点区域统一按键音(依赖 $util.hitVoice) */
         tapVoice() {
             this.$util.hitVoice()
@@ -409,21 +460,78 @@ export default {
             this.applyHistoryRow(row)
             this.closeCalcHistory()
         },
-        pushHistorySnapshot(total) {
+        onHistoryDeleteTap(e) {
+            this.tapVoice()
+            const idx = Number(e.currentTarget.dataset.idx)
+            if (isNaN(idx) || idx < 0 || idx >= this.calcHistory.length) {
+                return
+            }
+            this.calcHistory.splice(idx, 1)
+            this.persistCalcHistoryToStorage()
+        },
+        pushHistorySnapshot(total, opts) {
+            opts = opts || {}
             const now = new Date()
             const hh = String(now.getHours())
             const m = now.getMinutes() < 10 ? '0' + now.getMinutes() : String(now.getMinutes())
             const timeLabel = hh + ':' + m
-            const detailText = this.getExprDisplayString(true)
-            this.calcHistory.unshift({
-                tokens: this.cloneTokens(this.tokens),
-                total,
-                timeLabel,
-                detailText,
-            })
+            const hasCalc =
+                this.tokens.length > 0 ||
+                (this.calcInput != null && !this.$util.isEmpty(this.calcInput))
+            const orderOnly =
+                opts.orderOnly !== undefined
+                    ? !!opts.orderOnly
+                    : !hasCalc
+            const expr = this.getExprDisplayString(true)
+            const detailText = orderOnly
+                ? '订单 ' + this.formatMoney(total)
+                : expr || '订单 ' + this.formatMoney(total)
+            const row = this.normalizeHistoryRow(
+                {
+                    id: Date.now() + '-' + Math.random().toString(16).slice(2, 10),
+                    tokens: this.cloneTokens(this.tokens),
+                    calcInput: this.calcInput != null ? String(this.calcInput) : '',
+                    total,
+                    timeLabel,
+                    detailText,
+                    cashSnapshot: Number(this.cash) || 0,
+                    priceSnapshot: Number(this.price) || 0,
+                    orderOnly,
+                    source: opts.source === 'stash' ? 'stash' : 'submit',
+                },
+                0
+            )
+            this.calcHistory.unshift(row)
             if (this.calcHistory.length > this.maxHistory) {
                 this.calcHistory.pop()
             }
+            this.persistCalcHistoryToStorage()
+        },
+        stashCurrent() {
+            this.tapVoice()
+            const hasCalc =
+                this.tokens.length > 0 ||
+                (this.calcInput != null && !this.$util.isEmpty(this.calcInput))
+            const st = this.stackTotal
+            const orderP = Number(this.price)
+            let total = null
+            let orderOnly = false
+            if (hasCalc) {
+                if (!Number.isFinite(st) || isNaN(st) || st <= 0) {
+                    this.$msg('请先完成有效算式后再暂存')
+                    return
+                }
+                total = st
+                orderOnly = false
+            } else if (!isNaN(orderP) && orderP > 0) {
+                total = orderP
+                orderOnly = true
+            } else {
+                this.$msg('没有可暂存的内容')
+                return
+            }
+            this.pushHistorySnapshot(total, { source: 'stash', orderOnly })
+            this.$msg('已暂存')
         },
         clearStack() {
             this.tokens = []
@@ -433,17 +541,58 @@ export default {
             if (!row) {
                 return
             }
-            if (row.tokens !== undefined && row.tokens !== null) {
-                this.tokens = this.cloneTokens(row.tokens)
-                this.calcInput = ''
-            } else if (row.addends && row.addends.length) {
+            const ci = row.calcInput != null ? String(row.calcInput) : ''
+            const hasTok = row.tokens && row.tokens.length > 0
+            const hasLegacy = row.addends && row.addends.length
+
+            const restoreCash = () => {
+                this.$nextTick(() => {
+                    if (row.cashSnapshot != null && !isNaN(Number(row.cashSnapshot))) {
+                        this.cash = Number(row.cashSnapshot)
+                    }
+                })
+            }
+
+            if (hasLegacy) {
                 this.tokens = this.legacyAddendsToTokens(row.addends)
+                this.calcInput = ci
+                this.keyboardTarget = 'calc'
+                this.checkType = 3
+                restoreCash()
+                return
+            }
+            if (hasTok) {
+                this.tokens = this.cloneTokens(row.tokens)
+                this.calcInput = ci
+                this.keyboardTarget = 'calc'
+                this.checkType = 3
+                restoreCash()
+                return
+            }
+            if (!this.$util.isEmpty(ci)) {
+                this.tokens = []
+                this.calcInput = ci
+                this.keyboardTarget = 'calc'
+                this.checkType = 3
+                restoreCash()
+                return
+            }
+            const orderAmt =
+                row.priceSnapshot != null && !isNaN(Number(row.priceSnapshot)) && Number(row.priceSnapshot) > 0
+                    ? Number(row.priceSnapshot)
+                    : Number(row.total)
+            if (!isNaN(orderAmt) && orderAmt > 0) {
+                this.tokens = []
                 this.calcInput = ''
-            } else {
+                this.price = orderAmt
+                this.cash =
+                    row.cashSnapshot != null && !isNaN(Number(row.cashSnapshot))
+                        ? Number(row.cashSnapshot)
+                        : 0
+                this.keyboardTarget = 'order'
+                this.checkType = 1
                 return
             }
-            this.keyboardTarget = 'calc'
-            this.checkType = 3
         },
         cancel() {
             this.tapVoice()
@@ -560,7 +709,13 @@ export default {
                 this.$msg('订单金额须大于 0')
                 return
             }
-            this.pushHistorySnapshot(p)
+            const hasCalc =
+                this.tokens.length > 0 ||
+                (this.calcInput != null && !this.$util.isEmpty(this.calcInput))
+            this.pushHistorySnapshot(p, {
+                source: 'submit',
+                orderOnly: !hasCalc,
+            })
             this.$emit('zjGathering', { price: p, name: this.name, cash: Number(this.cash) || 0 })
             this.price = 0
             this.checkType = 3
@@ -719,6 +874,17 @@ export default {
         flex-direction: column;
         margin-top: 12upx;
     }
+    .pay-submit-row2 {
+        display: flex;
+        flex-direction: row;
+        margin-top: 8upx;
+    }
+    .pay-submit-row2 .pay-submit-btn {
+        flex: 1;
+    }
+    .pay-submit-row2 .pay-submit-btn + .pay-submit-btn {
+        margin-left: 8upx;
+    }
     .pay-submit-btn {
         text-align: center;
         font-size: 16upx;
@@ -729,9 +895,6 @@ export default {
         border: 1upx solid #09c567;
         font-weight: 600;
         box-sizing: border-box;
-        & + .pay-submit-btn {
-            margin-top: 8upx;
-        }
     }
     .pay-submit-btn-secondary {
         background: #f7f7f7;
@@ -739,6 +902,12 @@ export default {
         border-color: #dddddd;
         font-weight: 500;
     }
+    .pay-submit-btn-stash {
+        background: #ffffff;
+        color: #09c567;
+        border-color: #09c567;
+        font-weight: 600;
+    }
     .pay-submit-btn:active {
         opacity: 0.9;
     }
@@ -775,7 +944,7 @@ export default {
         justify-content: center;
     }
     .calc-placeholder {
-        font-size: 11upx;
+        font-size: 12upx;
         color: #999999;
     }
     .calc-num {
@@ -865,11 +1034,22 @@ export default {
         box-sizing: border-box;
     }
     .history-item {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
         padding: 8upx 6upx;
         border-bottom: 1upx solid #f0f0f0;
-        & + .history-item {
-            margin-top: 0;
-        }
+    }
+    .history-item-body {
+        flex: 1;
+        min-width: 0;
+    }
+    .history-del {
+        flex-shrink: 0;
+        font-size: 11upx;
+        color: #e54545;
+        padding: 4upx 8upx;
+        margin-left: 6upx;
     }
     .history-line {
         display: flex;