Files
pj_admin_cloud/src/views/hard/hard-door-manager/index.vue
T
2025-04-15 10:49:39 +08:00

396 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div v-loading="loading" class="layout-padding">
<div class="layout-padding-auto layout-padding-view" style="overflow: scroll !important">
<el-descriptions :column="3" title="经营信息" border>
<template #extra>
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
<el-button circle icon="Refresh" @click="doRefresh" />
</el-tooltip>
</template>
<el-descriptions-item label="今日交易金额:">{{ displayPrice(0) }}</el-descriptions-item>
<el-descriptions-item label="本月交易金额:">{{ displayPrice(0) }}</el-descriptions-item>
<el-descriptions-item label="本年交易金额:">{{ displayPrice(0) }}</el-descriptions-item>
</el-descriptions>
<el-descriptions :column="3" title="智能柜设置" border>
<template #extra>
<el-button icon="Edit" type="primary" @click="changeInfo">修改</el-button>
</template>
<el-descriptions-item label="商户名称:">{{}}</el-descriptions-item>
<el-descriptions-item label="设备编号:">{{ state.deviceDetail.deviceCode }}</el-descriptions-item>
<el-descriptions-item label="设备名称:">{{ state.deviceDetail.hardName }}</el-descriptions-item>
<el-descriptions-item label="设备IMEI卡号:">{{ state.deviceDetail.imei }}</el-descriptions-item>
<el-descriptions-item label="货柜数量:">{{ state.deviceDetail.cabinetNum }}</el-descriptions-item>
<el-descriptions-item label="单个货柜摄像头数量:">{{ state.deviceDetail.cabinetCameraNum }}</el-descriptions-item>
<el-descriptions-item label="单个货柜称重单元数量:">{{ state.deviceDetail.cabinetWeightUnitNum }}</el-descriptions-item>
<el-descriptions-item label="SIM卡号:">{{ state.deviceDetail.simSn }}</el-descriptions-item>
<el-descriptions-item label="柜子层数:">{{ state.deviceDetail.doorCount }}</el-descriptions-item>
</el-descriptions>
<el-descriptions :column="3" title="运行信息" border>
<template #extra>
<el-button icon="Edit" type="primary" @click="doVolumeSetting">音量设置</el-button>
</template>
<el-descriptions-item label="售卖状态:">
<el-tag v-if="state.deviceDetail.saleStatus == 1" type="primary">在售</el-tag>
<el-tag v-if="state.deviceDetail.saleStatus == 2" type="danger">停售</el-tag>
</el-descriptions-item>
<el-descriptions-item label="电源状态:">
<el-tag v-if="state.deviceDetail.powerStatus == 1" type="primary">通电</el-tag>
<el-tag v-if="state.deviceDetail.powerStatus == 2" type="danger">断电</el-tag>
</el-descriptions-item>
<el-descriptions-item label="在线状态:">
<el-tag v-if="state.deviceDetail.netStatus == 1" type="primary">在线</el-tag>
<el-tag v-if="state.deviceDetail.netStatus == 2" type="danger">离线</el-tag>
</el-descriptions-item>
<el-descriptions-item label="媒体音量:">
<div class="color-danger">{{ state.deviceDetail.mediaVolume }}</div>
</el-descriptions-item>
<el-descriptions-item label="系统音量:">
<div class="color-danger">{{ state.deviceDetail.systemVolume }}</div>
</el-descriptions-item>
<el-descriptions-item>
{{ state.deviceDetail.signalIntensity }}
<template #label>
SIM信号强度<tip content="大于 -95 表示信号强度好;-95 到 -105 表示信号强度中等;小于 -105 表示信号差" />:
</template>
</el-descriptions-item>
<el-descriptions-item>
{{ state.deviceDetail.signalRatio }}
<template #label>
信噪比<tip content="用于体现信道传输质量的参数。大于 15 表示质量好;15 到 0 表示质量中等;小于等于 0 表示质量差" />:
</template>
</el-descriptions-item>
<el-descriptions-item label="SIM信号值更新时间:">{{ state.deviceDetail.signalTime }}</el-descriptions-item>
<el-descriptions-item label="上次重启时间:">{{ state.deviceDetail.restartTime }}</el-descriptions-item>
</el-descriptions>
<el-descriptions :column="3" title="货柜信息" border>
<template #extra>
<el-space>
<el-button icon="CircleCheck" type="primary" @click="checkOpenAccess" :disabled="checkCloseLoading" :loading="checkOpenLoading">
检修开门
</el-button>
<el-button
icon="CircleClose"
type="primary"
@click="checkCloseAccess"
:disabled="checkOpenLoading"
:loading="checkCloseLoading"
>
检修关门
</el-button>
</el-space>
</template>
</el-descriptions>
<el-tabs type="border-card" @tab-click="doorTabClick">
<el-tab-pane
v-if="state.deviceDetail.cabinetList?.length"
:label="state.deviceDetail.deviceCode + '-' + item.cabinetNo"
v-for="(item, index) in state.deviceDetail.cabinetList"
:key="index"
>
<el-descriptions :column="3" title="" border>
<el-descriptions-item label="货柜号:">{{ item.cabinetNo }}</el-descriptions-item>
<el-descriptions-item label="锁在线:">
<el-tag v-if="item.isLockOnline == 'Y'" type="primary">在线</el-tag>
<el-tag v-if="item.isLockOnline == 2" type="primary">离线</el-tag>
</el-descriptions-item>
<el-descriptions-item label="锁状态:">
<el-tag v-if="item.lockStatus == 1" type="primary">锁关</el-tag>
<el-tag v-if="item.lockStatus == 2" type="danger">锁开</el-tag>
</el-descriptions-item>
<el-descriptions-item label="门状态:">
<el-tag v-if="item.doorStatus == 1" type="primary">门关</el-tag>
<el-tag v-if="item.doorStatus == 2" type="danger">门开</el-tag>
</el-descriptions-item>
<el-descriptions-item label="货柜售卖状态:">
<el-tag v-if="item.saleStatus == 1" type="primary">在售</el-tag>
<el-tag v-if="item.saleStatus == 2" type="danger">停售</el-tag>
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
</el-tabs>
<el-descriptions :column="0" title="货柜商品" border>
<!-- <template #extra>
<el-button icon="Edit" type="primary">设置</el-button>
</template> -->
</el-descriptions>
<el-tabs type="border-card" @tab-click="tabClick">
<el-tab-pane
v-if="state.deviceDetail.cabinetList?.length"
:label="state.deviceDetail.deviceCode + '-' + item.cabinetNo"
v-for="(item, index) in state.deviceDetail.cabinetList"
:key="index"
>
<div v-for="(floorItem, floorIndex) in state.cabinetData" :key="floorIndex">
<el-divider />
<div class="text-black flex items-center">
<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 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 />
</div>
<el-tooltip effect="dark" :content="v.spuDetail?.name">
<div class="line-clamp-1">{{ v.spuDetail?.name }}</div>
</el-tooltip>
<div
class="color-primary w-full flex items-center"
:class="v.spuDetail.specsCapacity ? 'justify-between' : 'justify-center'"
>
<span>{{ displayPrice(v.spuDetail.price) }}</span>
<span>{{ v.spuDetail.specsCapacity }}</span>
</div>
<!-- <div class="w-full flex items-center justify-between">
<span>{{ v.spuDetail.specsTaste }}</span>
<span>{{ v.spuDetail.specsWeight }}</span>
<span>{{ v.spuDetail.categoryName }}</span>
</div> -->
</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"
@click="clickPutaway(v.id)"
>
点击上架
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
<!-- 柜子设置 -->
<info-setting ref="infoSettingRef" @refreshInfo="refreshInfo" />
<!-- 音量设置 -->
<volume-setting ref="volumeSettingRef" @refreshVolume="refreshVolume" />
<!-- 商品上架 -->
<goods-putaway ref="goodsPutawayRef" @refreshCabinet="refreshCabinet" />
</div>
</template>
<script setup lang="ts" name="hardDoorManager">
import { onMounted, ref } from "vue"
import { useMessage } from "/@/hooks/message"
import { displayPrice } from "/@/utils/formatMoney"
import * as hardDoorManager from "/@/api/hard/hard-door-manager"
import { ElMessageBox } from "element-plus"
import { getByCabinetNo, unPutaway } from "/@/api/hard/hard-spu"
import { closeAccess, openAccess } from "/@/api/hard/hard-door-manager"
const InfoSetting = defineAsyncComponent(() => import("./info-setting.vue"))
const VolumeSetting = defineAsyncComponent(() => import("./volume-setting.vue"))
const GoodsPutaway = defineAsyncComponent(() => import("./goods-putaway.vue"))
const { query } = useRoute()
const loading = ref(false)
const checkOpenLoading = ref(false)
const checkCloseLoading = ref(false)
const infoSettingRef = ref()
const volumeSettingRef = ref()
const goodsPutawayRef = ref()
const state = reactive<any>({
hardId: "",
deviceDetail: {},
cabinetData: [],
curActivedDoorTabIndex: 0,
curActivedTabIndex: 0,
})
onMounted(async () => {
await getDetail()
await getCabinet()
})
// 获取柜子详情
const getDetail = async () => {
const id = query.id as unknown as any
if (!id) return useMessage().error("设备id不存在")
state.hardId = id
const { data } = await hardDoorManager.getByHardId({ hardId: state.hardId })
if (data) {
state.deviceDetail = { ...data, cabinetList: JSON.parse(data.cabinetList) }
}
}
// 获取柜子物品
const getCabinet = async (cabinetIndex: number = 0) => {
if (!state.hardId) return useMessage().error("设备id不存在")
if (!state.deviceDetail.cabinetList?.length) return useMessage().error("设备空间不存在")
const { data } = await getByCabinetNo({
hardId: state.hardId,
cabinetNo: state.deviceDetail.cabinetList[cabinetIndex].cabinetNo,
})
if (data) {
state.cabinetData = data
}
}
// 修改基本信息
const changeInfo = async () => {
if (infoSettingRef.value) {
infoSettingRef.value.openDialog(state.hardId)
}
}
const refreshInfo = () => {
doRefresh()
}
// 音量设置
const doVolumeSetting = async () => {
if (volumeSettingRef.value) {
volumeSettingRef.value.openDialog(state.deviceDetail.hardId, state.deviceDetail.mediaVolume, state.deviceDetail.systemVolume)
}
}
const refreshVolume = (data: { hardId: string; mediaVolume: number; systemVolume: number }) => {
state.deviceDetail.mediaVolume = data.mediaVolume
state.deviceDetail.systemVolume = data.systemVolume
}
// 检修开门
const checkOpenAccess = async () => {
try {
checkOpenLoading.value = true
const res = await openAccess({
hardDoorId: state.hardId,
cabinetNo: state.deviceDetail.cabinetList[state.curActivedDoorTabIndex].cabinetNo,
})
if (res.code == 0) {
useMessage().success("操作成功")
return
}
useMessage().error(res.msg || "操作失败")
} catch (error: any) {
useMessage().error(error.msg)
} finally {
checkOpenLoading.value = false
}
}
// 检修关门
const checkCloseAccess = async () => {
try {
checkCloseLoading.value = true
const res = await closeAccess({
hardDoorId: state.hardId,
cabinetNo: state.deviceDetail.cabinetList[state.curActivedDoorTabIndex].cabinetNo,
})
if (res.code == 0) {
useMessage().success("操作成功")
return
}
useMessage().error(res.msg || "操作失败")
} catch (error: any) {
useMessage().error(error.msg)
} finally {
checkCloseLoading.value = false
}
}
// 点击柜门tab
const doorTabClick = async (tab: any) => {
state.curActivedDoorTabIndex = tab.index
}
// 点击柜门商品tab
const tabClick = async (tab: any) => {
state.curActivedTabIndex = tab.index
await getCabinet(tab.index)
}
// 点击上架
const clickPutaway = (cabinetItemId: any) => {
if (goodsPutawayRef.value) {
goodsPutawayRef.value.openDialog(cabinetItemId)
}
}
const refreshCabinet = async () => {
try {
loading.value = true
await getCabinet(state.curActivedTabIndex)
} finally {
loading.value = false
}
}
const doRefresh = async () => {
try {
loading.value = true
await getDetail()
await getCabinet(state.curActivedTabIndex)
} finally {
loading.value = false
}
}
// 下架商品
const deleteGoods = async (v: any) => {
if (!v.id) return useMessage().error("绑定id不存在")
if (!v.spuId) return useMessage().error("商品id不存在")
ElMessageBox.confirm("确定下架吗?", "商品下架", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }).then(
async () => {
loading.value = true
const res = await unPutaway({ id: v.id, hardSpuId: v.spuId }).finally(() => (loading.value = false))
if (res.code == 0) {
useMessage().success("下架成功")
return getCabinet(state.curActivedTabIndex)
}
useMessage().error(res.msg || "下架失败")
},
)
}
</script>
<style lang="scss" scoped>
:deep(.el-descriptions) {
&:not(:nth-child(1)) {
margin-top: 20px;
}
.el-descriptions__cell.is-bordered-label {
width: 150px;
background-color: transparent;
border: none;
}
.el-descriptions__cell.is-bordered-content {
width: 200px;
border: none;
}
.el-descriptions__title {
display: flex;
align-items: center;
&::before {
display: inline-block;
width: 3px;
height: 20px;
margin-right: 10px;
background-color: #409eff;
content: "";
}
}
.el-descriptions-item__container {
margin: 0 10px;
.no-colon {
margin: 0;
&::after {
content: "";
}
}
}
}
</style>