优化页面小时,优化用时显示
This commit is contained in:
@@ -11,8 +11,6 @@ import { useSocketStore } from '@/stores/socket';
|
|||||||
const pinia = createPinia()
|
const pinia = createPinia()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log('WS URL:', import.meta.env.VITE_WS_URL);
|
|
||||||
|
|
||||||
// 重启或刷新防止ws丢失
|
// 重启或刷新防止ws丢失
|
||||||
const socketStore = useSocketStore(pinia)
|
const socketStore = useSocketStore(pinia)
|
||||||
socketStore.restoreFromStorage()
|
socketStore.restoreFromStorage()
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export const useUserStore = defineStore('user', {
|
|||||||
state: () => ({
|
state: () => ({
|
||||||
token: '',
|
token: '',
|
||||||
shopInfo: '',
|
shopInfo: '',
|
||||||
shopStaff: ''
|
shopStaff: '',
|
||||||
|
account: ''
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
async login(params) {
|
async login(params) {
|
||||||
@@ -19,6 +20,8 @@ export const useUserStore = defineStore('user', {
|
|||||||
// 登录员工
|
// 登录员工
|
||||||
if (res.loginType == 1) this.shopStaff = res.shopStaff
|
if (res.loginType == 1) this.shopStaff = res.shopStaff
|
||||||
// async 函数直接返回值即可 resolve
|
// async 函数直接返回值即可 resolve
|
||||||
|
|
||||||
|
this.account = params.username
|
||||||
return res
|
return res
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error('先下单模式下不可登录,请联系管理员')
|
ElMessage.error('先下单模式下不可登录,请联系管理员')
|
||||||
@@ -68,7 +71,7 @@ export const useUserStore = defineStore('user', {
|
|||||||
{
|
{
|
||||||
key: 'kitchen-user',
|
key: 'kitchen-user',
|
||||||
storage: localStorage,
|
storage: localStorage,
|
||||||
paths: ['token', 'shopInfo', 'shopStaff'] // 持久化指定状态
|
paths: ['token', 'shopInfo', 'shopStaff', 'account'] // 持久化指定状态
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算当前时间与传入时间的时间差,并按规则格式化
|
* 计算基准时间与传入目标时间的时间差,并按规则格式化
|
||||||
* @param {string|number|Date} targetTime - 传入的目标时间(支持字符串、时间戳、Date对象)
|
* @param {string|number|Date} targetTime - 传入的目标时间(支持字符串、时间戳、Date对象)
|
||||||
* @returns {string} 格式化后的时间差(≤1小时:MM:ss;>1小时:HH:MM:ss)| 错误提示
|
* @param {string|number|Date} [currentTime=dayjs()] - 基准时间(默认当前时间),支持字符串、时间戳、Date对象
|
||||||
|
* @returns {string} 格式化后的时间差(≤1小时:MM:ss;>1小时:HH:MM:ss)| 无效时间返回 "00:00"
|
||||||
*/
|
*/
|
||||||
export const formatTimeDiff = (targetTime) => {
|
export const formatTimeDiff = (targetTime, currentTime = dayjs()) => {
|
||||||
// 1. 校验传入时间的有效性
|
// 1. 校验目标时间和基准时间的有效性
|
||||||
const target = dayjs(targetTime);
|
const target = dayjs(targetTime);
|
||||||
if (!target.isValid()) {
|
const baseTime = dayjs(currentTime); // 解析基准时间(默认当前时间)
|
||||||
return '00:00'; // 无效时间返回提示
|
|
||||||
|
// 任一时间无效,返回 "00:00"
|
||||||
|
if (!target.isValid() || !baseTime.isValid()) {
|
||||||
|
return '00:00';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 计算当前时间与目标时间的**秒级总差值**(当前时间 - 传入时间)
|
// 2. 计算基准时间与目标时间的**秒级总差值**(基准时间 - 目标时间)
|
||||||
const diffSeconds = dayjs().diff(target, 'second');
|
const diffSeconds = baseTime.diff(target, 'second');
|
||||||
// 处理差值为负数的情况(传入时间在当前时间之后,差值为负)
|
// 处理差值为负数的情况(目标时间在基准时间之后,取绝对值)
|
||||||
const absDiffSeconds = Math.abs(diffSeconds);
|
const absDiffSeconds = Math.abs(diffSeconds);
|
||||||
|
|
||||||
// 3. 按秒数分解为 小时、分钟、秒
|
// 3. 按秒数分解为 小时、分钟、秒
|
||||||
@@ -36,68 +40,104 @@ export const formatTimeDiff = (targetTime) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断时分秒字符串是否大于指定分钟数
|
* 判断时间字符串是否大于指定分钟数(兼容分秒格式和时分秒格式)
|
||||||
* @param {string} timeStr - 时分秒字符串,如 "26:30:40"
|
* @param {string} timeStr - 时间字符串,支持两种格式:
|
||||||
|
* 1. 分秒格式:"MM:SS"(如 "12:34")
|
||||||
|
* 2. 时分秒格式:"HH:MM:SS"(如 "07:23:45")
|
||||||
* @param {number} [thresholdMinutes=15] - 分钟阈值,默认15分钟
|
* @param {number} [thresholdMinutes=15] - 分钟阈值,默认15分钟
|
||||||
* @returns {boolean} 大于阈值返回true,否则false(格式错误返回false)
|
* @returns {boolean} 大于阈值返回true,否则false(格式错误返回false)
|
||||||
*/
|
*/
|
||||||
export const isMoreThanSpecifiedMinutes = (timeStr, thresholdMinutes = 15) => {
|
export const isMoreThanSpecifiedMinutes = (timeStr, thresholdMinutes = 15) => {
|
||||||
// 1. 按冒号分割时分秒并转换为数字
|
console.log('isMoreThanSpecifiedMinutes===', timeStr);
|
||||||
const [hours, minutes, seconds] = timeStr.split(':').map(Number);
|
|
||||||
|
|
||||||
// 2. 校验时分秒格式是否合法
|
// 1. 按冒号分割时间字符串并转换为数字数组
|
||||||
|
const timeParts = timeStr.split(':').map(Number);
|
||||||
|
|
||||||
|
// 2. 校验格式合法性(仅允许 2 段【分秒】或 3 段【时分秒】,且所有部分为有效数字)
|
||||||
if (
|
if (
|
||||||
isNaN(hours) ||
|
!([2, 3].includes(timeParts.length)) || // 仅支持 2 或 3 段
|
||||||
isNaN(minutes) ||
|
timeParts.some(part => isNaN(part)) || // 存在非数字部分
|
||||||
isNaN(seconds) ||
|
timeParts.some(part => part < 0) // 存在负数
|
||||||
hours < 0 ||
|
|
||||||
minutes < 0 || minutes >= 60 ||
|
|
||||||
seconds < 0 || seconds >= 60
|
|
||||||
) {
|
) {
|
||||||
console.error('时分秒格式错误,示例:"26:30:40"');
|
console.error('时间格式错误,支持:分秒格式(如 "12:34")或时分秒格式(如 "07:23:45")');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 转换为总秒数:小时*3600 + 分钟*60 + 秒
|
// 3. 根据分割长度补全小时位,统一转换为 [小时, 分钟, 秒]
|
||||||
|
let hours = 0, minutes = 0, seconds = 0;
|
||||||
|
if (timeParts.length === 3) {
|
||||||
|
// 时分秒格式:HH:MM:SS
|
||||||
|
[hours, minutes, seconds] = timeParts;
|
||||||
|
// 额外校验:分钟和秒不能超过 59
|
||||||
|
if (minutes >= 60 || seconds >= 60) {
|
||||||
|
console.error('时分秒格式错误:分钟和秒必须小于 60');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (timeParts.length === 2) {
|
||||||
|
// 分秒格式:MM:SS → 补全小时为 0
|
||||||
|
[minutes, seconds] = timeParts;
|
||||||
|
// 额外校验:分钟和秒不能超过 59
|
||||||
|
if (minutes >= 60 || seconds >= 60) {
|
||||||
|
console.error('分秒格式错误:分钟和秒必须小于 60');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 转换为总秒数:小时*3600 + 分钟*60 + 秒
|
||||||
const totalSeconds = hours * 3600 + minutes * 60 + seconds;
|
const totalSeconds = hours * 3600 + minutes * 60 + seconds;
|
||||||
|
|
||||||
// 4. 将分钟阈值转换为总秒数,进行比较
|
// 5. 将分钟阈值转换为总秒数,进行比较
|
||||||
const thresholdSeconds = thresholdMinutes * 60;
|
const thresholdSeconds = thresholdMinutes * 60;
|
||||||
|
|
||||||
return totalSeconds > thresholdSeconds;
|
return totalSeconds > thresholdSeconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算时分秒字符串超出指定分钟阈值的时长(返回HH:MM:SS格式)
|
* 计算时间字符串超出指定分钟阈值的时长(返回HH:MM:SS格式,兼容分秒/时分秒输入)
|
||||||
* @param {string} timeStr - 时分秒字符串,如 "26:30:40"
|
* @param {string} timeStr - 时间字符串,支持两种格式:
|
||||||
|
* 1. 分秒格式:"MM:SS"(如 "12:34")
|
||||||
|
* 2. 时分秒格式:"HH:MM:SS"(如 "07:23:45")
|
||||||
* @param {number} [thresholdMinutes=15] - 分钟阈值,默认15分钟
|
* @param {number} [thresholdMinutes=15] - 分钟阈值,默认15分钟
|
||||||
* @returns {string} 超时时长(HH:MM:SS),未超时返回"00:00:00",格式错误返回"格式错误"
|
* @returns {string} 超时时长(HH:MM:SS),未超时返回"00:00:00",格式错误返回"格式错误"
|
||||||
*/
|
*/
|
||||||
export const calculateTimeoutDuration = (timeStr, thresholdMinutes = 15) => {
|
export const calculateTimeoutDuration = (timeStr, thresholdMinutes = 15) => {
|
||||||
// 1. 按冒号分割时分秒并转换为数字
|
// 新增:清理输入字符串(去除前后空格、替换中文冒号为英文冒号)
|
||||||
const [hours, minutes, seconds] = timeStr.split(':').map(Number);
|
const cleanedTimeStr = timeStr.trim().replace(/:/g, ':');
|
||||||
|
// 按英文冒号分割并转换为数字数组
|
||||||
|
const timeParts = cleanedTimeStr.split(':').map(Number);
|
||||||
|
|
||||||
// 2. 校验时分秒格式合法性
|
// 校验格式合法性(仅支持 2 段【分秒】或 3 段【时分秒】)
|
||||||
if (
|
if (
|
||||||
isNaN(hours) ||
|
!([2, 3].includes(timeParts.length)) || // 仅允许 2/3 段分割结果
|
||||||
isNaN(minutes) ||
|
timeParts.some(part => isNaN(part)) || // 存在非数字部分
|
||||||
isNaN(seconds) ||
|
timeParts.some(part => part < 0) // 存在负数
|
||||||
hours < 0 ||
|
|
||||||
minutes < 0 || minutes >= 60 ||
|
|
||||||
seconds < 0 || seconds >= 60
|
|
||||||
) {
|
) {
|
||||||
console.error('时分秒格式错误,示例:"26:30:40"');
|
console.error('时间格式错误,支持:分秒格式(如 "12:34")或时分秒格式(如 "07:23:45")');
|
||||||
return '格式错误';
|
return '格式错误';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 转换为总秒数
|
// 根据分割长度补全小时位,统一转换为 [小时, 分钟, 秒]
|
||||||
|
let hours = 0, minutes = 0, seconds = 0;
|
||||||
|
if (timeParts.length === 3) {
|
||||||
|
[hours, minutes, seconds] = timeParts;
|
||||||
|
if (minutes >= 60 || seconds >= 60) {
|
||||||
|
console.error('时分秒格式错误:分钟和秒必须小于 60');
|
||||||
|
return '格式错误';
|
||||||
|
}
|
||||||
|
} else if (timeParts.length === 2) {
|
||||||
|
[minutes, seconds] = timeParts;
|
||||||
|
if (minutes >= 60 || seconds >= 60) {
|
||||||
|
console.error('分秒格式错误:分钟和秒必须小于 60');
|
||||||
|
return '格式错误';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算总秒数、阈值秒数、超时秒数
|
||||||
const totalSeconds = hours * 3600 + minutes * 60 + seconds;
|
const totalSeconds = hours * 3600 + minutes * 60 + seconds;
|
||||||
// 4. 计算阈值对应的总秒数
|
|
||||||
const thresholdSeconds = thresholdMinutes * 60;
|
const thresholdSeconds = thresholdMinutes * 60;
|
||||||
// 5. 计算超时秒数(差值≤0则未超时)
|
|
||||||
const timeoutSeconds = Math.max(totalSeconds - thresholdSeconds, 0);
|
const timeoutSeconds = Math.max(totalSeconds - thresholdSeconds, 0);
|
||||||
|
|
||||||
// 6. 将超时秒数转换回HH:MM:SS格式(补零处理)
|
// 格式化为 HH:MM:SS
|
||||||
const padZero = (num) => num.toString().padStart(2, '0');
|
const padZero = (num) => num.toString().padStart(2, '0');
|
||||||
const timeoutHours = padZero(Math.floor(timeoutSeconds / 3600));
|
const timeoutHours = padZero(Math.floor(timeoutSeconds / 3600));
|
||||||
const timeoutMins = padZero(Math.floor((timeoutSeconds % 3600) / 60));
|
const timeoutMins = padZero(Math.floor((timeoutSeconds % 3600) / 60));
|
||||||
|
|||||||
@@ -40,15 +40,15 @@ service.interceptors.request.use(
|
|||||||
// 响应拦截器
|
// 响应拦截器
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
|
const userStore = useUserStore()
|
||||||
// 对响应数据做点什么
|
// 对响应数据做点什么
|
||||||
if (+response.status === 200) {
|
if (+response.status === 200) {
|
||||||
if (+response.data.code == 200) {
|
if (+response.data.code == 200) {
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
} else if (+response.data.code == 501) {
|
} else if (+response.data.code == 501) {
|
||||||
useStorage.del("token");
|
userStore.shopInfo = ''
|
||||||
useStorage.del("userInfo");
|
userStore.token = ''
|
||||||
useStorage.del("shopInfo");
|
userStore.shopStaff = ''
|
||||||
useStorage.del("douyin");
|
|
||||||
ElMessage.error("登录已过期,请重新登录");
|
ElMessage.error("登录已过期,请重新登录");
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
return Promise.reject("登录已过期,请重新登录");
|
return Promise.reject("登录已过期,请重新登录");
|
||||||
|
|||||||
@@ -17,11 +17,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tab_wrap">
|
<div class="tab_wrap">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="item" v-for="(item, index) in checkTypeList" :key="index"
|
<div class="item" :class="{ active: checkType == item.value }" v-for="(item, index) in checkTypeList"
|
||||||
@click="queryForm.tableName = ''; checkTypeHandle(item)">
|
:key="index" @click="queryForm.tableName = ''; checkTypeHandle(item)">
|
||||||
<el-text :type="checkType == item.value ? 'primary' : ''">
|
<span>{{ item.label }}</span>
|
||||||
{{ item.label }}
|
|
||||||
</el-text>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right" @click="showScanTipsHandle">
|
<div class="right" @click="showScanTipsHandle">
|
||||||
@@ -62,10 +60,10 @@
|
|||||||
}})</el-button>
|
}})</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="people_wrap">
|
<!-- <div class="people_wrap">
|
||||||
<peopleIcon />
|
<peopleIcon />
|
||||||
<span>1人</span>
|
<span>1人</span>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-empty v-if="tableList.length <= 0"></el-empty>
|
<el-empty v-if="tableList.length <= 0"></el-empty>
|
||||||
@@ -74,21 +72,19 @@
|
|||||||
<div class="table_info_wrap">
|
<div class="table_info_wrap">
|
||||||
<el-button type="primary">{{ selectItem.tableName || '-' }} | {{ selectItem.areaName || '-'
|
<el-button type="primary">{{ selectItem.tableName || '-' }} | {{ selectItem.areaName || '-'
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
<el-text>待出菜({{ selectItem.pendingDishCount || '-' }})</el-text>
|
<el-text>待出菜({{ selectItem.pendingDishCount }})</el-text>
|
||||||
<el-text>员工名称:{{ selectItem.staffName || notStaff }}</el-text>
|
<el-text>员工名称:{{ selectItem.staffName || notStaff }}</el-text>
|
||||||
<el-text>下单时间:{{ selectItem.orderTime || '-' }}</el-text>
|
<el-text>下单时间:{{ selectItem.orderTime || '-' }}</el-text>
|
||||||
</div>
|
</div>
|
||||||
<div class="table_wrap">
|
<div class="table_wrap">
|
||||||
<el-table :data="tableData.list" border stripe>
|
<el-table :data="tableData.list" border stripe>
|
||||||
<el-table-column label="菜品名称" prop="productName"></el-table-column>
|
<el-table-column label="菜品名称" prop="productName">
|
||||||
<el-table-column label="用时" prop="startOrderTime">
|
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-text v-if="scope.row.subStatus == 'READY_TO_SERVE'">{{
|
{{ scope.row.productName }} * {{ scope.row.num }}
|
||||||
formatTimeDiff(scope.row.startOrderTime) }}</el-text>
|
|
||||||
<el-text v-if="scope.row.subStatus == 'TIMEOUT'">{{ scope.row.timeout_time }}</el-text>
|
|
||||||
<el-text v-if="scope.row.subStatus == 'SENT_OUT'">{{ scope.row.dishOutTime }}</el-text>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="用时" prop="time_taken"></el-table-column>
|
||||||
|
<el-table-column label="下单时间" prop="orderTime"></el-table-column>
|
||||||
<el-table-column label="状态" prop="subStatus" width="150">
|
<el-table-column label="状态" prop="subStatus" width="150">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-tag disable-transitions :type="statusFilter(scope.row.subStatus).type" size="large">
|
<el-tag disable-transitions :type="statusFilter(scope.row.subStatus).type" size="large">
|
||||||
@@ -120,15 +116,16 @@
|
|||||||
<div class="table_wrap">
|
<div class="table_wrap">
|
||||||
<div class="table" v-for="(item, index) in goodsTableData" :key="index">
|
<div class="table" v-for="(item, index) in goodsTableData" :key="index">
|
||||||
<div class="goods_table_title">
|
<div class="goods_table_title">
|
||||||
<el-text size="large">{{ item.productName }}</el-text>
|
<span>{{ item.productName }} 待出菜({{ item.total
|
||||||
|
}})</span>
|
||||||
</div>
|
</div>
|
||||||
<el-table :data="item.foodItems" border stripe>
|
<el-table :data="item.foodItems" border stripe>
|
||||||
<el-table-column label="下单台桌" prop="areaName"></el-table-column>
|
<el-table-column label="下单台桌" prop="areaName">
|
||||||
<el-table-column label="用时" prop="startOrderTime">
|
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-text>{{ formatTimeDiff(scope.row.startOrderTime) }}</el-text>
|
{{ scope.row.tableName }} | {{ scope.row.areaName }} * {{ scope.row.num }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="用时" prop="time_taken"></el-table-column>
|
||||||
<el-table-column label="状态" prop="subStatus" width="150">
|
<el-table-column label="状态" prop="subStatus" width="150">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-tag disable-transitions :type="statusFilter(scope.row.subStatus).type" size="large">
|
<el-tag disable-transitions :type="statusFilter(scope.row.subStatus).type" size="large">
|
||||||
@@ -158,6 +155,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import _ from 'lodash'
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useUserStore } from '@/stores/user';
|
import { useUserStore } from '@/stores/user';
|
||||||
import scanIcon from '@/components/icons/scanIcon.vue';
|
import scanIcon from '@/components/icons/scanIcon.vue';
|
||||||
@@ -223,7 +221,7 @@ function inputClear() {
|
|||||||
|
|
||||||
// 搜索
|
// 搜索
|
||||||
function searchHandle() {
|
function searchHandle() {
|
||||||
goodsListActive.value = -1
|
// goodsListActive.value = -1
|
||||||
checkTypeHandle({ value: checkType.value })
|
checkTypeHandle({ value: checkType.value })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,7 +233,9 @@ async function checkTypeHandle(item) {
|
|||||||
} else {
|
} else {
|
||||||
await getKitchenFoodAjax()
|
await getKitchenFoodAjax()
|
||||||
}
|
}
|
||||||
startUpdate()
|
setTimeout(() => {
|
||||||
|
startUpdate()
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
const categorys = ref([])
|
const categorys = ref([])
|
||||||
@@ -264,7 +264,9 @@ async function getKitchenTableAjax() {
|
|||||||
})
|
})
|
||||||
tableList.value = res
|
tableList.value = res
|
||||||
if (res.length > 0) {
|
if (res.length > 0) {
|
||||||
selectItem.value = res[0]
|
if (!selectItem.value.id) {
|
||||||
|
selectItem.value = res[0]
|
||||||
|
}
|
||||||
getKitchenTableFoodsAjax()
|
getKitchenTableFoodsAjax()
|
||||||
} else {
|
} else {
|
||||||
selectItem.value = {}
|
selectItem.value = {}
|
||||||
@@ -294,7 +296,7 @@ async function getKitchenTableFoodsAjax() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
res.forEach(item => {
|
res.forEach(item => {
|
||||||
item.timeout_time = ''
|
item.time_taken = timeTakenUtils(item)
|
||||||
})
|
})
|
||||||
|
|
||||||
tableData.list = res
|
tableData.list = res
|
||||||
@@ -313,6 +315,15 @@ async function getKitchenFoodAjax() {
|
|||||||
productName: queryForm.tableName,
|
productName: queryForm.tableName,
|
||||||
categoryId: categoryId.value
|
categoryId: categoryId.value
|
||||||
})
|
})
|
||||||
|
res.forEach(val => {
|
||||||
|
val.total = 0
|
||||||
|
val.foodItems.forEach(item => {
|
||||||
|
item.time_taken = timeTakenUtils(item)
|
||||||
|
if (item.subStatus == 'READY_TO_SERVE') {
|
||||||
|
val.total += +item.num
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
goodsList.value = res
|
goodsList.value = res
|
||||||
goodsTableData.value = goodsList.value
|
goodsTableData.value = goodsList.value
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -332,8 +343,8 @@ function changeGoodsIndexHandle(item, index) {
|
|||||||
getKitchenFoodAjax()
|
getKitchenFoodAjax()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 扫码出菜
|
// 扫码出菜 1秒内最多调用1次,防止重复提交
|
||||||
function handleScan(code) {
|
const handleScan = _.throttle(async function (code) {
|
||||||
console.log('handleScan', code);
|
console.log('handleScan', code);
|
||||||
try {
|
try {
|
||||||
upOrderDetailAjax({
|
upOrderDetailAjax({
|
||||||
@@ -342,7 +353,7 @@ function handleScan(code) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('handleScan error', err)
|
console.error('handleScan error', err)
|
||||||
}
|
}
|
||||||
}
|
}, 1000, { leading: true, trailing: false })
|
||||||
|
|
||||||
// 出菜
|
// 出菜
|
||||||
async function upOrderDetailAjax(item) {
|
async function upOrderDetailAjax(item) {
|
||||||
@@ -402,8 +413,8 @@ function statusFilter(status) {
|
|||||||
|
|
||||||
// 刷新所有数据的状态
|
// 刷新所有数据的状态
|
||||||
function updateOrderStatus() {
|
function updateOrderStatus() {
|
||||||
console.log('刷新所有数据的状态.tableData.list', tableData.list);
|
// console.log('刷新所有数据的状态.tableData.list', tableData.list);
|
||||||
console.log('刷新所有数据的状态.goodsTableData.value', goodsTableData.value);
|
// console.log('刷新所有数据的状态.goodsTableData.value', goodsTableData.value);
|
||||||
|
|
||||||
if (checkType.value == 1) {
|
if (checkType.value == 1) {
|
||||||
// 刷新按台桌查看的数据
|
// 刷新按台桌查看的数据
|
||||||
@@ -411,8 +422,8 @@ function updateOrderStatus() {
|
|||||||
let timeSpent = formatTimeDiff(item.startOrderTime)
|
let timeSpent = formatTimeDiff(item.startOrderTime)
|
||||||
if (item.subStatus == 'READY_TO_SERVE' && isMoreThanSpecifiedMinutes(timeSpent, userStore.shopInfo.serveTime)) {
|
if (item.subStatus == 'READY_TO_SERVE' && isMoreThanSpecifiedMinutes(timeSpent, userStore.shopInfo.serveTime)) {
|
||||||
item.subStatus = 'TIMEOUT'
|
item.subStatus = 'TIMEOUT'
|
||||||
item.timeout_time = calculateTimeoutDuration(timeSpent)
|
|
||||||
}
|
}
|
||||||
|
item.time_taken = timeTakenUtils(item)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 刷新按菜品查看的数据
|
// 刷新按菜品查看的数据
|
||||||
@@ -421,17 +432,41 @@ function updateOrderStatus() {
|
|||||||
let timeSpent = formatTimeDiff(item.startOrderTime)
|
let timeSpent = formatTimeDiff(item.startOrderTime)
|
||||||
if (item.subStatus == 'READY_TO_SERVE' && isMoreThanSpecifiedMinutes(timeSpent, userStore.shopInfo.serveTime)) {
|
if (item.subStatus == 'READY_TO_SERVE' && isMoreThanSpecifiedMinutes(timeSpent, userStore.shopInfo.serveTime)) {
|
||||||
item.subStatus = 'TIMEOUT'
|
item.subStatus = 'TIMEOUT'
|
||||||
item.timeout_time = calculateTimeoutDuration(timeSpent)
|
|
||||||
}
|
}
|
||||||
|
item.time_taken = timeTakenUtils(item)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据类型返回用时
|
||||||
|
function timeTakenUtils(row) {
|
||||||
|
// 待出菜用时
|
||||||
|
if (row.subStatus == 'READY_TO_SERVE') {
|
||||||
|
return formatTimeDiff(row.startOrderTime)
|
||||||
|
}
|
||||||
|
// 超时用时
|
||||||
|
if (row.subStatus == 'TIMEOUT') {
|
||||||
|
// let timeSpent = formatTimeDiff(row.startOrderTime)
|
||||||
|
// return calculateTimeoutDuration(timeSpent, userStore.shopInfo.serveTime)
|
||||||
|
return formatTimeDiff(row.startOrderTime)
|
||||||
|
}
|
||||||
|
// 出菜用时
|
||||||
|
if (row.subStatus == 'SENT_OUT') {
|
||||||
|
return formatTimeDiff(row.startOrderTime, row.dishOutTime)
|
||||||
|
}
|
||||||
|
// 上菜用时
|
||||||
|
if (row.subStatus == 'DELIVERED') {
|
||||||
|
return formatTimeDiff(row.foodServeTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 启动刷新
|
// 启动刷新
|
||||||
const timer = ref(null)
|
const timer = ref(null)
|
||||||
function startUpdate() {
|
function startUpdate() {
|
||||||
if (userStore.shopInfo.isServeTimeControl && (tableList.length || tableData.list.length)) {
|
if (userStore.shopInfo.isServeTimeControl && (goodsTableData.length || tableData.list.length)) {
|
||||||
|
console.log('启动刷新');
|
||||||
|
|
||||||
// 只有开启的情况下调用
|
// 只有开启的情况下调用
|
||||||
updateOrderStatus()
|
updateOrderStatus()
|
||||||
if (timer.value !== null) {
|
if (timer.value !== null) {
|
||||||
@@ -458,8 +493,8 @@ onMounted(async () => {
|
|||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clearInterval(timer.value)
|
clearInterval(timer.value)
|
||||||
this.timer = null
|
timer.value = null
|
||||||
unsub.close()
|
// unsub.close()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -522,6 +557,20 @@ onUnmounted(() => {
|
|||||||
.left {
|
.left {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--padding);
|
gap: var(--padding);
|
||||||
|
|
||||||
|
.item {
|
||||||
|
&.active {
|
||||||
|
span {
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
@@ -644,6 +693,12 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
.goods_table_title {
|
.goods_table_title {
|
||||||
padding: 10px 0 5px 0;
|
padding: 10px 0 5px 0;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const formRef = ref(null)
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const form = ref({
|
const form = ref({
|
||||||
loginType: 0, // 登录类型 0:商户登录 1:员工登录
|
loginType: 0, // 登录类型 0:商户登录 1:员工登录
|
||||||
username: '',
|
username: userStore.account,
|
||||||
password: '',
|
password: '',
|
||||||
staffUserName: '',
|
staffUserName: '',
|
||||||
code: '',
|
code: '',
|
||||||
|
|||||||
Reference in New Issue
Block a user