Pārlūkot izejas kodu

Merge branch 'feature_收钱吧对接' of elab-damai-h5/h5-dm-orderFront into master

tangy 1 mēnesi atpakaļ
vecāks
revīzija
1b634cc131

+ 15 - 0
src/api/order.ts

@@ -16,6 +16,10 @@ export function createOrders(params?: any) {
     return request.post({ url: '/order/create', params }) //创建订单
 }
 
+export function rockoverDesk(params?: any) {
+    return request.post({ url: '/order/rockover', params }) //翻台
+}
+
 export function dishAdd(params?: any) {
     return request.get({ url: '/order/dishAdd', params }) //添加菜品
 }
@@ -44,6 +48,17 @@ export function orderCheckout(params?: any) {
     return request.get({ url: '/order/checkout', params })
 }
 
+export function orderPay(params?: any) {
+    return request.get({ url: '/order/pay', params })
+}
+export function queryPayStatus(params?: any) {
+    return request.post({ url: '/order/query', params })
+}
+
+export function cancelOrder(params?: any) {
+    return request.post({ url: '/order/cancel', params })
+}
+
 export function deskOrderedDishListAll(params?: any) {
     return request.get({ url: '/orders/orderDishes', params }) //已点商品
 }

BIN
src/assets/images/scan.gif


+ 2 - 2
src/views/dish/lists/edit.vue

@@ -79,7 +79,7 @@
                             <div v-for="(spec, index) in formData.specs" :key="index" class="w-full">
                                 <div class="flex items-center">
                                     <el-input
-                                        v-model="spec.name"
+                                        v-model="spec.name" maxlength="5"
                                         placeholder="请输入规格名称"
                                         class="w-60 mr-2"
                                     />
@@ -100,7 +100,7 @@
                                     </el-tag>
                                     <el-input
                                         v-if="spec.inputVisible"
-                                        ref="InputRef"
+                                        ref="InputRef" maxlength="8"
                                         v-model="spec.inputValue"
                                         class="w-20 ml-1"
                                         size="small"

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 724 - 378
src/views/order/console.vue


+ 196 - 16
src/views/order/index.vue

@@ -15,7 +15,6 @@
                 :key="i"
                 class="p-1 flex-wrap float-left text-center md:w-28 h-28 w-1/3"
             >
-
                 <a href="javascript:void(0);" @click="order_(i)"
                     ><div
                         class="rounded w-full h-full pt-3 relative"
@@ -86,14 +85,54 @@
                 </el-radio-group>
                 <el-button class="w-full" plain @click="order()">开始点餐</el-button>
             </div>
-            <el-button class="w-full mt-1" plain @click="dialogVisible = false">关闭</el-button>
+            <el-button v-if="currentDeskStatus != 2" class="w-full mt-1" plain @click="rockover()">翻台</el-button>
+        </el-dialog>
+        <el-dialog
+            v-model="scanDialogVisible"
+            title="请使用扫码枪扫码支付"
+            width="300px"
+            center
+            :show-close="false"
+            :close-on-click-modal="false"
+            :close-on-press-escape="false"
+        >
+            <div class="text-center">
+                <img
+                    src="@/assets/images/scan.gif"
+                    alt="扫码"
+                    class="mx-auto mb-4"
+                    style="width: 150px"
+                />
+            </div>
+            <template #footer>
+                <div class="dialog-footer">
+                    <el-button @click="scanDialogVisible = false">取消支付</el-button>
+                </div>
+            </template>
+        </el-dialog>
+        <el-dialog
+            v-model="payingDialogVisible"
+            title="支付处理中"
+            width="300px"
+            :show-close="false"
+            :close-on-click-modal="false"
+            :close-on-press-escape="false"
+        >
+            <div class="flex flex-col items-center justify-center py-4">
+            <el-icon class="is-loading mb-4" :size="32">
+                <Loading />
+            </el-icon>
+            <p class="text-gray-600">正在支付中,请不要关闭或退出界面</p>
+            </div>
         </el-dialog>
     </div>
     <console @init="init()" ref="consoleRef"></console>
 </template>
 <script lang="ts" setup>
+// 在 script setup 部分添加
+import { Loading } from '@element-plus/icons-vue'
 import { postAll } from '@/api/org/post'
-import { orderDeskList, createOrders, orderCheckout } from '@/api/order'
+import { orderDeskList, createOrders, orderCheckout, orderPay, queryPayStatus, cancelOrder, rockoverDesk } from '@/api/order'
 import Console from './console.vue'
 import { getOrdersCurrent } from '@/api/orders'
 import feedback from '@/utils/feedback'
@@ -114,7 +153,8 @@ const consoleRef = ref<InstanceType<typeof Console>>()
 const data = reactive({
     userNum: 1, //当前就餐人数
     deskId: null,
-    type: 0 //后台点餐类型:0
+    type: 0, //后台点餐类型:0
+    canScan: false
 })
 const order_ = (i: any) => {
     dialogVisible.value = true
@@ -129,34 +169,162 @@ const order = () => {
         consoleRef.value?.open(currentDesk, data.userNum, res)
         init()
     })
-    console.warn("***order***",currentDesk)
+    console.warn('***order***', currentDesk)
     // router.push({ path: '/order/console', query: { deskID: id } })
 }
+const rockover = () => {
+  feedback.confirm('将重置桌号状态, 确定翻台吗?').then(() => {
+    rockoverDesk(data).then(() => {
+      feedback.notifySuccess('翻台成功!')
+      dialogVisible.value = false
+      init()
+    })
+  }).catch(()=>{
+    dialogVisible.value = false
+  })
+}
 const reorder = () => {
     dialogVisible.value = false
-    consoleRef.value?.open(currentDesk);//继续下单时会把当前餐桌上的订单号ordersId传进去
-    console.warn("***reorder***",currentDesk)
+    consoleRef.value?.open(currentDesk) //继续下单时会把当前餐桌上的订单号ordersId传进去
+    console.warn('***reorder***', currentDesk)
 }
 const refresh = () => {
     isLoading.value = true
     init()
 }
+const scanDialogVisible = ref(false)
+const scanCode = ref('')
+
+// 添加支付中对话框的控制变量
+const payingDialogVisible = ref(false)
+
+// 添加扫码事件监听函数
+const handleScanInput = (event: KeyboardEvent) => {
+    if (event.key === 'Enter') {
+        const code = scanCode.value
+        console.log('扫码内容:', code)
+        if (!data.canScan) {
+            feedback.notifyWarning('正在处理支付,请勿重复扫码')
+            return
+        }
+        data.canScan = false
+        payingDialogVisible.value = true // 显示支付中对话框
+        document.removeEventListener('keydown', handleScanInput)
+
+        // 修改支付处理逻辑
+        orderPay({ oid: currentDesk.oid, code: code })
+          .then((res) => {
+            console.log(res)
+            // 实际上支付成功之后,res返回的是[],如果不是实时成功,返回的是个对象, 形如:{orderId: '123456789', sn: '7895004131583689'}
+            if (res == null || res.length == 0) {
+              feedback.notifySuccess('成功结账' + currentDesk.amount + '元')
+              scanDialogVisible.value = false
+              dialogVisible.value = false
+              payingDialogVisible.value = false // 隐藏支付中对话框
+              init()
+            } else {
+              console.log('支付中')
+              return queryPayStatusWithRetry(res)
+                  .then((paySuccess) => {
+                    if (paySuccess) {
+                      feedback.notifySuccess('成功结账' + currentDesk.amount + '元')
+                      scanDialogVisible.value = false
+                      dialogVisible.value = false
+                      init()
+                    }
+                  })
+            }
+          })
+          .catch(() => {
+            payingDialogVisible.value = false // 隐藏支付中对话框
+
+            feedback.confirm('支付失败,请重试').then(() => {
+                data.canScan = true
+                scanDialogVisible.value = true
+                // 添加键盘事件监听
+                document.addEventListener('keydown', handleScanInput)
+            })
+          })
+        scanCode.value = ''
+    } else {
+        scanCode.value += event.key
+    }
+}
+
+// 定义查询支付状态的函数
+const queryPayStatusWithRetry = (data): Promise<boolean> => {
+    const intervals = [3000, 5000, 10000]
+    let currentIndex = 0
+    payingDialogVisible.value = true
+
+    const tryQuery = () => {
+        return new Promise<boolean>((resolve) => {
+            setTimeout(() => {
+                queryPayStatus({ orderId: data.orderId,sn: data.sn })
+                    .then((result) => {
+                        if (result.result_code == '200' && result.biz_response.data.order_status == 'SUCCESS') {
+                            resolve(true)
+                        } else if (currentIndex < intervals.length - 1) {
+                            currentIndex++
+                            tryQuery().then(resolve)
+                        } else {
+                            resolve(false)
+                        }
+                    })
+                    .catch(() => {
+                        if (currentIndex < intervals.length - 1) {
+                            currentIndex++
+                            tryQuery().then(resolve)
+                        } else {
+                            resolve(false)
+                        }
+                    })
+            }, intervals[currentIndex])
+        })
+    }
+
+    return tryQuery().then((success) => {
+        payingDialogVisible.value = false
+        if (!success) {
+            return cancelOrder({ orderId: data.orderId,sn: data.sn })
+                .then(() => {
+                    feedback.notifyWarning('支付超时,已自动撤销本次支付')
+                    return false
+                })
+                .catch((error) => {
+                    console.error('撤单失败:', error)
+                    feedback.notifyError('支付失败,请重试')
+                    return false
+                })
+        }
+        return success
+    })
+}
+
 const checkout = () => {
     refresh()
     //结账
-    console.warn("***结账***",currentDesk)
-    if(currentDesk && !currentDesk.amount){
+    console.warn('***结账***', currentDesk)
+    if (currentDesk && !currentDesk.amount) {
         feedback.notify('当前桌未出单,无法结账')
         return false
     }
-    feedback.confirm('结账金额为' + currentDesk.amount + ',确定要结账吗?').then(() => {
-        orderCheckout({ did: currentDesk.id }).then(() => {
-            feedback.notifySuccess('成功结账' + currentDesk.amount + '元')
-            dialogVisible.value = false
-            init()
+    orderCheckout({ did: currentDesk.id }).then((res) => {
+        console.log('结账', res)
+        currentDesk.oid = res.id
+        feedback.confirm(currentDesk.name + ' 结账金额为' + currentDesk.amount + ',确定要结账吗?').then(() => {
+            data.canScan = true
+            scanDialogVisible.value = true
+            // 添加键盘事件监听
+            document.addEventListener('keydown', handleScanInput)
         })
     })
 }
+
+// 在组件卸载时移除事件监听
+onUnmounted(() => {
+    document.removeEventListener('keydown', handleScanInput)
+})
 const tabChange = (name: any) => {
     if (name != 'all') {
         deskList.value = deskListAll.filter((ele: any) => {
@@ -167,11 +335,11 @@ const tabChange = (name: any) => {
     }
 }
 const init = async () => {
-    let _list: any[] = [];
+    let _list: any[] = []
     await orderDeskList().then((res: any) => {
         // deskList.value = res
         deskListAll = res
-        _list = res;
+        _list = res
         getOrdersCurrent().then((res) => {
             deskList.value = _list.map((item) => {
                 res.forEach((element: any) => {
@@ -208,3 +376,15 @@ onMounted(() => {
     init()
 })
 </script>
+<style scoped>
+.scan-dialog ::v-deep(.el-dialog__header) {
+    margin-right: 0;
+    padding: 20px;
+    text-align: center;
+}
+
+.scan-dialog ::v-deep(.el-dialog__title) {
+    font-size: 16px;
+    font-weight: 500;
+}
+</style>

+ 11 - 5
src/views/orders/list.vue

@@ -15,6 +15,7 @@
                         <el-option label="待下单" value="0" />
                         <el-option label="待结帐" value="1" />
                         <el-option label="已完成" value="2" />
+                        <el-option label="已退款" value="4" />
                     </el-select>
                 </el-form-item>
                 <el-form-item label="创建时间" class="w-[280px]">
@@ -94,8 +95,10 @@
                 <el-table-column label="支付金额" min-width="160" prop="amount">
                     <template #default="{ row }">
                         <div>
-                            <div :style="row.status > 1 ? 'text-decoration: line-through;': ''" v-if="row.status > 0">订单金额:¥{{row.amount}}</div>
-                            <div style="color: #f01414;" v-if="row.status > 1">实付金额:¥{{row.payAmount || row.amount}}</div>
+                            <div :style="row.status > 1 && row.status != 6 ? 'text-decoration: line-through;': ''" v-if="row.status > 1 && row.status != 6">订单金额:¥{{row.amount}}</div>
+                            <div style="color: #f01414;" v-if="row.status >= 2 && row.status != 6">
+                              实付:¥{{row.payAmount || row.amount}}   {{row.status==4 ? '退款:¥' + row.refundAmount : ''}}
+                            </div>
                             <div v-if="row.ticketNo" class="refund-info">
                                 <div style="font-size: 12px;">抵扣券券号:{{ row.ticketNo }}</div>
                                 <div style="font-size: 12px;">抵扣券金额:¥{{ row.ticketAmount }}</div>
@@ -130,7 +133,7 @@
                 <el-table-column label="操作" width="200" fixed="right">
                     <template #default="{ row }">
                         <el-button type="primary" link @click="showDetail(row)">查看已点菜品</el-button>
-                        <el-button v-if="row.type == 1 && row.status=='2' && !row.refundAmount" type="danger" link @click="refund(row)">退款</el-button>
+                        <el-button v-if="row.status=='2' && !row.refundAmount" type="danger" link @click="refund(row)">退款</el-button>
                     </template>
                 </el-table-column>
             </el-table>
@@ -155,7 +158,7 @@
             <template #footer>
                 <span class="dialog-footer">
                     <el-button @click="refundDialogVisible = false">取 消</el-button>
-                    <el-button type="primary" @click="confirmRefund">确 定</el-button>
+                    <el-button type="primary" :loading="refundLoading" @click="confirmRefund">确 定</el-button>
                 </span>
             </template>
         </el-dialog>
@@ -215,6 +218,8 @@
         amount: number;
         status: number; id: any;
     };
+    // 添加loading状态变量
+    const refundLoading = ref(false)
     // 修改refund函数
     const refund = async (row: any) => {
         refundDialogVisible.value = true
@@ -230,6 +235,7 @@
             if(refundAmount.value > (refundOrder.payAmount || refundOrder.amount)){
                 return feedback.msgError('退款金额不能大于订单实付金额')
             }
+            refundLoading.value = true
             const res = await refundReq({ orderId: refundOrder.id, payAmount: refundAmount.value })
             if (res) {
                 feedback.msgSuccess('退款成功')
@@ -244,8 +250,8 @@
             }
         } catch (error) {
             console.error('退款失败:', error)
-            feedback.msgError('退款失败')
         } finally {
+            refundLoading.value = false
             refundDialogVisible.value = false
         }
     }