|
|
<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>
|