|
|
@ -1,5 +1,5 @@ |
|
|
<template> |
|
|
<template> |
|
|
<div class="app-container" style="position: relative; height: 784px; background-color: #fff;"> |
|
|
|
|
|
|
|
|
<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" style="display: flex; justify-content: space-between;"> |
|
|
<div class="position-top-left"> |
|
|
<div class="position-top-left"> |
|
|
<el-select |
|
|
<el-select |
|
|
@ -38,15 +38,16 @@ |
|
|
</el-tree> |
|
|
</el-tree> |
|
|
</div> |
|
|
</div> |
|
|
</el-select> |
|
|
</el-select> |
|
|
<el-card v-if="bindAllRackList.length !== 0" class="box-card shelf-bind-card"> |
|
|
|
|
|
|
|
|
<!-- v-if="bindAllRackList.length !== 0" --> |
|
|
|
|
|
<el-card class="box-card shelf-bind-card"> |
|
|
<ul class="shelf-bind-tab"> |
|
|
<ul class="shelf-bind-tab"> |
|
|
<li class="active">已绑定(136)</li> |
|
|
|
|
|
<li>未绑定(2)</li> |
|
|
|
|
|
|
|
|
<li :class="{ active: bindStatus === 'bound' }" @click="switchBindStatus('bound')">已绑定({{ boundShelfList.length }})</li> |
|
|
|
|
|
<li :class="{ active: bindStatus === 'unbound' }" @click="switchBindStatus('unbound')">未绑定({{ unboundShelfList.length }})</li> |
|
|
</ul> |
|
|
</ul> |
|
|
<ul class="shelf-bind-list"> |
|
|
<ul class="shelf-bind-list"> |
|
|
<li v-for="(item,index) in 8" :key="index"> |
|
|
|
|
|
<span>{{ index+1 }}</span> |
|
|
|
|
|
<p>FTZN-03-001-A-01-1</p> |
|
|
|
|
|
|
|
|
<li v-for="item in (bindStatus === 'bound' ? boundShelfList : unboundShelfList)" :key="item.id"> |
|
|
|
|
|
<span>{{ item.id }}</span> |
|
|
|
|
|
<p>{{ item.code }}</p> |
|
|
</li> |
|
|
</li> |
|
|
</ul> |
|
|
</ul> |
|
|
</el-card> |
|
|
</el-card> |
|
|
@ -77,20 +78,12 @@ |
|
|
<el-select v-model="form.shelfVal" size="small" placeholder="架列表" class="filter-item" style="width: 100px;"> |
|
|
<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-option v-for="item in rackOptions" :key="item.id" :label="item.name" :value="item.id" /> |
|
|
</el-select> |
|
|
</el-select> |
|
|
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" /> |
|
|
|
|
|
|
|
|
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="getInitShelfGridByShelfId()" /> |
|
|
</el-form-item> |
|
|
</el-form-item> |
|
|
</el-form> |
|
|
</el-form> |
|
|
<div v-if="filterShelfList.length !== 0" class="filter-shelf-list"> |
|
|
<div v-if="filterShelfList.length !== 0" class="filter-shelf-list"> |
|
|
<el-tag v-for="(item,index) in filterShelfList" :key="index" type="success">{{ item.name }}</el-tag> |
|
|
|
|
|
<!-- <el-tag type="success">FTZN-03-001-A-01-2</el-tag> |
|
|
|
|
|
<el-tag type="success">FTZN-03-001-A-01-3</el-tag> |
|
|
|
|
|
<el-tag type="success">FTZN-03-001-A-01-4</el-tag> |
|
|
|
|
|
<el-tag type="success">FTZN-03-001-A-01-5</el-tag> |
|
|
|
|
|
<el-tag type="success">FTZN-03-001-A-01-6</el-tag> |
|
|
|
|
|
<el-tag type="success">FTZN-03-001-A-01-7</el-tag> |
|
|
|
|
|
<el-tag type="success">FTZN-03-001-A-01-8</el-tag> --> |
|
|
|
|
|
|
|
|
<el-tag v-for="(item,index) in filterShelfList" :key="index" type="success">{{ item.gridName }}</el-tag> |
|
|
</div> |
|
|
</div> |
|
|
<!-- v-if="currentFid && filterShelfList.length!==0" --> |
|
|
|
|
|
<div class="filter-model-select"> |
|
|
<div class="filter-model-select"> |
|
|
<div class="model-select-style">已选定位:模型ID【{{ currentFid }}】</div> |
|
|
<div class="model-select-style">已选定位:模型ID【{{ currentFid }}】</div> |
|
|
<div class="model-select-style">已选架位:<span>{{ filterShelfList.length }}</span></div> |
|
|
<div class="model-select-style">已选架位:<span>{{ filterShelfList.length }}</span></div> |
|
|
@ -99,35 +92,101 @@ |
|
|
</el-card> |
|
|
</el-card> |
|
|
</div> |
|
|
</div> |
|
|
<div class="position-top-right"> |
|
|
<div class="position-top-right"> |
|
|
<el-card v-if="bindAllInquiryList.length !== 0" class="box-card"> |
|
|
|
|
|
|
|
|
<!-- v-if="bindAllInquiryList.length !== 0" --> |
|
|
|
|
|
<el-card class="box-card"> |
|
|
<div class="inquiry-machine-bind-top"> |
|
|
<div class="inquiry-machine-bind-top"> |
|
|
<h4>查询机绑定</h4> |
|
|
<h4>查询机绑定</h4> |
|
|
<div class="inquiry-machine-bind-params"> |
|
|
<div class="inquiry-machine-bind-params"> |
|
|
<span style="color: rgb(3, 72, 243); font-weight: bold;">已绑 1</span> |
|
|
|
|
|
|
|
|
<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>/</span> |
|
|
<span style="color: rgb(237, 74, 65); font-weight: bold;">未绑 1</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> |
|
|
</div> |
|
|
</div> |
|
|
<ul class="shelf-bind-list" style="height: 190px;"> |
|
|
<ul class="shelf-bind-list" style="height: 190px;"> |
|
|
<li v-for="(item,index) in 8" :key="index"> |
|
|
|
|
|
<span>{{ index+1 }}</span> |
|
|
|
|
|
<p>查询机001</p> |
|
|
|
|
|
<span style="color: rgb(3, 72, 243); cursor: pointer;">绑定</span> |
|
|
|
|
|
<!-- <span style="color: #2ecaac; cursor: pointer;">定位</span> --> |
|
|
|
|
|
|
|
|
<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> |
|
|
</li> |
|
|
</ul> |
|
|
</ul> |
|
|
</el-card> |
|
|
</el-card> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<PreviewMap v-if="is3DMap" ref="map" :map-data="mapData" :to-shlef="true" @refreshAreaFid="handleAreaFid" /> |
|
|
|
|
|
|
|
|
<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%;" /> |
|
|
<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> |
|
|
</div> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script> |
|
|
<script> |
|
|
import { FetchRegionTree } from '@/api/deviceVI/index' |
|
|
import { FetchRegionTree } from '@/api/deviceVI/index' |
|
|
import { FetchMapDetails } from '@/api/map/index' |
|
|
import { FetchMapDetails } from '@/api/map/index' |
|
|
import { FetchInitBookShelfList, FetchBookShelfDetails } from '@/api/shelf/index' |
|
|
|
|
|
|
|
|
import { FetchInitBookShelfList, FetchBookShelfDetails, FetchInitShelfGridByShelfId } from '@/api/shelf/index' |
|
|
import PreviewMap from '../map3d/map' |
|
|
import PreviewMap from '../map3d/map' |
|
|
export default { |
|
|
export default { |
|
|
name: 'Shelf3dPosition', |
|
|
name: 'Shelf3dPosition', |
|
|
@ -162,7 +221,79 @@ export default { |
|
|
bindAllRackList: [], |
|
|
bindAllRackList: [], |
|
|
bindAllInquiryList: [], |
|
|
bindAllInquiryList: [], |
|
|
filterShelfList: [], |
|
|
filterShelfList: [], |
|
|
currentFid: null |
|
|
|
|
|
|
|
|
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() { |
|
|
created() { |
|
|
@ -170,9 +301,13 @@ export default { |
|
|
this.regionTreeData = [this.transformData(res)] |
|
|
this.regionTreeData = [this.transformData(res)] |
|
|
console.log(this.regionTreeData) |
|
|
console.log(this.regionTreeData) |
|
|
this.$nextTick(() => { |
|
|
this.$nextTick(() => { |
|
|
|
|
|
// 从localStorage获取并自动选中对应的节点 |
|
|
|
|
|
this.autoSelectFromLocalStorage() |
|
|
|
|
|
|
|
|
|
|
|
// 如果没有localStorage数据,选择第一个有子节点的区域 |
|
|
if (!this.regionTreeData[0].children?.length) return |
|
|
if (!this.regionTreeData[0].children?.length) return |
|
|
const targetFloor = this.regionTreeData[0].children.find(floor => floor.children?.length > 0) |
|
|
const targetFloor = this.regionTreeData[0].children.find(floor => floor.children?.length > 0) |
|
|
if (targetFloor?.children?.length) { |
|
|
|
|
|
|
|
|
if (targetFloor?.children?.length && !this.currentTreeNode) { |
|
|
const firstRegion = targetFloor.children[0] |
|
|
const firstRegion = targetFloor.children[0] |
|
|
this.$refs.treeRef.setCurrentKey(firstRegion.id) |
|
|
this.$refs.treeRef.setCurrentKey(firstRegion.id) |
|
|
this.handleTreeNodeClick(firstRegion) |
|
|
this.handleTreeNodeClick(firstRegion) |
|
|
@ -185,6 +320,108 @@ export default { |
|
|
this.changeShelfToModel(this.options1[0]?.value) |
|
|
this.changeShelfToModel(this.options1[0]?.value) |
|
|
}, |
|
|
}, |
|
|
methods: { |
|
|
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) { |
|
|
transformData(data) { |
|
|
const rootNode = { |
|
|
const rootNode = { |
|
|
id: data.fondsId, |
|
|
id: data.fondsId, |
|
|
@ -212,8 +449,11 @@ export default { |
|
|
} |
|
|
} |
|
|
return rootNode |
|
|
return rootNode |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
handleTreeNodeClick(nodeData) { |
|
|
handleTreeNodeClick(nodeData) { |
|
|
this.form.layerVal = null |
|
|
this.form.layerVal = null |
|
|
|
|
|
this.form.shelfVal = null // 清空架位选择 |
|
|
|
|
|
this.rackOptions = [] // 清空架位列表 |
|
|
this.currentTreeNode = nodeData.raw |
|
|
this.currentTreeNode = nodeData.raw |
|
|
console.log('handleTreeNodeClick', nodeData) |
|
|
console.log('handleTreeNodeClick', nodeData) |
|
|
const currentNode = this.$refs.treeRef.getNode(nodeData) |
|
|
const currentNode = this.$refs.treeRef.getNode(nodeData) |
|
|
@ -239,6 +479,7 @@ export default { |
|
|
this.getMapDetails(nodeData.raw.mapId) |
|
|
this.getMapDetails(nodeData.raw.mapId) |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
getMapDetails(id) { |
|
|
getMapDetails(id) { |
|
|
const params = { |
|
|
const params = { |
|
|
'id': id |
|
|
'id': id |
|
|
@ -257,15 +498,24 @@ export default { |
|
|
} |
|
|
} |
|
|
if (this.currentTreeNode.fid) { |
|
|
if (this.currentTreeNode.fid) { |
|
|
this.$refs.map.areaFid = this.currentTreeNode.fid |
|
|
this.$refs.map.areaFid = this.currentTreeNode.fid |
|
|
|
|
|
// this.handleAreaFid(this.currentTreeNode.fid) |
|
|
} else { |
|
|
} else { |
|
|
this.$refs.map.areaFid = null |
|
|
this.$refs.map.areaFid = null |
|
|
|
|
|
this.currentFid = null |
|
|
} |
|
|
} |
|
|
this.$refs.map.initMap() |
|
|
this.$refs.map.initMap() |
|
|
}) |
|
|
}) |
|
|
}).catch(() => { |
|
|
}).catch(() => { |
|
|
}) |
|
|
}) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
changeShelfGetGrid(val) { |
|
|
changeShelfGetGrid(val) { |
|
|
|
|
|
if (!val) { |
|
|
|
|
|
this.rackOptions = [] |
|
|
|
|
|
this.form.shelfVal = null |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
FetchBookShelfDetails({ 'shelfId': val.id }).then(res => { |
|
|
FetchBookShelfDetails({ 'shelfId': val.id }).then(res => { |
|
|
this.rackOptions = [] |
|
|
this.rackOptions = [] |
|
|
const start = parseInt(res.startShelf) || 1 |
|
|
const start = parseInt(res.startShelf) || 1 |
|
|
@ -276,18 +526,37 @@ export default { |
|
|
name: `${i.toString().padStart(2, '0')}架` |
|
|
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(() => { |
|
|
}).catch(() => { |
|
|
|
|
|
this.rackOptions = [] |
|
|
|
|
|
this.form.shelfVal = null |
|
|
}) |
|
|
}) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
handleVisibleChange(visible) { |
|
|
|
|
|
// 下拉关闭时的额外逻辑(可选) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
// 微调:筛选类型改变时,仅当当前朝向无效时才重置 |
|
|
changeShelfToModel(val) { |
|
|
changeShelfToModel(val) { |
|
|
if (val === 1 || val === 3) { |
|
|
if (val === 1 || val === 3) { |
|
|
this.towardDisabled = true |
|
|
this.towardDisabled = true |
|
|
this.abOptions = [ |
|
|
this.abOptions = [ |
|
|
{ value: 0, name: '双面' } |
|
|
|
|
|
|
|
|
{ value: 1, name: '双面' } |
|
|
] |
|
|
] |
|
|
} else { |
|
|
} else { |
|
|
this.towardDisabled = false |
|
|
this.towardDisabled = false |
|
|
@ -296,8 +565,17 @@ export default { |
|
|
{ value: 2, name: 'B面' } |
|
|
{ value: 2, name: 'B面' } |
|
|
] |
|
|
] |
|
|
} |
|
|
} |
|
|
this.form.toward = this.abOptions[0]?.value |
|
|
|
|
|
|
|
|
// 只有当当前朝向不在可选范围内时,才重置朝向 |
|
|
|
|
|
const hasCurrentToward = this.abOptions.some(item => item.value === this.form.toward) |
|
|
|
|
|
if (!hasCurrentToward) { |
|
|
|
|
|
this.form.toward = this.abOptions[0]?.value |
|
|
|
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
handleVisibleChange(visible) { |
|
|
|
|
|
// 下拉关闭时的额外逻辑(可选) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
getInitBookShelfList(data) { |
|
|
getInitBookShelfList(data) { |
|
|
const params = { 'floorId': data.parentFloorId, 'regionId': data.regionId } |
|
|
const params = { 'floorId': data.parentFloorId, 'regionId': data.regionId } |
|
|
FetchInitBookShelfList(params).then(res => { |
|
|
FetchInitBookShelfList(params).then(res => { |
|
|
@ -313,13 +591,99 @@ export default { |
|
|
rowType: item.rowType |
|
|
rowType: item.rowType |
|
|
} |
|
|
} |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
// 如果有localStorage数据,重新触发表单填充 |
|
|
|
|
|
const shelfDataStr = localStorage.getItem('shelf3dPositionRow') |
|
|
|
|
|
if (shelfDataStr) { |
|
|
|
|
|
this.autoFillForm(JSON.parse(shelfDataStr)) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
}).catch(() => { |
|
|
}).catch(() => { |
|
|
}) |
|
|
}) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
handleAreaFid(areaFid) { |
|
|
handleAreaFid(areaFid) { |
|
|
this.currentFid = areaFid |
|
|
this.currentFid = areaFid |
|
|
console.log('mapAreaFid', 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) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -411,6 +775,16 @@ export default { |
|
|
padding: 10px 10px 0 10px; |
|
|
padding: 10px 10px 0 10px; |
|
|
height: 96px; |
|
|
height: 96px; |
|
|
overflow-y: scroll; |
|
|
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{ |
|
|
.filter-model-select{ |
|
|
border-top: 1px solid #edeff3; |
|
|
border-top: 1px solid #edeff3; |
|
|
@ -453,4 +827,57 @@ export default { |
|
|
font-size: 14px; |
|
|
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> |
|
|
</style> |