|
|
@@ -0,0 +1,435 @@
|
|
|
+<template>
|
|
|
+ <div class="mapBox">
|
|
|
+ <div style="width:400px;height: 350px;border: 1px solid black;margin: 10px;position: absolute;z-index: 1;top:0">
|
|
|
+ <h3 style="padding-left: 10px">操作流程:</h3>
|
|
|
+ <div style="display: flex;padding-left: 10px">
|
|
|
+ <h4>1.选择物资柜</h4>
|
|
|
+ <el-select
|
|
|
+ style="width: 215px;margin: 10px 20px;"
|
|
|
+ v-model="queryParams.materialsCabinetId"
|
|
|
+ placeholder="请选择物资柜"
|
|
|
+ @change="handleCabinetChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="dict in cabinets"
|
|
|
+ :key="dict.value"
|
|
|
+ :label="dict.label"
|
|
|
+ :value="dict.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div style="display: flex;padding-left: 10px">
|
|
|
+ <h4>2.</h4>
|
|
|
+ <el-button @click="changeDoor(true)" style="width:60px;height:30px;padding:5px 8px;margin: 12px 10px">开柜门
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <div style="display: flex;padding-left: 10px">
|
|
|
+ <h4>3.取物资/还物资</h4>
|
|
|
+ <!-- <el-input v-model="inputStatus" style="width:150px"></el-input>-->
|
|
|
+ </div>
|
|
|
+ <div style="display: flex;padding-left: 10px">
|
|
|
+ <h4>4.</h4>
|
|
|
+ <el-button :disabled="!doorOpen" @click="changeDoor(false)"
|
|
|
+ style="width:60px;height:30px;padding:5px 8px;margin: 12px 10px"
|
|
|
+ >关柜门
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div id="container" ref="container" style="width: 260vh; height: 90vh; background-color: white;"></div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import Konva from 'konva'
|
|
|
+import {
|
|
|
+ getExMaterials,
|
|
|
+ getIsMaterialsCabinets, insertCabinetOpenTimeout,
|
|
|
+ listMaterials,
|
|
|
+ selectMaterialsById,
|
|
|
+ updateIsMaterialById,
|
|
|
+ updateCabinetOpenTimeout
|
|
|
+} from '@/api/mes/material/information'
|
|
|
+import { getDicts } from '@/api/system/dict/data'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'Lending',
|
|
|
+ dicts:['timer_params'],
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ stage: null,
|
|
|
+ layer: null,
|
|
|
+ bgLayer: null,
|
|
|
+ list: [], // 三号柜子的物资
|
|
|
+ listInCabinet: [], // 存储物资柜内的物资
|
|
|
+ listOutOfCabinet: [], // 存储物资柜外的物资
|
|
|
+ cabinets: [], // 物资所属柜
|
|
|
+ doorOpen: false,
|
|
|
+ queryParams: {
|
|
|
+ current: 1,
|
|
|
+ size: -1,
|
|
|
+ materialsCabinetId: null,
|
|
|
+ loanState: null
|
|
|
+ },
|
|
|
+ inputStatus: '当前柜门已关闭',//柜门开关状态
|
|
|
+ materialElements: [], // 存储物资图标对象
|
|
|
+ materialsToUpdate: [], // 存储需要更新的物资
|
|
|
+ overTime:0,//
|
|
|
+ timer:null,//定时器
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.initKonva()
|
|
|
+ this.inputStatus = '当前柜门已关闭'
|
|
|
+ this.materialsCabinets()
|
|
|
+ })
|
|
|
+ getDicts('timer_params').then(res => {
|
|
|
+ console.log(res,'字典值')
|
|
|
+ this.overTime=res.data[0].dictValue
|
|
|
+ })
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ changeDoor(value) {
|
|
|
+ this.doorOpen = value
|
|
|
+ if (this.doorOpen) {
|
|
|
+ this.$message.success('柜门已打开')
|
|
|
+ this.updateDraggableStatus()
|
|
|
+
|
|
|
+ this.inputStatus = '当前柜门已打开'
|
|
|
+ // 获取定时器参数
|
|
|
+ this.getDicts('timer_params').then(res => {
|
|
|
+ console.log(res, '字典值');
|
|
|
+ this.overTime = res.data[0].dictValue;
|
|
|
+
|
|
|
+ // 如果 overTime 大于 0,则启动定时器
|
|
|
+ if (this.overTime > 0) {
|
|
|
+ this.timer = setTimeout(() => {
|
|
|
+ const data = {
|
|
|
+ loanFromId: this.queryParams.materialsCabinetId
|
|
|
+ };
|
|
|
+ insertCabinetOpenTimeout(data).then((res) => {
|
|
|
+ console.log(res);
|
|
|
+ if(res.data){
|
|
|
+ this.$message.error('柜门超过十秒未关闭')
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+ }, this.overTime * 1000); // 将秒转换为毫秒
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$message.info('柜门已关闭')
|
|
|
+ this.inputStatus = '当前柜门已关闭'
|
|
|
+ // 清除定时器
|
|
|
+ if (this.timer) {
|
|
|
+ clearTimeout(this.timer);
|
|
|
+ this.timer = null;
|
|
|
+ }
|
|
|
+ this.updateMaterialsBatch() // 柜门关闭时调用批量更新接口
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取物资柜信息
|
|
|
+ materialsCabinets() {
|
|
|
+ getIsMaterialsCabinets(this.queryParams).then((response) => {
|
|
|
+ if (response?.data?.records) {
|
|
|
+ this.cabinets = response.data.records.map((item) => ({
|
|
|
+ value: item.cabinetId,
|
|
|
+ label: item.cabinetName
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleCabinetChange() {
|
|
|
+ // 清空之前渲染的物资元素
|
|
|
+ this.clearMaterialsFromLayer()
|
|
|
+
|
|
|
+ // 获取柜内和柜外物资
|
|
|
+ Promise.all([this.getMaterialsInCabinet(), this.getMaterialsOutOfCabinet()])
|
|
|
+ .then(() => {
|
|
|
+ // 在所有数据获取完成后,统一渲染物资
|
|
|
+ this.addMaterialsToLayer()
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ async getMaterialsInCabinet() {
|
|
|
+ this.queryParams.loanState = '1'; // 设置查询条件为物资柜内
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res1 = await listMaterials(this.queryParams);
|
|
|
+ this.listInCabinet = res1.data.records;
|
|
|
+
|
|
|
+ const data1 = {
|
|
|
+ materialsCabinetId: this.queryParams.materialsCabinetId
|
|
|
+ };
|
|
|
+
|
|
|
+ const res2 = await getExMaterials(data1);
|
|
|
+ this.listInCabinet = [...this.listInCabinet, ...res2.data];
|
|
|
+ console.log(this.listInCabinet, '柜子内的数据demo2');
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error fetching data:', error);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ getMaterialsOutOfCabinet() {
|
|
|
+ this.queryParams.loanState = '0' // 设置查询条件为物资柜外
|
|
|
+
|
|
|
+ const data = {
|
|
|
+ current: 1,
|
|
|
+ size: -1,
|
|
|
+ loanState: '0'
|
|
|
+ }
|
|
|
+ listMaterials(data).then((res) => {
|
|
|
+ // item.status!=='3'这个判断的意思是放错柜子的数据不显示的柜子外 因为异常数据以及放在柜子里了 item.materialsCabinetId不显示未绑定柜子的 item.materialsCabinetId不显示绑定柜子是0的
|
|
|
+ this.listOutOfCabinet = res.data.records.filter((item) => {
|
|
|
+ return item.materialsCabinetId != null && item.materialsCabinetId !== '0' && item.status !== '3'
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ },
|
|
|
+ // 初始化Konva舞台
|
|
|
+ initKonva() {
|
|
|
+ this.stage = new Konva.Stage({
|
|
|
+ container: this.$refs.container,
|
|
|
+ width: 1600,
|
|
|
+ height: 1000
|
|
|
+ })
|
|
|
+
|
|
|
+ this.bgLayer = new Konva.Layer()
|
|
|
+ const bgImage = new Image()
|
|
|
+ bgImage.src = require('@/assets/images/table.png')
|
|
|
+ bgImage.onload = () => {
|
|
|
+ const konvaImage = new Konva.Image({
|
|
|
+ x: 600,
|
|
|
+ y: 25,
|
|
|
+ image: bgImage,
|
|
|
+ width: 500,
|
|
|
+ height: 700,
|
|
|
+ draggable: false
|
|
|
+ })
|
|
|
+ this.bgLayer.add(konvaImage)
|
|
|
+ this.bgLayer.draw()
|
|
|
+ }
|
|
|
+ this.stage.add(this.bgLayer)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 清除Konva图层中的所有物资元素
|
|
|
+ clearMaterialsFromLayer() {
|
|
|
+ if (!this.bgLayer) return
|
|
|
+ const materialNodes = this.bgLayer.find('.material')
|
|
|
+ console.log('清除物资:', materialNodes)
|
|
|
+ materialNodes.forEach(node => node.destroy()) // 清除已渲染的物资元素
|
|
|
+ this.materialElements = [] // 清空已存储的物资图标对象
|
|
|
+ this.bgLayer.draw() // 重新绘制图层
|
|
|
+ },
|
|
|
+
|
|
|
+ // 物资拖动结束时的处理
|
|
|
+ handleDragEnd(e) {
|
|
|
+ const materialId = e.target.getAttr('materialId') // 获取物资ID
|
|
|
+ const position = e.target.getClientRect() // 获取物资当前的位置信息
|
|
|
+ const material = e.target.getAttr('material') // 获取物资对象
|
|
|
+ console.log(material, '物资移动')
|
|
|
+ const isInCabinet = material.inCabinet // 物资是否在柜子内
|
|
|
+
|
|
|
+ selectMaterialsById(material.materialsId).then((res) => {
|
|
|
+ console.log(res, '一大啊啊啊是')
|
|
|
+ const originalCabinetId = res.data.materialsCabinetId//原来的柜子ID
|
|
|
+ const currentCabinetId = this.queryParams.materialsCabinetId // 归还目标柜子ID
|
|
|
+ console.log(originalCabinetId, currentCabinetId, 'originalCabinetId')
|
|
|
+
|
|
|
+ if (!currentCabinetId || position.x < 600 || position.x > 1100 || position.y < 25 || position.y > 725) {
|
|
|
+ // **物资移出柜子**
|
|
|
+ if (isInCabinet) {
|
|
|
+ console.log('1--------')
|
|
|
+ this.materialsToUpdate.push({
|
|
|
+ materialsId: materialId,
|
|
|
+ loanState: 0, // "借出"
|
|
|
+ loanUserId: 106
|
|
|
+ })
|
|
|
+ material.inCabinet = false // 更新状态
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // **物资归还到柜子**
|
|
|
+ if (!isInCabinet && originalCabinetId === currentCabinetId) {
|
|
|
+ console.log('2--------')
|
|
|
+ // **物资从外部归还**
|
|
|
+ this.materialsToUpdate.push({
|
|
|
+ materialsId: materialId,
|
|
|
+ loanState: 1, // "归还"
|
|
|
+ restitutionToId: currentCabinetId,
|
|
|
+ restitutionUserId: 106
|
|
|
+ })
|
|
|
+ material.inCabinet = true
|
|
|
+ material.materialsCabinetId = currentCabinetId // 更新物资的柜子ID
|
|
|
+ } else if (originalCabinetId !== currentCabinetId) {
|
|
|
+ console.log('3--------')
|
|
|
+ // **用户确认变更柜子**
|
|
|
+ this.materialsToUpdate.push({
|
|
|
+ materialsId: materialId,
|
|
|
+ loanState: 1,
|
|
|
+ restitutionToId: currentCabinetId,
|
|
|
+ restitutionUserId: 106
|
|
|
+ })
|
|
|
+ material.materialsCabinetId = currentCabinetId // 更新柜子ID
|
|
|
+ this.bgLayer.draw()
|
|
|
+ } else {
|
|
|
+ // **物资仍在同一个柜子内**
|
|
|
+ console.log('物资仍在同一个柜子内')
|
|
|
+ // 如果需要,可以在这里添加一些逻辑
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('获取物资信息失败:', error)
|
|
|
+ // 处理错误情况
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 将物资添加到Konva图层
|
|
|
+ addMaterialsToLayer() {
|
|
|
+ if (!this.bgLayer) return
|
|
|
+
|
|
|
+ const itemWidth = 60
|
|
|
+ const itemHeight = 60
|
|
|
+ const spacing = 40
|
|
|
+
|
|
|
+ // 清除之前的物资元素
|
|
|
+ this.clearMaterialsFromLayer()
|
|
|
+
|
|
|
+ // 渲染柜内物资
|
|
|
+ console.log(this.listInCabinet,'物资柜内部数据')
|
|
|
+ this.listInCabinet.forEach((material, index) => {
|
|
|
+ const x = 720 + (index % 3) * (itemWidth + spacing)
|
|
|
+ const y = 120 + Math.floor(index / 3) * (itemHeight + spacing)
|
|
|
+
|
|
|
+ const materialImage = new Image()
|
|
|
+ materialImage.src = material.materialsTypeIcon
|
|
|
+ materialImage.onload = () => {
|
|
|
+ const group = new Konva.Group({
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ draggable: this.doorOpen, // 初始时根据 doorOpen 状态设置可拖拽
|
|
|
+ name: 'material',
|
|
|
+ materialId: material.materialsId,
|
|
|
+ material: material
|
|
|
+ })
|
|
|
+
|
|
|
+ const konvaMaterialImage = new Konva.Image({
|
|
|
+ image: materialImage,
|
|
|
+ width: itemWidth,
|
|
|
+ height: itemHeight
|
|
|
+ })
|
|
|
+
|
|
|
+ const text = new Konva.Text({
|
|
|
+ x: 0,
|
|
|
+ y: itemHeight + 5,
|
|
|
+ text: material.materialsName,
|
|
|
+ fontSize: 12,
|
|
|
+ fill: 'black',
|
|
|
+ align: 'center',
|
|
|
+ width: itemWidth
|
|
|
+ })
|
|
|
+
|
|
|
+ group.add(konvaMaterialImage)
|
|
|
+ group.add(text)
|
|
|
+
|
|
|
+ // 给物资设置初始的柜内状态
|
|
|
+ material.inCabinet = true // 设置物资最初处于柜子内
|
|
|
+
|
|
|
+ group.on('dragend', this.handleDragEnd) // 添加dragend事件监听
|
|
|
+
|
|
|
+ this.bgLayer.add(group)
|
|
|
+ this.bgLayer.draw()
|
|
|
+ this.materialElements.push(group)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 渲染柜外物资
|
|
|
+ this.listOutOfCabinet.forEach((material, index) => {
|
|
|
+ const x = 1200 + (index % 3) * (itemWidth + spacing) // 左侧显示柜外物资
|
|
|
+ const y = 120 + Math.floor(index / 3) * (itemHeight + spacing)
|
|
|
+
|
|
|
+ const materialImage = new Image()
|
|
|
+ materialImage.src = material.materialsTypeIcon
|
|
|
+ materialImage.onload = () => {
|
|
|
+ const group = new Konva.Group({
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ draggable: this.doorOpen, // 初始时设为可拖拽
|
|
|
+ name: 'material',
|
|
|
+ materialId: material.materialsId,
|
|
|
+ material: material
|
|
|
+ })
|
|
|
+
|
|
|
+ const konvaMaterialImage = new Konva.Image({
|
|
|
+ image: materialImage,
|
|
|
+ width: itemWidth,
|
|
|
+ height: itemHeight
|
|
|
+ })
|
|
|
+
|
|
|
+ const text = new Konva.Text({
|
|
|
+ x: 0,
|
|
|
+ y: itemHeight + 5,
|
|
|
+ text: material.materialsName,
|
|
|
+ fontSize: 12,
|
|
|
+ fill: 'black',
|
|
|
+ align: 'center',
|
|
|
+ width: itemWidth
|
|
|
+ })
|
|
|
+
|
|
|
+ group.add(konvaMaterialImage)
|
|
|
+ group.add(text)
|
|
|
+
|
|
|
+ // 给物资设置初始的柜外状态
|
|
|
+ material.inCabinet = false // 设置物资最初处于柜子外
|
|
|
+
|
|
|
+ group.on('dragend', this.handleDragEnd) // 添加dragend事件监听
|
|
|
+
|
|
|
+ this.bgLayer.add(group)
|
|
|
+ this.bgLayer.draw()
|
|
|
+ this.materialElements.push(group)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+// 监听 doorOpen 状态变化时更新物资的 draggable 状态
|
|
|
+ updateDraggableStatus() {
|
|
|
+ this.materialElements.forEach(group => {
|
|
|
+ group.draggable(this.doorOpen) // 动态更新 draggable 状态
|
|
|
+ })
|
|
|
+ this.bgLayer.draw()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 批量更新物资状态
|
|
|
+ updateMaterialsBatch() {
|
|
|
+ const data={
|
|
|
+ loanFromId:this.queryParams.materialsCabinetId
|
|
|
+ }
|
|
|
+ updateCabinetOpenTimeout(data).then((res)=>{
|
|
|
+ console.log(res)
|
|
|
+ if(res.data){
|
|
|
+ this.$message.success('柜门异常解除')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (this.materialsToUpdate.length === 0) return // 如果没有需要更新的物资,直接返回
|
|
|
+
|
|
|
+ updateIsMaterialById(this.materialsToUpdate).then(response => {
|
|
|
+ if (response.data) {
|
|
|
+ this.$message.success('物资更新成功')
|
|
|
+ this.materialsToUpdate = [] // 清空需要更新的物资列表
|
|
|
+ } else {
|
|
|
+ this.$message.error('物资更新失败')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.mapBox {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ //background-color: pink;
|
|
|
+}
|
|
|
+</style>
|