智能柜货品补货上架下架

This commit is contained in:
weiwei committed 2025-04-18 19:18:23 +08:00
1 parent 3d0d330420
commit 7654dcd9c3
8 files changed
+221 -21576

No files matched your search

-21474
View File
File diff suppressed because it is too large. Load diff
+4 -4
View File
@@ -119,19 +119,19 @@ import { onLoad, onShow } from "@dcloudio/uni-app"
import { doorApi } from "@/sheep/api"
const state = reactive<any>({
hardDoorId: "",
id: "",
detail: {},
})
onLoad((option: any) => {
if (!option.hardDoorId) return
state.hardDoorId = option.hardDoorId
if (!option.id) return
state.id = option.id
})
onShow(async () => {
try {
uni.showLoading({ title: "加载中...", mask: true })
const res = await doorApi.hardDoorDetail({ hardDoorId: state.hardDoorId })
const res = await doorApi.hardDoorDetail({ hardDoorId: state.id })
if (res.code == 0) {
state.detail = res.data
return
+12 -12
View File
@@ -18,15 +18,15 @@
<tm-sheet v-for="(item, index) in pageHook.list" :key="index" :margin="[0, 20]">
<tm-text font-size="32">{{ item.hardName }} {{ item.deviceCode }}</tm-text>
<view class="card flex justify-around items-center my-1 p-2">
<view class="flex-col items-center p-2 rounded-1 active:bg-#E8E8E8" @click="doDetail(item.hardId)">
<view class="flex-col items-center p-2 rounded-1 active:bg-#E8E8E8" @click="doDetail(item.id)">
<image class="w-50 h-50" src="@/static/page/货柜详情.svg" />
<tm-text>货柜详情</tm-text>
</view>
<view class="flex-col items-center p-2 rounded-1 active:bg-#E8E8E8" @click="replenishment(item.hardId)">
<view class="flex-col items-center p-2 rounded-1 active:bg-#E8E8E8" @click="replenishment(item.id)">
<image class="w-50 h-50" src="@/static/page/开门.svg" />
<tm-text>货柜补货</tm-text>
</view>
<view class="flex-col items-center p-2 rounded-1 active:bg-#E8E8E8" @click="openPutaway(item.hardId)">
<view class="flex-col items-center p-2 rounded-1 active:bg-#E8E8E8" @click="openPutaway(item.id)">
<image class="w-50 h-50" src="@/static/page/货柜上架.svg" />
<tm-text>商品上架</tm-text>
</view>
@@ -50,20 +50,20 @@ const query = (page: number, pagesize: number) => {
}
// 货柜详情
const doDetail = (hardDoorId: string) => {
if (!hardDoorId) return
router.jump("/pages/cabinet/cabinetDetail", { hardDoorId }, 1)
const doDetail = (id: string) => {
if (!id) return
router.jump("/pages/cabinet/cabinetDetail", { id }, 1)
}
// 商品补货
const replenishment = (hardDoorId: string) => {
if (!hardDoorId) return
router.jump("/pages/cabinet/replenishment", { hardDoorId }, 1)
const replenishment = (id: string) => {
if (!id) return
router.jump("/pages/cabinet/replenishment", { id }, 1)
}
// 商品上架
const openPutaway = (hardDoorId: string) => {
if (!hardDoorId) return
router.jump("/pages/cabinet/putaway", { hardDoorId }, 1)
const openPutaway = (id: string) => {
if (!id) return
router.jump("/pages/cabinet/putaway", { id }, 1)
}
</script>
+185 -70
View File
@@ -1,16 +1,8 @@
<template>
<crud-layout bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
>
<template #top>
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
<tm-sticky>
<tm-sticky-header>
<view class="h-5rpx" />
<view class="bg-white rounded-20rpx my-20rpx font-bold">
<z-tabs
:list="
@@ -32,17 +24,25 @@
@change="doorTabsChange"
/>
</view>
</template>
</tm-sticky-header>
<view class="w-full w-full">
<view v-for="(item, index) in state.cabinetList" :key="index">
<tm-text class="text-center">第 {{ index + 1 }} 层</tm-text>
<view class="flex flex-wrap mb-4">
<view v-for="(v, i) in item[index + 1]" :key="i" class="w-1/5 h-150 p-1">
<view v-if="v.spuId && v.spuDetail" class="card w-full h-full flex items-center justify-center">
<image class="w-full h-full" :src="v.spuDetail.pic" />
<view v-for="(v, i) in item[index + 1]" :key="i" class="w-1/5 h-230 p-1">
<view v-if="v.spuId && v.spuDetail" class="flex-col items-center relative">
<view class="absolute top-[-10rpx] right-[-10rpx] z-200" @click="doUnPutaway(v)">
<image class="w-36rpx h-36rpx" src="@/static/page/关闭.svg" />
</view>
<image class="w-full h-150 rounded-2" :src="v.spuDetail.pic" />
<view class="sub-text-22">
{{ v.spuDetail.name?.length > 4 ? v.spuDetail.name.substring(0, 4) + "..." : v.spuDetail.name }}
</view>
<view class="sub-text-22 c-red!">¥{{ displayPrice(v.spuDetail.price) }}</view>
</view>
<view v-else class="card w-full h-full p-2 flex items-center justify-center active:bg-#e8e8e8!" @click="doPutaway">
<view v-else class="card w-full h-150 p-2 flex items-center justify-center active:bg-#e8e8e8!" @click="doPutaway(v.id)">
<image class="w-half h-half" src="@/static/page/加号.svg" />
</view>
</view>
@@ -51,87 +51,133 @@
</view>
<view class="h-30rpx" />
</z-paging>
</tm-sticky>
<tm-drawer
title="选择商品"
:showClose="true"
:showFooter="true"
size="90%"
title=""
:showClose="false"
:showFooter="false"
size="98%"
placement="bottom"
v-model:show="state.showDrawer"
zIndex="999"
:duration="100"
zIndex="100"
>
<tm-tabs
item-width="50%"
gap="0"
line-full
line-height="4rpx"
round="10"
active-title-color=""
:list="['平台商品', '我的商品']"
@change="goodsTabsChange"
/>
<view class="h-30rpx" />
<z-paging
ref="pageRef"
:fixed="true"
height="98%"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<template #top>
<view class="px-4 pt-2">
<tm-input v-model="queryParams.name" type="text" inputPadding="16" :showClear="true" placeholder="请输入货品名称">
<template v-slot:rightIcon>
<tm-button class="mr-1" size="m" @click="searchGoods">搜索</tm-button>
</template>
</tm-input>
</view>
<z-tabs
:list="['平台商品', '我的商品']"
bar-width="150"
:active-style="{
fontSize: '30rpx',
}"
:inactive-style="{
fontSize: '30rpx',
}"
@change="goodsTabsChange"
/>
</template>
<tm-checkbox-group v-model="state.checkboxValue" direction="column">
<view
v-for="(item, index) in listview"
:key="index"
class="w-full h-100rpx flex items-center p-2 border-1 border-solid border-b-coolGray"
:class="[state.checkboxValue.includes(item.id) ? 'bg-#e8e8e8' : '']"
>
<tm-checkbox class="w-full h-full" :value="item.id">
<template v-slot:label="checked">
<tm-text>{{ 11111 }}</tm-text>
</template>
</tm-checkbox>
</view>
</tm-checkbox-group>
<tm-radio-group v-model="state.radioValue" direction="column">
<view
v-for="(item, index) in pageHook.list"
:key="index"
class="w-full flex items-center p-2"
:class="[state.radioValue == item.id ? 'bg-#e8e8e8' : '']"
>
<tm-radio class="w-full h-full px-2" :value="item.id">
<template v-slot:label="checked">
<view class="flex items-center">
<image class="w-130rpx h-130rpx" :src="item.pic" />
<view class="ml-2 flex-1 flex-col">
<tm-text font-size="30">{{ item.name }}</tm-text>
<view class="flex justify-between my-1">
<tm-text font-size="26">种类:{{ item.categoryName }}</tm-text>
<tm-text font-size="26">售卖数量:{{ item.salesCount }}</tm-text>
<tm-text font-size="26">库存:{{ item.repertoryCount || 0 }}</tm-text>
</view>
<view class="flex justify-between items-center">
<tm-text font-size="30" color="red">¥{{ displayPrice(item.price) }}</tm-text>
</view>
</view>
</view>
</template>
</tm-radio>
</view>
</tm-radio-group>
<view class="h-30rpx" />
<view class="h-30rpx" />
<template #footer>
<view class="px-20rpx flex justify-between">
<tm-button skin="thin" block>取消</tm-button>
&nbsp;&nbsp;
<tm-button block>上架</tm-button>
</view>
</template>
<template #bottom>
<view class="px-20rpx pt-2 flex justify-between">
<tm-button skin="thin" block @click="state.showDrawer = false">取消</tm-button>
&nbsp;&nbsp;
<tm-button block @click="confirmPutaway" :disabled="!state.radioValue">上架</tm-button>
</view>
</template>
</z-paging>
</tm-drawer>
</crud-layout>
</template>
<script setup lang="ts">
import { computed, reactive } from "vue"
import { computed, reactive, ref } from "vue"
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
import { doorApi } from "@/sheep/api"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { displayPrice } from "@/sheep/utils/formatMoney"
import { hooks } from "@/sheep"
const state = reactive<any>({
hardDoorId: "",
id: "",
detail: {},
curDoorTabIndex: 0,
cabinetList: [],
curGoodsTabIndex: 0,
cabinetList: [],
showDrawer: false,
checkboxValue: [],
cabinetNoId: "",
radioValue: "",
})
const queryParams = reactive({
name: "",
skuType: "0",
})
const pageRef = ref()
const curCabinetNo = computed(() => {
if (state.detail.cabinetList) return state.detail.cabinetList[state.curDoorTabIndex].cabinetNo
})
onLoad((option: any) => {
if (!option.hardDoorId) return
state.hardDoorId = option.hardDoorId
if (!option.id) return
state.id = option.id
})
onShow(async () => {
if (!state.hardDoorId) return
if (!state.id) return
try {
uni.showLoading({ title: "加载中...", mask: true })
const res = await doorApi.hardDoorDetail({ hardDoorId: state.hardDoorId })
const res = await doorApi.hardDoorDetail({ hardDoorId: state.id })
if (res.code == 0) {
state.detail = res.data
} else {
@@ -151,7 +197,7 @@ onShow(async () => {
const getCabinetList = async () => {
try {
uni.showLoading({ title: "加载中...", mask: true })
const res = await doorApi.cabinetList({ hardId: state.hardDoorId, cabinetNo: curCabinetNo.value })
const res = await doorApi.cabinetList({ hardId: state.detail.hardId, cabinetNo: curCabinetNo.value })
if (res.code == 0) {
state.cabinetList = res.data
} else {
@@ -169,13 +215,82 @@ const doorTabsChange = async (e: number) => {
await getCabinetList()
}
const goodsTabsChange = (index: number) => {
state.curGoodsTabIndex = index
const goodsTabsChange = async (e: number) => {
state.curGoodsTabIndex = e
queryParams.skuType = e.toString()
pageRef.value.reload(true)
}
// 上架
const doPutaway = () => {
// 点击上架
const doPutaway = async (cabinetNoId: string) => {
state.curGoodsTabIndex = 0
queryParams.skuType = "0"
queryParams.name = ""
state.cabinetNoId = cabinetNoId
state.radioValue = ""
state.showDrawer = true
}
// 搜索商品
const searchGoods = () => {
state.radioValue = ""
pageRef.value.reload(true)
}
const pageHook = hooks.usePage(pageRef, doorApi.hardDoorSpuPage, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, queryParams)
}
// 确认上架
const confirmPutaway = async () => {
if (!state.radioValue) return uni.showToast({ title: "请先选择商品", icon: "none" })
try {
uni.showLoading({ title: "上架中...", mask: true })
const res = await doorApi.putaway({ id: state.cabinetNoId, hardSpuId: state.radioValue })
if (res.code == 0) {
state.showDrawer = false
state.cabinetNoId = ""
state.radioValue = ""
await getCabinetList()
} else {
uni.showToast({ title: res.msg, icon: "none" })
}
} catch (error: any) {
uni.showToast({ title: error.msg, icon: "none" })
} finally {
uni.hideLoading()
}
}
// 确认下架
const doUnPutaway = (v: any) => {
if (!v.id) return uni.showToast({ title: "绑定id不存在", icon: "none" })
if (!v.spuId) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.showModal({
title: "提示",
content: "确定要下架该商品吗?",
success: async (res) => {
if (res.confirm) {
try {
uni.showLoading({ title: "下架中...", mask: true })
const res: any = await doorApi.unPutaway({ id: v.id, hardSpuId: v.spuId })
if (res.code == 0) {
uni.showToast({ title: "下架成功", icon: "none" })
await getCabinetList()
} else {
uni.showToast({ title: res.msg, icon: "none" })
}
} catch (error: any) {
uni.showToast({ title: error.msg, icon: "none" })
} finally {
uni.hideLoading()
}
}
},
})
}
</script>
+13 -10
View File
@@ -62,9 +62,9 @@
<template #main-bottom>
<view class="m-30rpx flex justify-between">
<tm-button block @click="openDoor" :disabled="false">开门补货</tm-button>
<tm-button block @click="openDoor">开门补货</tm-button>
&nbsp;&nbsp;
<tm-button block @click="replenishmentComplete" :disabled="!state['flowId' + curCabinetNo.value]">补货完成</tm-button>
<tm-button block @click="replenishmentComplete" :disabled="!state['flowId' + curCabinetNo]">补货完成</tm-button>
</view>
</template>
</crud-layout>
@@ -78,7 +78,7 @@ import { doorApi } from "@/sheep/api"
import { displayPrice } from "@/sheep/utils/formatMoney"
const state = reactive<any>({
hardDoorId: "",
id: "",
detail: {},
curDoorTabIndex: 0,
cabinetPutawayList: [],
@@ -89,15 +89,15 @@ const curCabinetNo = computed(() => {
const putawayList = computed(() => state.cabinetPutawayList.map((item: any) => ({ hardSpuId: item.spuId, plusCount: item.plusCount || 0 })))
onLoad((option: any) => {
if (!option.hardDoorId) return
state.hardDoorId = option.hardDoorId
if (!option.id) return
state.id = option.id
})
onShow(async () => {
if (!state.hardDoorId) return
if (!state.id) return
try {
uni.showLoading({ title: "加载中...", mask: true })
const res = await doorApi.hardDoorDetail({ hardDoorId: state.hardDoorId })
const res = await doorApi.hardDoorDetail({ hardDoorId: state.id })
if (res.code == 0) {
state.detail = res.data
} else {
@@ -117,7 +117,7 @@ onShow(async () => {
const getCabinetPutawayList = async () => {
try {
uni.showLoading({ title: "加载中...", mask: true })
const res = await doorApi.cabinetPutawayList({ hardDoorId: state.detail.id, cabinetNo: curCabinetNo.value })
const res = await doorApi.cabinetPutawayList({ hardDoorId: state.id, cabinetNo: curCabinetNo.value })
if (res.code == 0) {
state.cabinetPutawayList = res.data
} else {
@@ -138,9 +138,10 @@ const doorTabsChange = async (e: number) => {
// 开门补货
const openDoor = async () => {
if (!state.id) return
try {
uni.showLoading({ title: "正在开门", mask: true })
const res = await doorApi.openRepertory({ hardDoorId: state.detail.id, cabinetNo: curCabinetNo.value })
const res = await doorApi.openRepertory({ hardDoorId: state.id, cabinetNo: curCabinetNo.value })
if (res.code == 0) {
state["flowId" + curCabinetNo.value] = res.data
uni.showToast({ title: "开门成功", icon: "none" })
@@ -161,7 +162,9 @@ const replenishmentComplete = async () => {
uni.showLoading({ title: "正在保存", mask: true })
const res = await doorApi.repertoryDone({ flowId: state["flowId" + curCabinetNo.value], list: putawayList.value })
if (res.code == 0) {
uni.showToast({ title: "保存成功", icon: "none" })
state["flowId" + curCabinetNo.value] = ""
uni.showToast({ title: "补货成功", icon: "none" })
await getCabinetPutawayList()
} else {
uni.showToast({ title: res.msg || "保存失败", icon: "none" })
}
+2 -2
View File
@@ -76,7 +76,7 @@ const state = reactive<{
// { text: "外来人员就餐", icon: "/static/icon/service_1.png", router: "/pages/apply/foreign-list" },
// { text: "跨单位就餐", icon: "/static/icon/service_1.png", router: "/pages/apply/stride-list" },
{ text: "人脸管理", icon: "/static/icon/service_5.png", router: "/pages/human-face/list" },
// { text: "智能柜列表", icon: "/static/icon/service_5.png", router: "/pages/cabinet/cabinetList" },
{ text: "智能柜列表", icon: "/static/icon/service_5.png", router: "/pages/cabinet/cabinetList" },
// { text: "意见反馈", icon: "/static/icon/service_5.png", router: "/pages/integrated/feedback/index" },
],
appInfo: "",
@@ -270,7 +270,7 @@ const scanCode = {
// const testQrCode = "eyJpZCI6IjE4OTYxNTcyMDc2NDQwNTM1MDYiLCJuYW1lIjoi5rWL6K+V5ZWG5oi3In0=" // 线上-测试超市-收款码
// const testQrCode = "eyJpZCI6IjE5MDU4MTY3NTEwNDM0NTI5MzAiLCJuYW1lIjoi5paw5Y6/5bqc6LaF5biCIn0=" // 测试环境-邓本地-新县府超市-收款码
// const testQrCode = "eyJpZCI6IjE5MDc2ODQwNTY4NDA4NDMyNjYiLCJuYW1lIjoi5pm66IO95p+c6Ieq6JCl5ZWG5oi3MSJ9" // 测试环境-邓本地-智能柜自营商户1-收款码
const testQrCode = "eyJoYXJkRG9vcklkIjoiMTkxMTYwNDg5ODQ1NTc4OTU2OSIsImNhYmluZXRObyI6IjEifQ==" // 测试智能柜货柜二维码
const testQrCode = "eyJoYXJkRG9vcklkIjoiMTkxMzE1NzA4MDQxODI5NTgwOSIsImNhYmluZXRObyI6IjEifQ==" // 测试智能柜货柜二维码
uni.showModal({ content: "开发环境不是浙政钉和诗画环境,扫码仅供测试,收款商家为测试商户超市" })
return scanCode.decodeBase64(testQrCode)
} else if (state.appInfo == "zzd") {
+4 -4
View File
@@ -61,7 +61,7 @@ export default {
* @param id 绑定id
* @param hardSpuId 商品id
*/
putaway: (data: { hardDoorId: any }) =>
putaway: (data: { id: any; hardSpuId: any }): Promise<any> =>
request({
url: "hard/hard-spu/app/putaway",
method: "POST",
@@ -76,7 +76,7 @@ export default {
* @param id 绑定id
* @param hardSpuId 商品id
*/
unPutaway: (data: { hardDoorId: { id: any; hardSpuId: any } }) =>
unPutaway: (data: { id: any; hardSpuId: any }) =>
request({
url: "hard/hard-spu/app/un-putaway",
method: "POST",
@@ -116,7 +116,7 @@ export default {
}),
/**
* app上架完成
* 补货完成
* @param flowId
* @param list
*/
@@ -131,7 +131,7 @@ export default {
}),
/**
* 上架开门
* 补货开门
* @param hardDoorId 智能柜编号
* @param cabinetNo 货柜编号
*/
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1744973847967" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2622" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M983.779031 312.718444a510.292766 510.292766 0 0 0-109.738544-162.758931A510.292766 510.292766 0 0 0 512 0.000569a510.292766 510.292766 0 0 0-362.040487 149.958944A510.292766 510.292766 0 0 0 0.000569 512a510.292766 510.292766 0 0 0 149.958944 362.040487A510.292766 510.292766 0 0 0 512 1023.999431a510.292766 510.292766 0 0 0 362.040487-149.958944A510.292766 510.292766 0 0 0 1023.999431 512a508.813657 508.813657 0 0 0-40.2204-199.281556zM512 951.40929c-242.289509 0-439.40929-197.119781-439.40929-439.40929S269.710491 72.59071 512 72.59071 951.40929 269.710491 951.40929 512 754.289509 951.40929 512 951.40929z" p-id="2623" fill="#0779FD"></path><path d="M693.020243 330.979757c-12.515542-12.515542-31.516409-13.767096-42.439064-2.844442L512 466.716495 373.418821 328.135315c-10.922655-10.922655-29.923522-9.6711-42.439064 2.844442-12.515542 12.515542-13.767096 31.516409-2.844442 42.439064L466.716495 512l-138.58118 138.581179c-10.922655 10.922655-9.6711 29.923522 2.844442 42.439064 12.515542 12.515542 31.516409 13.767096 42.439064 2.844442L512 557.226616l138.581179 138.638069c10.922655 10.922655 29.923522 9.6711 42.439064-2.844442 12.515542-12.515542 13.767096-31.516409 2.844442-42.439064L557.226616 512l138.638069-138.581179c10.922655-10.922655 9.6711-29.923522-2.844442-42.439064z" p-id="2624" fill="#0779FD"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB