Merge branch 'master' of https://gitea.zianxin.com/zax/biz-pc-cloud
This commit is contained in:
commit
361de88372
6 files changed
+105
-138
No files matched your search
@@ -54,6 +54,11 @@
|
||||
>
|
||||
<el-table-column type="selection" width="40" align="center" />
|
||||
<el-table-column type="index" label="#" width="40" />
|
||||
<el-table-column prop="merchantId" label="商户" show-overflow-tooltip min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ merchantOptions.find((item: any) => item.id === row.merchantId)?.name }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="分类名称" show-overflow-tooltip />
|
||||
<el-table-column prop="categoryType" label="餐段类型" show-overflow-tooltip width="180">
|
||||
<template #default="scope">
|
||||
@@ -98,6 +103,7 @@ import { BasicTableProps, useTable } from "/@/hooks/table"
|
||||
import { fetchList, delObjs } from "/@/api/canteen/canteenOnlineCategory"
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message"
|
||||
import { useDict } from "/@/hooks/dict"
|
||||
import { select } from "/@/api/wallet/mch-manage"
|
||||
|
||||
// 引入组件
|
||||
const FormDialog = defineAsyncComponent(() => import("./form.vue"))
|
||||
@@ -112,12 +118,26 @@ const showSearch = ref(true)
|
||||
// 多选变量
|
||||
const selectObjs = ref([]) as any
|
||||
const multiple = ref(true)
|
||||
const merchantOptions = ref<any>([]) // 商户
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {},
|
||||
pageList: fetchList,
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
await getCanteenMerchant()
|
||||
})
|
||||
|
||||
const getCanteenMerchant = async () => {
|
||||
try {
|
||||
const res = await select({ current: 1, size: 9999, types: 1 })
|
||||
merchantOptions.value = res.data.records
|
||||
} catch (error) {
|
||||
merchantOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// table hook
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile, tableStyle } = useTable(state)
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ const openDialog = async () => {
|
||||
dialogVisible.value = true
|
||||
merchantId.value = ""
|
||||
getDataList(false)
|
||||
tableRef.value.clearSelection()
|
||||
}
|
||||
|
||||
// 获取商品数据并且勾选
|
||||
@@ -166,10 +167,11 @@ const resetQuery = () => {
|
||||
|
||||
// 商品选择对话框确认
|
||||
const dialogConfirm = async () => {
|
||||
if (!merchantId.value) return useMessage().error("请选择商户")
|
||||
const $table = tableRef.value
|
||||
if ($table) {
|
||||
const currentSelectedRows = $table.getSelectionRows()
|
||||
if (!currentSelectedRows.length) return useMessage().error("请勾选菜品")
|
||||
if (!merchantId.value) return useMessage().error("请选择商户")
|
||||
|
||||
const items = currentSelectedRows.map((item: any) => {
|
||||
return {
|
||||
|
||||
@@ -66,6 +66,11 @@
|
||||
>
|
||||
<el-table-column type="selection" width="40" align="center" />
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column prop="merchantId" label="商户" show-overflow-tooltip min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ merchantOptions.find((item: any) => item.id === row.merchantId)?.name }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="商品名称" show-overflow-tooltip min-width="100" />
|
||||
<el-table-column prop="categoryId" label="商品分类" show-overflow-tooltip min-width="100">
|
||||
<template #default="{ row }">
|
||||
@@ -77,30 +82,25 @@
|
||||
<preview-image :src="scope.row.picUrl" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort" label="排序字段" show-overflow-tooltip min-width="100" />
|
||||
<el-table-column prop="status" label="商品上下架" show-overflow-tooltip min-width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="spu_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="dishTypeName" label="上架类型" show-overflow-tooltip min-width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-show="scope.row.dishType == 1" type="success">{{ scope.row.dishTypeName}}</el-tag>
|
||||
<el-tag v-show="scope.row.dishType == 2" type="primary">{{ scope.row.dishTypeName}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="商品价格" show-overflow-tooltip min-width="100">
|
||||
<template #default="scope">
|
||||
{{ displayPrice(scope.row.price) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column prop="marketPrice" label="市场价" show-overflow-tooltip min-width="100">-->
|
||||
<!-- <template #default="scope">-->
|
||||
<!-- {{ displayPrice(scope.row.marketPrice) }}-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column prop="stock" label="库存" show-overflow-tooltip min-width="100" />
|
||||
<el-table-column prop="salesCount" label="商品销量" show-overflow-tooltip min-width="100" />
|
||||
<el-table-column prop="dishTypeName" label="上架类型" show-overflow-tooltip min-width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-show="scope.row.dishType == 1" type="success">{{ scope.row.dishTypeName }}</el-tag>
|
||||
<el-tag v-show="scope.row.dishType == 2" type="primary">{{ scope.row.dishTypeName }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="salesCount" label="销量" show-overflow-tooltip min-width="100" />
|
||||
<el-table-column prop="status" label="商品上下架" show-overflow-tooltip min-width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="spu_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort" label="排序字段" show-overflow-tooltip min-width="100" />
|
||||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip min-width="160" />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="scope">
|
||||
@@ -136,6 +136,7 @@ import { useMessage, useMessageBox } from "/@/hooks/message"
|
||||
import { useDict } from "/@/hooks/dict"
|
||||
import { displayPrice } from "/@/utils/formatMoney"
|
||||
import { fetchList as getCanteenOnlineCategory } from "/@/api/canteen/canteenOnlineCategory"
|
||||
import { select } from "/@/api/wallet/mch-manage"
|
||||
|
||||
const FormDialog = defineAsyncComponent(() => import("./form.vue"))
|
||||
const ExportFormDialog = defineAsyncComponent(() => import("./export-form.vue"))
|
||||
@@ -151,12 +152,14 @@ const showSearch = ref(true)
|
||||
const selectObjs = ref([]) as any
|
||||
const multiple = ref(true)
|
||||
const categoryOptions = ref<any>([]) // 商品分类选项
|
||||
const merchantOptions = ref<any>([]) // 商户
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {},
|
||||
pageList: fetchList,
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
await getCanteenMerchant()
|
||||
await getCanteenOnlineCategoryAll()
|
||||
})
|
||||
|
||||
@@ -169,6 +172,15 @@ const getCanteenOnlineCategoryAll = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const getCanteenMerchant = async () => {
|
||||
try {
|
||||
const res = await select({ current: 1, size: 9999, types: 1 })
|
||||
merchantOptions.value = res.data.records
|
||||
} catch (error) {
|
||||
merchantOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile, tableStyle } = useTable(state)
|
||||
|
||||
// 清空搜索条件
|
||||
|
||||
@@ -39,17 +39,14 @@
|
||||
<div class="w-full">
|
||||
<div class="w-full flex flex-wrap items-center justify-center" v-for="(hourType, index) in foodData" :key="index">
|
||||
<div v-for="dish in hourType" :key="dish.id" class="w-60 p-2">
|
||||
<div class="h-32 overflow-hidden">
|
||||
<!-- <div class="absolute inset-0 bg-gradient-to-b from-transparent"></div> -->
|
||||
<div class="relative h-32 overflow-hidden">
|
||||
<img :src="imageBaseUrl + dish.picUrl" :alt="dish.name" class="h-full w-full object-cover" />
|
||||
<!-- <div class="absolute left-2 top-2 rounded-lg">
|
||||
<el-tag type="primary">午餐</el-tag>
|
||||
</div> -->
|
||||
<!-- <div class="absolute right-1 top-2 rounded-lg px-2 py-0.5 text-sm">
|
||||
<el-tag type="primary">
|
||||
{{ canteenCategoryOption?.find((v: any) => v.id == dish.categoryId)?.name }}
|
||||
</el-tag>
|
||||
</div> -->
|
||||
<div class="absolute left-1 top-1">
|
||||
<star-medal text="午餐" />
|
||||
</div>
|
||||
<div class="absolute left-1 top-1">
|
||||
<star-medal :text="canteenCategoryOption?.find((v: any) => v.id == dish.categoryId)?.name" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="w-full flex items-center justify-between bg-[#AEBBF9]/40 px-2 pb-4 backdrop-blur-sm rounded-bl-[50%] rounded-br-[50%]"
|
||||
@@ -68,8 +65,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from "vue"
|
||||
import { selectTimeFoodApi } from "/@/api/canteen/canteenDailyMenu"
|
||||
import { getAllSimple as getCanteenCategory } from "/@/api/canteen/canteenCategory"
|
||||
import { displayPrice } from "/@/utils/formatMoney"
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
import { ElTooltip } from "element-plus"
|
||||
import dayjs from "dayjs"
|
||||
import StarMedal from "./star-medal.vue"
|
||||
|
||||
const containerRef = ref<HTMLElement | null>(null)
|
||||
const currentDate = ref(dayjs().format("YYYY/MM/DD"))
|
||||
@@ -96,7 +99,7 @@ const foodData = reactive<{
|
||||
dinner: [],
|
||||
})
|
||||
const canteenCategoryOption = ref<any>()
|
||||
let timer: number
|
||||
let timer: number | null = null
|
||||
|
||||
onMounted(async () => {
|
||||
timer = setInterval(() => (currentTime.value = dayjs().format("HH:mm:ss")), 1000)
|
||||
@@ -182,6 +185,7 @@ const getDishByType = async () => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取食堂菜品分类
|
||||
const getCanteenDishesCategory = async () => {
|
||||
try {
|
||||
@@ -193,108 +197,6 @@ const getCanteenDishesCategory = async () => {
|
||||
canteenCategoryOption.value = []
|
||||
}
|
||||
}
|
||||
// =====================================
|
||||
import { ref, onMounted, onUnmounted, computed, watch, nextTick } from "vue"
|
||||
import { selectTimeFoodApi } from "/@/api/canteen/canteenDailyMenu"
|
||||
import { getAllSimple as getCanteenCategory } from "/@/api/canteen/canteenCategory"
|
||||
import { displayPrice } from "/@/utils/formatMoney"
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
|
||||
const scrollContainerRef = ref<HTMLElement | null>(null)
|
||||
let scrollOffset = ref(0)
|
||||
let isScrolling = ref(true)
|
||||
let lastTimestamp = 0
|
||||
const SCROLL_SPEED = 0.5
|
||||
let animationFrame: number | null = null
|
||||
|
||||
// 添加一个计算属性来判断是否需要滚动
|
||||
const needScroll = ref(false)
|
||||
|
||||
// 优化后的滚动处理函数
|
||||
const handleScroll = (timestamp: number) => {
|
||||
if (!isScrolling.value) return
|
||||
|
||||
if (!lastTimestamp) {
|
||||
lastTimestamp = timestamp
|
||||
}
|
||||
|
||||
const deltaTime = timestamp - lastTimestamp
|
||||
lastTimestamp = timestamp
|
||||
|
||||
const container = scrollContainerRef.value
|
||||
if (!container) return
|
||||
|
||||
// 计算新的滚动偏移量
|
||||
scrollOffset.value += SCROLL_SPEED * (deltaTime / 16)
|
||||
|
||||
const contentHeight = container.scrollHeight / 2 // 单个内容的高度
|
||||
|
||||
// 当滚动超过一个内容高度时,减去一个内容高度,造成无缝衔接的效果
|
||||
if (scrollOffset.value >= contentHeight) {
|
||||
scrollOffset.value -= contentHeight
|
||||
}
|
||||
|
||||
animationFrame = requestAnimationFrame(handleScroll)
|
||||
}
|
||||
|
||||
// 开始滚动
|
||||
const startScroll = () => {
|
||||
if (!isScrolling.value || !needScroll.value) return
|
||||
lastTimestamp = 0
|
||||
animationFrame = requestAnimationFrame(handleScroll)
|
||||
}
|
||||
|
||||
// 停止滚动
|
||||
const stopScroll = () => {
|
||||
if (animationFrame) {
|
||||
cancelAnimationFrame(animationFrame)
|
||||
animationFrame = null
|
||||
}
|
||||
}
|
||||
|
||||
// 切换滚动状态
|
||||
const toggleScroll = () => {
|
||||
isScrolling.value = !isScrolling.value
|
||||
if (isScrolling.value) {
|
||||
startScroll()
|
||||
} else {
|
||||
stopScroll()
|
||||
}
|
||||
}
|
||||
|
||||
// 修改检查是否需要滚动的函数
|
||||
const checkNeedScroll = () => {
|
||||
const container = scrollContainerRef.value
|
||||
if (!container) return false
|
||||
|
||||
// 获取内容的实际高度(不包括克隆的内容)
|
||||
const contentHeight = container.querySelector(".grid")?.getBoundingClientRect().height || 0
|
||||
// 获取容器的可视高度
|
||||
const containerHeight = container.clientHeight
|
||||
|
||||
// 更新是否需要滚动的状态
|
||||
needScroll.value = contentHeight > containerHeight
|
||||
|
||||
// 如果不需要滚动,确保停止滚动并重置位置
|
||||
if (!needScroll.value) {
|
||||
stopScroll()
|
||||
isScrolling.value = false
|
||||
scrollOffset.value = 0
|
||||
}
|
||||
|
||||
return needScroll.value
|
||||
}
|
||||
|
||||
// 防抖函数
|
||||
function debounce(fn: Function, delay: number) {
|
||||
let timer: number | null = null
|
||||
return function (this: any, ...args: any[]) {
|
||||
if (timer) clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(this, args)
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div class="star-medal">{{ text }}</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
text: {
|
||||
type: String,
|
||||
default: "未知",
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.star-medal {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
z-index: 100;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
background-color: #436df7;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
|
||||
clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
|
||||
}
|
||||
</style>
|
||||
@@ -66,7 +66,7 @@
|
||||
</el-descriptions>
|
||||
|
||||
<el-descriptions :column="3" title="货柜信息" border>
|
||||
<template #extra>
|
||||
<template v-if="state.deviceDetail" #extra>
|
||||
<el-space>
|
||||
<el-button icon="RefreshRight" type="primary" @click="refreshCabinetQrCode">刷新货柜二维码</el-button>
|
||||
<el-button icon="CircleCheck" type="primary" @click="checkOpenAccess" :disabled="checkCloseLoading" :loading="checkOpenLoading">
|
||||
@@ -84,7 +84,7 @@
|
||||
</el-space>
|
||||
</template>
|
||||
</el-descriptions>
|
||||
<el-tabs type="border-card" @tab-click="doorTabClick">
|
||||
<el-tabs v-if="state.deviceDetail" type="border-card" @tab-click="doorTabClick">
|
||||
<el-tab-pane
|
||||
v-if="state.deviceDetail.cabinetList?.length"
|
||||
:label="state.deviceDetail.deviceCode + '-' + item.cabinetNo"
|
||||
@@ -130,6 +130,7 @@
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-empty v-else description="无货柜信息" />
|
||||
|
||||
<el-descriptions :column="0" title="货柜商品" border>
|
||||
<!-- <template #extra>
|
||||
@@ -137,7 +138,7 @@
|
||||
</template> -->
|
||||
</el-descriptions>
|
||||
|
||||
<el-tabs type="border-card" @tab-click="tabClick">
|
||||
<el-tabs v-if="state.deviceDetail" type="border-card" @tab-click="tabClick">
|
||||
<el-tab-pane
|
||||
v-if="state.deviceDetail.cabinetList?.length"
|
||||
:label="state.deviceDetail.deviceCode + '-' + item.cabinetNo"
|
||||
@@ -150,12 +151,12 @@
|
||||
<div class="text-center w-24 text-lg font-bold">第 {{ floorIndex + 1 }} 层:</div>
|
||||
<div class="flex flex-wrap">
|
||||
<div class="flex flex-col items-center justify-start" v-for="(v, indexNo) in floorItem[floorIndex + 1]" :key="indexNo">
|
||||
<div v-if="v.spuId && v.spuDetail" class="w-20 mx-4 my-1 flex flex-col items-center">
|
||||
<div v-if="v.spuId && v.spuDetail" class="w-24 mx-4 my-1 flex flex-col items-center">
|
||||
<div class="relative">
|
||||
<el-icon @click.stop="deleteGoods(v)" class="absolute right-[-8px] top-[-8px] text-xl text-blue-600 z-50">
|
||||
<CircleClose />
|
||||
</el-icon>
|
||||
<preview-image width="86px" height="86px" :src="v.spuDetail.pic" @click.stop />
|
||||
<preview-image width="96px" height="86px" :src="v.spuDetail.pic" @click.stop />
|
||||
</div>
|
||||
<el-tooltip effect="dark" :content="v.spuDetail?.name">
|
||||
<div class="line-clamp-1">{{ v.spuDetail?.name }}</div>
|
||||
@@ -179,7 +180,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="bg-blue-50 w-20 h-20 border border-black mx-4 my-1 flex items-center justify-center cursor-pointer rounded-lg"
|
||||
class="bg-blue-50 w-24 h-20 border border-black mx-4 my-1 flex items-center justify-center cursor-pointer rounded-lg"
|
||||
@click="clickPutaway(v.id)"
|
||||
>
|
||||
点击上架
|
||||
@@ -190,6 +191,7 @@
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-empty v-else description="无货柜商品" />
|
||||
</div>
|
||||
|
||||
<!-- 柜子设置 -->
|
||||
|
||||
Reference in new issue
Block a user