You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
883 lines
30 KiB
883 lines
30 KiB
<template>
|
|
<div class="app-container" style="position: relative; height: 770px; background-color: #fff;">
|
|
<div class="position-top" style="display: flex; justify-content: space-between;">
|
|
<div class="position-top-left">
|
|
<el-select
|
|
ref="selectRef"
|
|
v-model="selectedValue"
|
|
placeholder="请选择"
|
|
style="width: 250px;"
|
|
@visible-change="handleVisibleChange"
|
|
>
|
|
<i slot="prefix" class="el-input__icon el-icon-location" />
|
|
<el-option value="" style="display: none;" />
|
|
<div class="tree-dropdown">
|
|
<el-tree
|
|
ref="treeRef"
|
|
:data="regionTreeData"
|
|
:props="treeProps"
|
|
node-key="id"
|
|
default-expand-all
|
|
:expand-on-click-node="false"
|
|
@node-click="handleTreeNodeClick"
|
|
>
|
|
<span slot-scope="{ node, data }" class="custom-tree-node">
|
|
<span v-if="data.fondsId" style="font-weight: bold;">
|
|
<i class="iconfont icon-gongsi" />
|
|
{{ data.label }}
|
|
</span>
|
|
<span v-else-if="data.floorId">
|
|
<i class="iconfont icon-duolouceng" />
|
|
{{ data.label }}
|
|
</span>
|
|
<span v-else>
|
|
<i class="iconfont icon-hangzhengquyuguanli" />
|
|
{{ data.label }}
|
|
</span>
|
|
</span>
|
|
</el-tree>
|
|
</div>
|
|
</el-select>
|
|
<!-- v-if="bindAllRackList.length !== 0" -->
|
|
<el-card class="box-card shelf-bind-card">
|
|
<ul class="shelf-bind-tab">
|
|
<li :class="{ active: bindStatus === 'bound' }" @click="switchBindStatus('bound')">已绑定({{ boundShelfList.length }})</li>
|
|
<li :class="{ active: bindStatus === 'unbound' }" @click="switchBindStatus('unbound')">未绑定({{ unboundShelfList.length }})</li>
|
|
</ul>
|
|
<ul class="shelf-bind-list">
|
|
<li v-for="item in (bindStatus === 'bound' ? boundShelfList : unboundShelfList)" :key="item.id">
|
|
<span>{{ item.id }}</span>
|
|
<p>{{ item.code }}</p>
|
|
</li>
|
|
</ul>
|
|
</el-card>
|
|
</div>
|
|
<div v-if="is3DMap" class="position-top-middle">
|
|
<el-card class="box-card">
|
|
<el-form ref="form" :model="form" label-width="100px">
|
|
<el-form-item label="架位筛选" prop="name">
|
|
<el-select v-model="form.code1" style="width: 190px;" @change="changeShelfToModel">
|
|
<el-option
|
|
v-for="(item,index) in options1"
|
|
:key="index"
|
|
:label="item.label"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
<el-select v-model="form.layerVal" size="small" placeholder="书架排列表" class="filter-item" style="width: 140px;" value-key="id" @change="changeShelfGetGrid">
|
|
<el-option v-for="item in layerOptions" :key="item.id" :label="item.name" :value="item" />
|
|
</el-select>
|
|
<el-select v-model="form.toward" style="width: 80px;" :disabled="towardDisabled">
|
|
<el-option
|
|
v-for="(item,index) in abOptions"
|
|
:key="index"
|
|
:label="item.name"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
<el-select v-model="form.shelfVal" size="small" placeholder="架列表" class="filter-item" style="width: 100px;">
|
|
<el-option v-for="item in rackOptions" :key="item.id" :label="item.name" :value="item.id" />
|
|
</el-select>
|
|
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="getInitShelfGridByShelfId()" />
|
|
</el-form-item>
|
|
</el-form>
|
|
<div v-if="filterShelfList.length !== 0" class="filter-shelf-list">
|
|
<el-tag v-for="(item,index) in filterShelfList" :key="index" type="success">{{ item.gridName }}</el-tag>
|
|
</div>
|
|
<div class="filter-model-select">
|
|
<div class="model-select-style">已选定位:模型ID【{{ currentFid }}】</div>
|
|
<div class="model-select-style">已选架位:<span>{{ filterShelfList.length }}</span></div>
|
|
<el-button class="filter-item filter-search" size="mini" type="success"><i class="iconfont icon-bangding" />绑定</el-button>
|
|
</div>
|
|
</el-card>
|
|
</div>
|
|
<div class="position-top-right">
|
|
<!-- v-if="bindAllInquiryList.length !== 0" -->
|
|
<el-card class="box-card">
|
|
<div class="inquiry-machine-bind-top">
|
|
<h4>查询机绑定</h4>
|
|
<div class="inquiry-machine-bind-params">
|
|
<span
|
|
:style="{ color: inquiryFilterStatus === 'all' || inquiryFilterStatus === 'bound' ? 'rgb(64, 196, 140)' : 'rgb(153, 153, 153)', fontWeight: inquiryFilterStatus === 'all' || inquiryFilterStatus === 'bound' ? 'bold' : 'normal', cursor: 'pointer' }"
|
|
@click="inquiryFilterStatus = inquiryFilterStatus === 'bound' ? 'all' : 'bound'"
|
|
>已绑 {{ inquiryList.filter(item => item.bound).length }}</span>
|
|
<span>/</span>
|
|
<span
|
|
:style="{ color: inquiryFilterStatus === 'all' || inquiryFilterStatus === 'unbound' ? 'rgb(237, 74, 65)' : 'rgb(153, 153, 153)', fontWeight: inquiryFilterStatus === 'all' || inquiryFilterStatus === 'unbound' ? 'bold' : 'normal', cursor: 'pointer' }"
|
|
@click="inquiryFilterStatus = inquiryFilterStatus === 'unbound' ? 'all' : 'unbound'"
|
|
>未绑 {{ inquiryList.filter(item => !item.bound).length }}</span>
|
|
</div>
|
|
</div>
|
|
<ul class="shelf-bind-list" style="height: 190px;">
|
|
<li v-for="item in filteredInquiryList" :key="item.id">
|
|
<span>{{ item.id }}</span>
|
|
<p>{{ item.name }}</p>
|
|
<span
|
|
:style="{ color: item.bound ? 'rgb(64, 196, 140)' : 'rgb(3, 72, 243)', cursor: 'pointer' }"
|
|
@click="item.bound ? handleInquiryLocate(item) : handleInquiryBind(item)"
|
|
>{{ item.bound ? '定位' : '绑定' }}</span>
|
|
</li>
|
|
</ul>
|
|
</el-card>
|
|
</div>
|
|
</div>
|
|
<PreviewMap v-if="is3DMap" ref="map" :map-data="mapData" :to-shlef="true" :area-fid="currentFid" @refreshAreaFid="handleAreaFid" />
|
|
<el-empty v-else description="当前区域非3D模式的地图" style="height: 100%;" />
|
|
<!-- 模型信息面板 -->
|
|
<div v-if="currentFid" class="model-info-panel">
|
|
<div class="model-info-content">
|
|
<div class="model-info-item">
|
|
<span class="model-info-label">当前选中:</span>
|
|
<span class="model-info-value">模型ID【{{ currentFid }}】</span>
|
|
</div>
|
|
<div v-if="bindData.rackCount > 0" class="model-info-item">
|
|
<span class="model-info-label">绑定架位:</span>
|
|
<span class="model-info-value">{{ bindData.rackCount }} / 个</span>
|
|
<el-button type="text" class="model-info-link" @click="showDetail('rack')">查看详情</el-button>
|
|
</div>
|
|
<div v-if="bindData.inquiryCount > 0" class="model-info-item">
|
|
<span class="model-info-label">绑定查询机:</span>
|
|
<span class="model-info-value">{{ bindData.inquiryCount }} / 个</span>
|
|
<el-button type="text" class="model-info-link" @click="showDetail('inquiry')">查看详情</el-button>
|
|
</div>
|
|
<div v-if="bindData.areaCount > 0" class="model-info-item">
|
|
<span class="model-info-label">绑定区域:</span>
|
|
<span class="model-info-value">{{ bindData.areaCount }} / 个</span>
|
|
<el-button type="text" class="model-info-link" @click="showDetail('area')">查看详情</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 详情对话框 -->
|
|
<el-dialog
|
|
:visible.sync="dialogVisible"
|
|
:title="dialogTitle"
|
|
width="500px"
|
|
append-to-body
|
|
:close-on-click-modal="false"
|
|
:modal-append-to-body="false"
|
|
>
|
|
<el-table :data="dialogType === 'rack' ? rackDetails : dialogType === 'inquiry' ? inquiryDetails : areaDetails" style="width: 100%" height="300px" max-height="300px">
|
|
<!-- 绑定架位详情表格 -->
|
|
<template v-if="dialogType === 'rack'">
|
|
<el-table-column prop="id" label="序号" width="80" />
|
|
<el-table-column prop="rack" label="架位" />
|
|
<el-table-column prop="name" label="名称" />
|
|
</template>
|
|
|
|
<!-- 绑定查询机详情表格 -->
|
|
<template v-else-if="dialogType === 'inquiry'">
|
|
<el-table-column prop="id" label="序号" width="80" />
|
|
<el-table-column prop="name" label="查询机名称" />
|
|
<el-table-column prop="ip" label="设备IP" />
|
|
</template>
|
|
|
|
<!-- 绑定区域详情表格 -->
|
|
<template v-else-if="dialogType === 'area'">
|
|
<el-table-column prop="id" label="序号" width="80" />
|
|
<el-table-column prop="code" label="区域编码" />
|
|
<el-table-column prop="name" label="区域名称" />
|
|
</template>
|
|
</el-table>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { FetchRegionTree } from '@/api/deviceVI/index'
|
|
import { FetchMapDetails } from '@/api/map/index'
|
|
import { FetchInitBookShelfList, FetchBookShelfDetails, FetchInitShelfGridByShelfId } from '@/api/shelf/index'
|
|
import PreviewMap from '../map3d/map'
|
|
export default {
|
|
name: 'Shelf3dPosition',
|
|
components: {
|
|
PreviewMap
|
|
},
|
|
data() {
|
|
return {
|
|
selectedValue: '',
|
|
regionTreeData: [],
|
|
treeProps: { label: 'label', children: 'children' },
|
|
form: {
|
|
code1: 0,
|
|
layerVal: null,
|
|
toward: null,
|
|
shelfVal: null
|
|
},
|
|
selectList: [],
|
|
options1: [
|
|
{ value: 0, label: '按 “排-单面-架” 筛选' },
|
|
{ value: 1, label: '按 “排-双面-架” 筛选' },
|
|
{ value: 2, label: '按 “排-单面” 筛选' },
|
|
{ value: 3, label: '按 “排-双面” 筛选' }
|
|
],
|
|
layerOptions: [],
|
|
abOptions: [],
|
|
mapData: {},
|
|
towardDisabled: false,
|
|
currentTreeNode: null,
|
|
is3DMap: false,
|
|
rackOptions: [],
|
|
bindAllRackList: [],
|
|
bindAllInquiryList: [],
|
|
filterShelfList: [],
|
|
currentFid: null,
|
|
// 绑定状态切换
|
|
bindStatus: 'bound', // 'bound' | 'unbound'
|
|
// 查询机筛选状态
|
|
inquiryFilterStatus: 'all', // 'all' | 'bound' | 'unbound'
|
|
// 模拟数据
|
|
boundShelfList: [
|
|
{ id: 1, code: 'FTZN-03-001-A-01-1' },
|
|
{ id: 2, code: 'FTZN-03-001-A-01-2' },
|
|
{ id: 3, code: 'FTZN-03-001-A-01-3' },
|
|
{ id: 4, code: 'FTZN-03-001-A-01-4' },
|
|
{ id: 5, code: 'FTZN-03-001-A-01-5' },
|
|
{ id: 6, code: 'FTZN-03-001-A-01-6' },
|
|
{ id: 7, code: 'FTZN-03-001-A-01-7' },
|
|
{ id: 8, code: 'FTZN-03-001-A-01-8' }
|
|
],
|
|
unboundShelfList: [
|
|
{ id: 1, code: 'FTZN-03-001-A-01-9' },
|
|
{ id: 2, code: 'FTZN-03-001-A-01-10' }
|
|
],
|
|
// 查询机数据
|
|
inquiryList: [
|
|
{ id: 1, name: '查询机001', bound: true, modelId: '7069948641322078208' },
|
|
{ id: 2, name: '查询机002', bound: false },
|
|
{ id: 3, name: '查询机003', bound: false },
|
|
{ id: 4, name: '查询机004', bound: false },
|
|
{ id: 5, name: '查询机005', bound: false },
|
|
{ id: 6, name: '查询机006', bound: false },
|
|
{ id: 7, name: '查询机007', bound: false },
|
|
{ id: 8, name: '查询机008', bound: false }
|
|
],
|
|
bindData: {
|
|
rackCount: 0,
|
|
inquiryCount: 0,
|
|
areaCount: 0
|
|
},
|
|
modelScreenPosition: null,
|
|
// 对话框相关
|
|
dialogVisible: false,
|
|
dialogType: '', // 'rack' | 'inquiry' | 'area'
|
|
dialogTitle: '',
|
|
// 模拟数据
|
|
rackDetails: [
|
|
{ id: 1, rack: 'FTZN-03-001-A-01-1', name: '架位1' },
|
|
{ id: 2, rack: 'FTZN-03-001-A-01-2', name: '架位2' },
|
|
{ id: 3, rack: 'FTZN-03-001-A-01-3', name: '架位3' },
|
|
{ id: 4, rack: 'FTZN-03-001-A-01-4', name: '架位4' },
|
|
{ id: 5, rack: 'FTZN-03-001-A-01-5', name: '架位5' },
|
|
{ id: 6, rack: 'FTZN-03-001-A-01-6', name: '架位6' },
|
|
{ id: 1, rack: 'FTZN-03-001-A-01-1', name: '架位1' },
|
|
{ id: 2, rack: 'FTZN-03-001-A-01-2', name: '架位2' },
|
|
{ id: 3, rack: 'FTZN-03-001-A-01-3', name: '架位3' },
|
|
{ id: 4, rack: 'FTZN-03-001-A-01-4', name: '架位4' },
|
|
{ id: 5, rack: 'FTZN-03-001-A-01-5', name: '架位5' },
|
|
{ id: 6, rack: 'FTZN-03-001-A-01-6', name: '架位6' }
|
|
],
|
|
inquiryDetails: [
|
|
{ id: 1, name: '查询机001', ip: '192.168.1.100' }
|
|
],
|
|
areaDetails: [
|
|
{ id: 1, code: '03', name: '区域1' }
|
|
]
|
|
}
|
|
},
|
|
computed: {
|
|
filteredInquiryList() {
|
|
if (this.inquiryFilterStatus === 'bound') {
|
|
return this.inquiryList.filter(item => item.bound)
|
|
} else if (this.inquiryFilterStatus === 'unbound') {
|
|
return this.inquiryList.filter(item => !item.bound)
|
|
} else {
|
|
return this.inquiryList
|
|
}
|
|
}
|
|
},
|
|
created() {
|
|
FetchRegionTree().then(res => {
|
|
this.regionTreeData = [this.transformData(res)]
|
|
console.log(this.regionTreeData)
|
|
this.$nextTick(() => {
|
|
// 从localStorage获取并自动选中对应的节点
|
|
this.autoSelectFromLocalStorage()
|
|
|
|
// 如果没有localStorage数据,选择第一个有子节点的区域
|
|
if (!this.regionTreeData[0].children?.length) return
|
|
const targetFloor = this.regionTreeData[0].children.find(floor => floor.children?.length > 0)
|
|
if (targetFloor?.children?.length && !this.currentTreeNode) {
|
|
const firstRegion = targetFloor.children[0]
|
|
this.$refs.treeRef.setCurrentKey(firstRegion.id)
|
|
this.handleTreeNodeClick(firstRegion)
|
|
}
|
|
})
|
|
}).catch(() => {
|
|
})
|
|
},
|
|
mounted() {
|
|
this.changeShelfToModel(this.options1[0]?.value)
|
|
},
|
|
methods: {
|
|
getInitShelfGridByShelfId() {
|
|
// rowType 1 单 2 双
|
|
// toward 1 A面 2 B面
|
|
// shelfType 1 '始终最左边为第1架(S型排架)'
|
|
// shelfType 2 'A面最左为第1架(B面最左为最后1架)'
|
|
// shelfType 3 'B面最左为第1架(A面最左为最后1架)'
|
|
// floorType 1 '最顶层为第一层(从上至下)'
|
|
// floorType 2 '最底层为第一层(从下至上)'
|
|
console.log(' this.form', this.form)
|
|
FetchInitShelfGridByShelfId({ 'shelfId': this.form.layerVal.id, 'toward': this.form.toward }).then(res => {
|
|
console.log('FetchInitShelfGridByShelfId', res)
|
|
this.filterShelfList = res
|
|
}).catch(() => {
|
|
})
|
|
},
|
|
// 从localStorage自动选择对应的节点和架位
|
|
autoSelectFromLocalStorage() {
|
|
try {
|
|
const shelfDataStr = localStorage.getItem('shelf3dPositionRow')
|
|
if (!shelfDataStr) return
|
|
|
|
const shelfData = JSON.parse(shelfDataStr)
|
|
console.log('shelf3dPositionRow', shelfData)
|
|
|
|
// 1. 递归查找对应的区域节点
|
|
const targetRegionNode = this.findRegionNodeByShelfData(this.regionTreeData, shelfData)
|
|
if (targetRegionNode) {
|
|
// 选中树形节点
|
|
this.$refs.treeRef.setCurrentKey(targetRegionNode.id)
|
|
// 触发节点点击事件
|
|
this.handleTreeNodeClick(targetRegionNode)
|
|
|
|
// 2. 自动填充表单值
|
|
this.$nextTick(() => {
|
|
this.autoFillForm(shelfData)
|
|
})
|
|
} else {
|
|
console.warn('未找到对应的区域节点', shelfData)
|
|
}
|
|
} catch (error) {
|
|
console.error('自动选择节点失败', error)
|
|
}
|
|
},
|
|
|
|
// 递归查找对应的区域节点(根据floorName和regionName)
|
|
findRegionNodeByShelfData(treeData, shelfData) {
|
|
for (const node of treeData) {
|
|
// 查找楼层节点
|
|
if (node.floorId && node.raw?.floorName === shelfData.floorName) {
|
|
// 遍历楼层下的区域节点
|
|
if (node.children && node.children.length) {
|
|
const regionNode = node.children.find(
|
|
region => region.raw?.regionName === shelfData.regionName
|
|
)
|
|
if (regionNode) {
|
|
return regionNode
|
|
}
|
|
}
|
|
}
|
|
|
|
// 递归查找子节点
|
|
if (node.children && node.children.length) {
|
|
const result = this.findRegionNodeByShelfData(node.children, shelfData)
|
|
if (result) return result
|
|
}
|
|
}
|
|
return null
|
|
},
|
|
|
|
// 根据架位数据自动填充表单
|
|
autoFillForm(shelfData) {
|
|
// 设置朝向
|
|
this.form.toward = shelfData.toward
|
|
|
|
// 根据rowType设置筛选类型
|
|
if (shelfData.rowType === 1) {
|
|
// 单面
|
|
this.form.code1 = shelfData.shelfShelf > 1 ? 0 : 2 // 有架数选"排-单面-架",否则选"排-单面"
|
|
} else if (shelfData.rowType === 2) {
|
|
// 双面
|
|
this.form.code1 = shelfData.shelfShelf > 1 ? 1 : 3 // 有架数选"排-双面-架",否则选"排-双面"
|
|
this.towardDisabled = true
|
|
}
|
|
|
|
// 更新筛选类型对应的朝向选项
|
|
this.changeShelfToModel(this.form.code1)
|
|
|
|
// 在layerOptions加载完成后选择对应的排
|
|
const timer = setInterval(() => {
|
|
if (this.layerOptions.length > 0) {
|
|
clearInterval(timer)
|
|
// 查找对应的排
|
|
const targetLayer = this.layerOptions.find(item => item.id === shelfData.shelfId)
|
|
if (targetLayer) {
|
|
this.form.layerVal = targetLayer
|
|
// 触发架列表加载(包含联动逻辑)
|
|
this.changeShelfGetGrid(targetLayer)
|
|
}
|
|
}
|
|
}, 100)
|
|
},
|
|
|
|
transformData(data) {
|
|
const rootNode = {
|
|
id: data.fondsId,
|
|
fondsId: data.fondsId,
|
|
label: data.fondsName,
|
|
raw: { ...data },
|
|
children: data.floors.map(floor => {
|
|
const floorNode = {
|
|
id: floor.id,
|
|
floorId: floor.id,
|
|
label: floor.floorName,
|
|
raw: { ...floor },
|
|
children: floor.regions.map(region => {
|
|
return {
|
|
id: region.id,
|
|
regionId: region.id,
|
|
label: region.regionName,
|
|
parentFloorId: floor.id,
|
|
raw: { ...region }
|
|
}
|
|
})
|
|
}
|
|
return floorNode
|
|
})
|
|
}
|
|
return rootNode
|
|
},
|
|
|
|
handleTreeNodeClick(nodeData) {
|
|
this.form.layerVal = null
|
|
this.form.shelfVal = null // 清空架位选择
|
|
this.rackOptions = [] // 清空架位列表
|
|
this.currentTreeNode = nodeData.raw
|
|
console.log('handleTreeNodeClick', nodeData)
|
|
const currentNode = this.$refs.treeRef.getNode(nodeData)
|
|
console.log('currentNode', currentNode)
|
|
if (currentNode.level === 1) {
|
|
return
|
|
}
|
|
const parentNode = currentNode.parent
|
|
const parentLabel = parentNode && parentNode.data && parentNode.data.label
|
|
? parentNode.data.label
|
|
: ''
|
|
|
|
this.selectedValue = parentLabel
|
|
? `${parentLabel} - ${nodeData.label}`
|
|
: nodeData.label
|
|
this.$refs.selectRef.blur()
|
|
this.getInitBookShelfList(currentNode.data)
|
|
|
|
if (nodeData.raw.mapType === 1) {
|
|
this.is3DMap = false
|
|
} else {
|
|
this.is3DMap = true
|
|
this.getMapDetails(nodeData.raw.mapId)
|
|
}
|
|
},
|
|
|
|
getMapDetails(id) {
|
|
const params = {
|
|
'id': id
|
|
}
|
|
FetchMapDetails(params).then(res => {
|
|
this.mapData = res
|
|
console.log('this.mapData', this.mapData)
|
|
this.$nextTick(() => {
|
|
if (this.$refs.map) {
|
|
this.$refs.map.dispose()
|
|
}
|
|
if (this.currentTreeNode.mapLevel) {
|
|
this.$refs.map.level = Number(this.currentTreeNode.mapLevel)
|
|
} else {
|
|
this.$refs.map.level = 1
|
|
}
|
|
if (this.currentTreeNode.fid) {
|
|
this.$refs.map.areaFid = this.currentTreeNode.fid
|
|
// this.handleAreaFid(this.currentTreeNode.fid)
|
|
} else {
|
|
this.$refs.map.areaFid = null
|
|
this.currentFid = null
|
|
}
|
|
this.$refs.map.initMap()
|
|
})
|
|
}).catch(() => {
|
|
})
|
|
},
|
|
|
|
changeShelfGetGrid(val) {
|
|
if (!val) {
|
|
this.rackOptions = []
|
|
this.form.shelfVal = null
|
|
return
|
|
}
|
|
|
|
FetchBookShelfDetails({ 'shelfId': val.id }).then(res => {
|
|
this.rackOptions = []
|
|
const start = parseInt(res.startShelf) || 1
|
|
const end = start + res.shelfShelf - 1
|
|
for (let i = start; i <= end; i++) {
|
|
this.rackOptions.push({
|
|
id: i,
|
|
name: `${i.toString().padStart(2, '0')}架`
|
|
})
|
|
}
|
|
|
|
// 1. 根据选中排的rowType(单面/双面)自动设置筛选类型(code1)
|
|
if (val.rowType === 1) { // 单面
|
|
// 根据是否有多个架位,选择对应的筛选类型
|
|
this.form.code1 = res.shelfShelf > 1 ? 0 : 2
|
|
// 0: 按 "排-单面-架" 筛选 | 2: 按 "排-单面" 筛选
|
|
} else if (val.rowType === 2) { // 双面
|
|
this.form.code1 = res.shelfShelf > 1 ? 1 : 3
|
|
// 1: 按 "排-双面-架" 筛选 | 3: 按 "排-双面" 筛选
|
|
}
|
|
|
|
this.changeShelfToModel(this.form.code1)
|
|
|
|
// 4. 默认选中第一个架位(可选,根据业务需求调整)
|
|
if (this.rackOptions.length > 0) {
|
|
this.form.shelfVal = this.rackOptions[0].id
|
|
} else {
|
|
this.form.shelfVal = null
|
|
}
|
|
}).catch(() => {
|
|
this.rackOptions = []
|
|
this.form.shelfVal = null
|
|
})
|
|
},
|
|
|
|
// 微调:筛选类型改变时,仅当当前朝向无效时才重置
|
|
changeShelfToModel(val) {
|
|
if (val === 1 || val === 3) {
|
|
this.towardDisabled = true
|
|
this.abOptions = [
|
|
{ value: 1, name: '双面' }
|
|
]
|
|
} else {
|
|
this.towardDisabled = false
|
|
this.abOptions = [
|
|
{ value: 1, name: 'A面' },
|
|
{ value: 2, name: 'B面' }
|
|
]
|
|
}
|
|
// 只有当当前朝向不在可选范围内时,才重置朝向
|
|
const hasCurrentToward = this.abOptions.some(item => item.value === this.form.toward)
|
|
if (!hasCurrentToward) {
|
|
this.form.toward = this.abOptions[0]?.value
|
|
}
|
|
},
|
|
|
|
handleVisibleChange(visible) {
|
|
// 下拉关闭时的额外逻辑(可选)
|
|
},
|
|
|
|
getInitBookShelfList(data) {
|
|
const params = { 'floorId': data.parentFloorId, 'regionId': data.regionId }
|
|
FetchInitBookShelfList(params).then(res => {
|
|
if (res.content.length === 0) {
|
|
this.layerOptions = []
|
|
this.rackOptions = []
|
|
} else {
|
|
this.layerOptions = res.content.map(item => {
|
|
return {
|
|
name: item.shelfName,
|
|
id: item.shelfId,
|
|
toward: item.toward,
|
|
rowType: item.rowType
|
|
}
|
|
})
|
|
|
|
// 如果有localStorage数据,重新触发表单填充
|
|
const shelfDataStr = localStorage.getItem('shelf3dPositionRow')
|
|
if (shelfDataStr) {
|
|
this.autoFillForm(JSON.parse(shelfDataStr))
|
|
}
|
|
}
|
|
}).catch(() => {
|
|
})
|
|
},
|
|
|
|
handleAreaFid(areaFid) {
|
|
this.currentFid = areaFid
|
|
console.log('mapAreaFid', areaFid)
|
|
// 模拟获取绑定数据
|
|
this.fetchBindData(areaFid)
|
|
},
|
|
fetchBindData(fid) {
|
|
// 模拟异步请求
|
|
setTimeout(() => {
|
|
// 模拟数据,实际应该从后端接口获取
|
|
this.bindData = {
|
|
rackCount: 6, // 绑定架位数量
|
|
inquiryCount: 1, // 绑定查询机数量
|
|
areaCount: 1 // 绑定区域数量
|
|
}
|
|
}, 300)
|
|
},
|
|
// 显示详情对话框
|
|
showDetail(type) {
|
|
this.dialogType = type
|
|
switch (type) {
|
|
case 'rack':
|
|
this.dialogTitle = `绑定架位详情 - 绑定位置【${this.currentFid}】`
|
|
break
|
|
case 'inquiry':
|
|
this.dialogTitle = `绑定查询机详情 - 绑定位置【${this.currentFid}】`
|
|
break
|
|
case 'area':
|
|
this.dialogTitle = `绑定区域详情 - 绑定位置【${this.currentFid}】`
|
|
break
|
|
}
|
|
this.dialogVisible = true
|
|
},
|
|
// 切换绑定状态
|
|
switchBindStatus(status) {
|
|
this.bindStatus = status
|
|
// 这里后续可以添加后端接口调用,根据状态获取对应的数据
|
|
// 例如:
|
|
// if (status === 'bound') {
|
|
// this.fetchBoundShelfList()
|
|
// } else {
|
|
// this.fetchUnboundShelfList()
|
|
// }
|
|
},
|
|
// 处理查询机绑定
|
|
handleInquiryBind(item) {
|
|
this.$confirm('此操作将绑定所选查询机位置。<br>查询机一般作为3D地图导航的起点!<span>你是否还要继续?</span>', '提示', {
|
|
confirmButtonText: '继续',
|
|
cancelButtonText: '取消',
|
|
type: 'warning',
|
|
dangerouslyUseHTMLString: true
|
|
}).then(() => {
|
|
if (!this.currentFid) {
|
|
this.$message.warning('请先选择一个模型位置')
|
|
return
|
|
}
|
|
// 后续这里会调用后端接口进行绑定操作
|
|
console.log('绑定查询机:', item.name, '到位置:', this.currentFid)
|
|
// 模拟绑定成功
|
|
item.bound = true
|
|
item.modelId = this.currentFid
|
|
this.$message.success('绑定成功')
|
|
}).catch(err => {
|
|
console.log(err)
|
|
})
|
|
},
|
|
// 处理已绑定查询机的定位
|
|
handleInquiryLocate(item) {
|
|
if (!item.modelId) {
|
|
this.$message.warning('该查询机未绑定模型位置')
|
|
return
|
|
}
|
|
// 设置当前选中的FID,触发地图定位
|
|
this.currentFid = item.modelId
|
|
// 模拟获取绑定数据
|
|
this.fetchBindData(item.modelId)
|
|
// 调用地图组件的centerOnModel方法定位到指定模型
|
|
this.$nextTick(() => {
|
|
if (this.$refs.map) {
|
|
this.$refs.map.centerOnModel(item.modelId)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.tree-dropdown {
|
|
width: 250px;
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
}
|
|
.position-top{
|
|
position: absolute;
|
|
top: 10px;
|
|
left: 20px;
|
|
width: calc(100% - 40px);
|
|
z-index: 999;
|
|
}
|
|
::v-deep .el-tree{
|
|
.el-tree-node__children{
|
|
font-size: 14px;
|
|
.iconfont{
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.position-top-left,
|
|
.position-top-right{
|
|
width: 300px;
|
|
}
|
|
|
|
.shelf-bind-card{
|
|
width: 280px;
|
|
margin-top: 20px;
|
|
font-size: 16px;
|
|
.shelf-bind-tab{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
text-align: center;
|
|
align-items: center;
|
|
li{
|
|
width: 50%;
|
|
height: 40px;
|
|
line-height: 40px;
|
|
cursor: pointer;
|
|
background: #f5f5f5;
|
|
&.active{
|
|
background: #fff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.shelf-bind-list{
|
|
font-size: 14px;
|
|
margin-top: 8px;
|
|
height: 155px;
|
|
overflow-y: scroll;
|
|
li{
|
|
display: flex;
|
|
justify-content: flex-start;
|
|
line-height: 30px;
|
|
padding: 4px 10px;
|
|
span{
|
|
display: block;
|
|
width: 30px;
|
|
text-align: center;
|
|
}
|
|
p{
|
|
flex: 1;
|
|
padding-left: 20px;
|
|
}
|
|
&:hover{
|
|
background: #f5f5f5;
|
|
cursor: default;
|
|
}
|
|
}
|
|
}
|
|
|
|
.position-top-middle{
|
|
width: 900px;
|
|
.el-card{
|
|
padding:20px 0 10px 0;
|
|
}
|
|
}
|
|
.filter-shelf-list{
|
|
border-top: 1px solid #edeff3;
|
|
padding: 10px 10px 0 10px;
|
|
height: 96px;
|
|
overflow-y: scroll;
|
|
.el-tag{
|
|
margin-right: 5px;
|
|
cursor: pointer;
|
|
&:hover,
|
|
&.bind-selected{
|
|
background-color: #0348f3;
|
|
color: #fff;
|
|
border: 1px solid #0348f3;
|
|
}
|
|
}
|
|
}
|
|
.filter-model-select{
|
|
border-top: 1px solid #edeff3;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 10px 10px 0 10px;
|
|
margin-top: 10px;
|
|
.model-select-style{
|
|
font-weight: bold;
|
|
&:first-child{
|
|
flex: 1;
|
|
}
|
|
span{
|
|
display: inline-block;
|
|
width: 32px;
|
|
height: 32px;
|
|
line-height: 32px;
|
|
background-color: #2ecaac;
|
|
color: #fff;
|
|
text-align: center;
|
|
border-radius: 50%;
|
|
}
|
|
}
|
|
.el-button{
|
|
margin-left: 20px;
|
|
}
|
|
}
|
|
|
|
.inquiry-machine-bind-top{
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
color: #0c0e1e;
|
|
border-bottom: 1px solid #edeff3;
|
|
height: 40px;
|
|
line-height: 40px;
|
|
padding: 0 10px;
|
|
.inquiry-machine-bind-params{
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
|
|
/* 模型信息面板 */
|
|
.model-info-panel{
|
|
position: absolute;
|
|
top: 42%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
z-index: 1000;
|
|
background-color: rgba(0, 0, 0, 0.7);
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
color: #fff;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.5);
|
|
min-width: 300px;
|
|
}
|
|
|
|
.model-info-content{
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.model-info-item{
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.model-info-label{
|
|
font-weight: bold;
|
|
min-width: 100px;
|
|
}
|
|
|
|
.model-info-value{
|
|
flex: 1;
|
|
}
|
|
|
|
.model-info-link{
|
|
color: #409EFF !important;
|
|
font-size: 12px;
|
|
padding: 0 !important;
|
|
margin: 0 !important;
|
|
border: none !important;
|
|
}
|
|
|
|
.model-info-link:hover{
|
|
color: #66B1FF !important;
|
|
background-color: transparent !important;
|
|
}
|
|
.model-info-link:focus{
|
|
color: #66B1FF !important;
|
|
background-color: transparent !important;
|
|
}
|
|
</style>
|