优化退菜原因以及无台桌退菜不刷新历史订单的问题

This commit is contained in:
gyq
2026-06-17 18:22:31 +08:00
parent 75be7c0d53
commit 54667097b3
9 changed files with 300 additions and 21 deletions

View File

@@ -1,14 +1,14 @@
# 本地环境
ENV = development
# 测试ws
# VITE_API_WSS = 'wss://sockets.sxczgkj.com/wss'
# 正式ws
# VITE_API_WSS = 'wss://czgeatws.sxczgkj.com/wss'
# 本地ws
VITE_API_WSS = 'ws://192.168.1.42:2348'
# VITE_API_WSS = 'ws://192.168.1.42:2348'
# 线上本地映射测试ws
VITE_API_WSS = 'ws://frp.sxczgkj.com/wss'
# 正式 php
VITE_API_PHP_URL = 'https://newblockwlx.sxczgkj.cn/index.php/api'
@@ -17,7 +17,7 @@ VITE_API_PHP_URL = 'https://newblockwlx.sxczgkj.cn/index.php/api'
# VITE_API_KP_URL = 'http://192.168.1.13:8888/api'
# 正式 php 开票
# VITE_API_KP_URL = 'https://invoice.sxczgkj.cn/api'
VITE_API_KP_URL = 'https://invoice.sxczgkj.cn/api'
# 线上测试
# VITE_API_URL = 'https://tapi.cashier.sxczgkj.cn'
@@ -26,4 +26,7 @@ VITE_API_PHP_URL = 'https://newblockwlx.sxczgkj.cn/index.php/api'
# VITE_API_URL = 'https://cashier.sxczgkj.com'
# 本地调试连接
VITE_API_URL = 'http://192.168.1.42/'
# VITE_API_URL = 'http://192.168.1.42/'
# 线上本地映射测试
VITE_API_URL = 'https://frp.sxczgkj.com'

View File

@@ -2,7 +2,10 @@
ENV = test
# 测试ws
VITE_API_WSS = 'ws://192.168.1.42:2348'
# VITE_API_WSS = 'ws://192.168.1.42:2348'
# 线上本地映射测试ws
VITE_API_WSS = 'ws://frp.sxczgkj.com/wss'
# 测试ws
# VITE_API_WSS = 'wss://sockets.sxczgkj.com/wss'
@@ -26,4 +29,7 @@ VITE_API_KP_URL = 'https://invoice.sxczgkj.cn/api'
# VITE_API_URL = 'https://cashier.sxczgkj.com/'
# 本地调试连接
VITE_API_URL = 'http://192.168.1.42/'
# VITE_API_URL = 'http://192.168.1.42/'
# 线上本地映射测试
VITE_API_URL = 'https://frp.sxczgkj.com'

View File

@@ -1,7 +1,7 @@
{
"name": "vite-electron",
"private": true,
"version": "2.0.31",
"version": "2.0.32",
"main": "dist-electron/main.js",
"scripts": {
"dev": "chcp 65001 && vite",

View File

@@ -4,7 +4,7 @@
<div class="title_wrap">请确认当前菜品是否已上菜</div>
<div class="list_wrap">
<div class="item" v-for="(item, index) in list" :key="index">
<span>{{ item.name }}</span>
<span>{{ item.name || item.product_name }}</span>
<span>x{{ item.num }}</span>
</div>
</div>

View File

@@ -59,8 +59,9 @@
</template>
</template>
</div>
<div class="remark_wrap" @click="showRemark(props.item)">
备注<span class="t">{{ props.item.remark }}</span><el-icon class="icon" v-if="props.type == 'cart'">
<div class="remark_wrap" v-if="props.item.id">
备注<span class="t">{{ props.item.remark }}</span>
<el-icon class="icon" v-if="props.type == 'cart'" @click="showRemark(props.item)">
<EditPen />
</el-icon>
</div>

View File

@@ -135,13 +135,19 @@
</el-icon>
<el-text class="t">免厨</el-text>
</div>
<div class="item"
<!-- <div class="item"
:class="{ disabled: goodsStore.cartOrderItem.returnNum >= goodsStore.cartOrderItem.number }"
@click="returnOrderItemHandle">
<el-icon class="icon">
<Delete />
</el-icon>
<el-text class="t">退菜</el-text>
</div> -->
<div class="item" @click="returnOrderItemHandle">
<el-icon class="icon">
<Delete />
</el-icon>
<el-text class="t">退菜</el-text>
</div>
<div class="item" @click="pendingOrderHandle">
<el-icon class="icon">
@@ -227,6 +233,8 @@
</el-dialog>
<!-- 合并/转桌 -->
<tableMerging ref="tableMergingRef" @success="" />
<!-- 批量退菜 -->
<cartOperationReturn ref="cartOperationReturnRef" />
<!-- 退菜数量 -->
<el-dialog
:title="`退菜:${goodsStore.cartOrderItem.product_name} x ${goodsStore.cartOrderItem.number - goodsStore.cartOrderItem.returnNum}`"
@@ -266,6 +274,7 @@ import { useSocket } from '@/store/socket.js'
import { usePrint } from '@/store/print.js'
import { useUser } from '@/store/user.js'
import refundConsModal from '@/components/refundConsModal.vue'
import cartOperationReturn from './cartOperationReturn.vue'
const refundConsModalRef = ref(null)
@@ -274,6 +283,7 @@ const socket = useSocket()
const printStore = usePrint()
const store = useUser()
const tableMergingRef = ref(null)
const cartOperationReturnRef = ref(null)
const props = defineProps({
item: {
@@ -307,12 +317,13 @@ function pendingOrderHandle() {
// 退菜
async function returnOrderItemHandle() {
if (goodsStore.cartOrderItem.returnNum >= goodsStore.cartOrderItem.number) return
if (goodsStore.cartOrderItem.number == 1) {
returnOrderItemAjax()
} else {
showReturnForm.value = true
}
cartOperationReturnRef.value.open()
// if (goodsStore.cartOrderItem.returnNum >= goodsStore.cartOrderItem.number) return
// if (goodsStore.cartOrderItem.number == 1) {
// returnOrderItemAjax()
// } else {
// showReturnForm.value = true
// }
}
// 提交自定义数量退菜
@@ -335,6 +346,7 @@ function refundConsModalSuccess(e) {
refundNext()
}
// 提交最终退款请求
async function refundNext() {
try {
let data = {

View File

@@ -0,0 +1,257 @@
<!-- 退菜弹窗 -->
<template>
<div>
<el-dialog title="批量退菜" v-model="visable" width="700px" top="3vh" @closed="resetDialog">
<div class="return_container">
<div class="title">退菜原因统一设置<el-text type="danger">*</el-text></div>
<div class="remark_btns">
<el-button plain :type="item.active ? 'primary' : 'default'" v-for="item in remarks"
:key="item.label" @click="item.active = !item.active">
{{ item.label }}
</el-button>
</div>
<div class="remark_input">
<el-input placeholder="请输入自定义备注(选填)" v-model="remarkValue" clearable />
</div>
<div class="title">请选择要退的菜品</div>
<div class="table">
<el-table ref="tableRef" row-key="id" :data="tableData" border stripe height="280"
@selection-change="handleSelectionChange">
<el-table-column type="selection"></el-table-column>
<el-table-column prop="name" label="菜品信息">
<template #default="{ row }">
<div>{{ row.productName }}</div>
<div class="tag_wrap" v-if="row.sku_name">
<el-text type="info" size="small">规格</el-text>
<el-text type="info" size="small" v-for="item in row.sku_name.split(',')">
{{ item }}
</el-text>
</div>
<div class="tag_wrap" v-if="row.remark">
<el-text type="info" size="small">备注</el-text>
<el-text type="info" size="small">{{ row.remark }}</el-text>
</div>
</template>
</el-table-column>
<el-table-column prop="quantity" label="退菜数量">
<template #default="{ row }">
<el-input-number v-model="row.customReturnNum" :min="1"
:max="row.number - row.returnNum" style="width: 180px" :step="1" step-strictly>
</el-input-number>
</template>
</el-table-column>
</el-table>
</div>
<div class="footer_wrap">
<div class="left">退菜数量{{ _.sumBy(selectData, 'customReturnNum') || 0 }}</div>
<div class="right">
<el-button plain @click="visable = false"> </el-button>
<el-button type="primary" :disabled="selectData.length == 0" :loading="loading"
@click="confirmReturn">
</el-button>
</div>
</div>
</div>
</el-dialog>
<!-- 退款推库存的操作弹窗 -->
<refundConsModal ref="refundConsModalRef" :list="refundList" @success="refundConsModalSuccess" />
</div>
</template>
<script setup>
import _ from 'lodash'
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { useUser } from '@/store/user.js'
import { useGoods } from '@/store/goods.js'
import { refundOrder } from '@/api/order.js'
import refundConsModal from '@/components/refundConsModal.vue'
const goodsStore = useGoods()
const remarks = ref([
{
label: '不想要了',
active: false
},
{
label: '食材不足',
active: false
},
{
label: '等待过长',
active: false
},
{
label: '点重复了',
active: false
},
{
label: '口味问题',
active: false
}
])
const remarkValue = ref('')
const visable = ref(false)
const tableData = ref([])
const tableRef = ref(null)
const refundConsModalRef = ref(null)
const refundList = ref([])
const refundStock = ref('')
const store = useUser()
const selectData = ref([])
function handleSelectionChange(val) {
selectData.value = val
console.log('selectData', selectData.value)
}
function confirmReturn() {
// 获取表格选中的数据
const selectedData = tableRef.value.getSelectionRows()
if (selectedData.length == 0) {
ElMessage.warning('请至少选择一项菜品退菜')
return
}
console.log('selectedData', selectedData)
// 判断是否有需要推库存的菜品
refundList.value = selectedData.filter(item => item.refundMode == 3)
console.log('选中的菜品', refundList.value)
if (refundList.value.length > 0) {
// 打开退款推库存的操作弹窗
refundConsModalRef.value.show()
} else {
// 直接提交退菜请求
refundNext()
}
}
// 退款推库存的操作
function refundConsModalSuccess(e) {
refundStock.value = e
refundNext()
}
// 提交最终退款请求
const loading = ref(false)
async function refundNext() {
try {
const selectedData = tableRef.value.getSelectionRows()
const selectRemarks = remarks.value.filter(item => item.active).map(item => item.label)
if (selectRemarks.length == 0) {
ElMessage.warning('请选择退菜原因')
return
}
let data = {
orderId: goodsStore.orderListInfo.id,
refundAmount: 0,
modify: 0,
cash: false,
refundReason: `${selectRemarks.join('')}${remarkValue.value}`,
refundDetails: selectedData.map(item => ({
id: item.id,
returnAmount: item.lowPrice,
num: item.customReturnNum
})),
operator: store.userInfo.name || store.shopInfo.shopName,
print: true,
refundStock: refundStock.value, // 是否推库存 1退菜图库存 2仅退菜不退库存
}
loading.value = true
await refundOrder(data)
await goodsStore.historyOrderAjax(goodsStore.orderListInfo.tableCode)
ElMessage.success('退菜成功')
goodsStore.calcCartInfo()
// 关闭退菜弹窗
setTimeout(() => {
visable.value = false
}, 300);
} catch (error) {
console.log(error);
} finally {
setTimeout(() => {
loading.value = false
}, 300);
}
}
// 重置弹窗数据
function resetDialog() {
remarkValue.value = ''
selectData.value = []
refundList.value = []
refundStock.value = ''
remarks.value.forEach(item => {
item.active = false
})
}
function open() {
visable.value = true
tableData.value = _.flatMap(goodsStore.orderList, 'goods').map(item => ({
...item,
customReturnNum: item.number - item.returnNum
})).filter(item => item.number - item.returnNum > 0)
tableData.value.forEach(item => {
goodsStore.originGoodsList.forEach(val => {
if (item.productId == val.id) {
if (store.shopInfo.refundMode == 1) {
// 跟随分类退款模式
goodsStore.categoryList.forEach(v => {
if (val.categoryId == v.id) {
item.refundMode = v.refundMode
}
})
} else {
// 跟随商品退款模式及
item.refundMode = val.refundMode
}
}
})
})
console.log('cartOperationReturn组件打开了', tableData.value)
setTimeout(() => {
let row = tableData.value.find(item => item.id === goodsStore.cartOrderItem.id)
if (row && row.id) {
tableRef.value.toggleRowSelection(row, true)
}
}, 100);
}
defineExpose({
open
})
</script>
<style lang="scss" scoped>
.return_container {
.title {
font-size: 16px;
margin-bottom: 14px;
}
.remark_btns,
.remark_input {
margin-bottom: 14px;
}
.footer_wrap {
padding-top: 25px;
display: flex;
align-items: center;
justify-content: space-between;
.left {
font-size: 16px;
}
}
}
</style>

View File

@@ -1061,7 +1061,7 @@ onMounted(() => {
.shop_list {
// max-height: calc(100vh - 40px - 80px - 40px);
height: calc(100vh - 40px - 80px - 28px);
height: calc(100vh - 40px - 80px - 40px);
// overflow-y: auto;
// display: flex;
// flex-wrap: wrap;

View File

@@ -685,7 +685,7 @@ function showTableMerging() {
.shop_list {
flex: 1;
height: calc(100vh - 40px - 60px - 90px);
height: calc(100vh - 40px - 60px - 102px);
overflow-y: auto;
border-right: 1px solid #ececec;