PLC设备管理页面修改
This commit is contained in:
@@ -16,6 +16,15 @@ const router = createRouter({
|
||||
component: () => import('../views/Layout.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
redirect: '/home',
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
component: () => import('../views/Home.vue'),
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
name: 'user',
|
||||
@@ -90,7 +99,7 @@ router.beforeEach((to, from, next) => {
|
||||
if (to.path === '/login') {
|
||||
// 已登录状态下访问登录页,自动跳转到首页
|
||||
if (token) {
|
||||
next('/')
|
||||
next('/home')
|
||||
ElMessage.success('已登录,自动跳转')
|
||||
} else {
|
||||
// 未登录,正常进入登录页
|
||||
@@ -106,6 +115,12 @@ router.beforeEach((to, from, next) => {
|
||||
return
|
||||
}
|
||||
|
||||
// 如果访问根路径,重定向到首页
|
||||
if (to.path === '/') {
|
||||
next('/home')
|
||||
return
|
||||
}
|
||||
|
||||
// 已登录且访问合法页面,正常放行
|
||||
next()
|
||||
})
|
||||
|
||||
@@ -43,6 +43,27 @@ const TokenManager = {
|
||||
// 应用启动时初始化token
|
||||
TokenManager.initToken()
|
||||
|
||||
// 登录过期提示防重复标志
|
||||
let isLoginExpiredShown = false
|
||||
|
||||
// 处理登录过期(防重复提示)
|
||||
const handleLoginExpired = () => {
|
||||
if (!isLoginExpiredShown) {
|
||||
isLoginExpiredShown = true
|
||||
// 清除token
|
||||
TokenManager.removeToken()
|
||||
// 显示提示消息
|
||||
ElMessage.error('登录已过期,请重新登录')
|
||||
// 跳转到登录页
|
||||
router.replace('/login').finally(() => {
|
||||
// 延迟重置标志位,确保跳转完成后再允许下次提示
|
||||
setTimeout(() => {
|
||||
isLoginExpiredShown = false
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use(
|
||||
(config: InternalAxiosRequestConfig) => {
|
||||
@@ -72,10 +93,8 @@ request.interceptors.response.use(
|
||||
|
||||
// 处理业务错误码
|
||||
if (data.code === 302) {
|
||||
// 清除token
|
||||
TokenManager.removeToken()
|
||||
// 跳转到登录页
|
||||
router.replace('/login')
|
||||
// 处理登录过期(防重复提示)
|
||||
handleLoginExpired()
|
||||
return Promise.reject(data)
|
||||
}
|
||||
|
||||
@@ -90,11 +109,8 @@ request.interceptors.response.use(
|
||||
(error) => {
|
||||
// 处理401未授权错误
|
||||
if (error.response?.status === 401) {
|
||||
// 清除token
|
||||
TokenManager.removeToken()
|
||||
// 跳转到登录页
|
||||
ElMessage.error('登录已过期,请重新登录')
|
||||
router.replace('/login')
|
||||
// 处理登录过期(防重复提示)
|
||||
handleLoginExpired()
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
|
||||
56
rc_autoplc_front/src/views/Home.vue
Normal file
56
rc_autoplc_front/src/views/Home.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div class="home-container">
|
||||
<div class="welcome-content">
|
||||
<h1 class="welcome-title">欢迎使用北京融创智能仪器管理系统</h1>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 首页组件,未来将展示数字孪生监控大屏
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.home-container {
|
||||
width: 100%;
|
||||
height: calc(92vh - 25px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
text-align: center;
|
||||
color: #080101;
|
||||
padding: 40px;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.welcome-title {
|
||||
font-size: 48px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
|
||||
letter-spacing: 2px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.welcome-subtitle {
|
||||
font-size: 24px;
|
||||
margin: 0;
|
||||
opacity: 0.9;
|
||||
font-weight: 300;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.welcome-title {
|
||||
font-size: 32px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -31,6 +31,10 @@
|
||||
router
|
||||
:collapse="false"
|
||||
>
|
||||
<el-menu-item index="/home">
|
||||
<el-icon><HomeFilled /></el-icon>
|
||||
<span>首页</span>
|
||||
</el-menu-item>
|
||||
<el-sub-menu index="system">
|
||||
<template #title>
|
||||
<el-icon><Setting /></el-icon>
|
||||
@@ -66,17 +70,17 @@
|
||||
<el-icon><Grid /></el-icon>
|
||||
<span>业务管理</span>
|
||||
</template>
|
||||
<el-menu-item index="/island-info">
|
||||
<el-icon><Setting /></el-icon>
|
||||
<span>功能岛管理</span>
|
||||
<el-menu-item index="/plc-devinfo">
|
||||
<el-icon><Connection /></el-icon>
|
||||
<span>PLC设备管理</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/devinfo">
|
||||
<el-icon><Monitor /></el-icon>
|
||||
<span>设备管理</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/plc-devinfo">
|
||||
<el-icon><Connection /></el-icon>
|
||||
<span>PLC设备管理</span>
|
||||
<el-menu-item index="/island-info">
|
||||
<el-icon><Setting /></el-icon>
|
||||
<span>功能岛管理</span>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="flow">
|
||||
@@ -112,7 +116,7 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { User, Setting, Avatar, OfficeBuilding, Briefcase, Document, CaretBottom, UserFilled, Grid, Monitor, Connection, List, EditPen, Files, Tickets, Management, FolderOpened, Box, Filter } from '@element-plus/icons-vue'
|
||||
import { User, Setting, Avatar, OfficeBuilding, Briefcase, Document, CaretBottom, UserFilled, Grid, Monitor, Connection, List, EditPen, Files, Tickets, Management, FolderOpened, Box, Filter, HomeFilled } from '@element-plus/icons-vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@@ -209,7 +209,7 @@ const handleLogin = async () => {
|
||||
|
||||
ElMessage.success('登录成功')
|
||||
// 跳转到首页
|
||||
router.push('/')
|
||||
router.push('/home')
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 错误提示已在全局响应拦截中处理,这里不重复弹出
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="dept-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>系统管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>部门管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="devinfo-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>业务管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>设备管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="plc-devinfo-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>业务管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>PLC设备管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
@@ -82,13 +83,6 @@
|
||||
{{ row.company || '暂无' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getStatusType(row.status)" size="small">
|
||||
{{ getStatusText(row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="devDesc" label="描述" min-width="150" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ row.devDesc || '暂无' }}
|
||||
@@ -277,7 +271,7 @@ const formData = reactive({
|
||||
company: '',
|
||||
devDesc: '',
|
||||
remark: '',
|
||||
status: 0, // 状态自动设置为0
|
||||
status: 0, // 状态默认为0
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
@@ -292,21 +286,6 @@ const getIndex = (index: number) => {
|
||||
return (pagination.pageNum - 1) * pagination.pageSize + index + 1
|
||||
}
|
||||
|
||||
// 获取状态类型
|
||||
const getStatusType = (status: number | null | undefined) => {
|
||||
if (status === 0) return 'success' // 空闲 - 绿色
|
||||
if (status === 1) return 'warning' // 运行 - 黄色
|
||||
if (status === 4) return 'danger' // 故障 - 红色
|
||||
return 'info'
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status: number | null | undefined) => {
|
||||
if (status === 0) return '空闲'
|
||||
if (status === 1) return '运行'
|
||||
if (status === 4) return '故障'
|
||||
return '未知'
|
||||
}
|
||||
|
||||
// 获取设备列表(只查询devModel为PLC的设备)
|
||||
const getDeviceList = async () => {
|
||||
@@ -483,7 +462,7 @@ const handleSubmit = async () => {
|
||||
const submitData: any = {
|
||||
devName: formData.devName,
|
||||
devModel: 'PLC', // 设备型号固定为PLC
|
||||
status: 0, // 状态自动设置为0
|
||||
status: 0, // 状态默认为0
|
||||
}
|
||||
|
||||
// 添加其他字段(如果非空)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="flowinfo-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>流程管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>标准流程管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div class="goodsinfo-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>流程管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>样品信息管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>样品管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<!-- 搜索栏 -->
|
||||
<el-card class="search-card" shadow="never">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="island-info-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>业务管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>功能岛管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
@@ -92,8 +93,8 @@
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.pageNum"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:page-sizes="[9]"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
background
|
||||
@current-change="handleCurrentChange"
|
||||
@@ -149,7 +150,7 @@
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="绑定设备">
|
||||
<el-form-item v-if="isEdit" label="绑定设备">
|
||||
<div class="bind-device-wrapper">
|
||||
<el-button type="primary" @click="handleBindDevice">
|
||||
<el-icon><Plus /></el-icon>
|
||||
@@ -199,6 +200,7 @@
|
||||
|
||||
<!-- 绑定设备对话框 -->
|
||||
<el-dialog
|
||||
v-if="isEdit"
|
||||
v-model="bindDeviceDialogVisible"
|
||||
:title="isEdit ? '绑定/解绑设备' : '绑定设备'"
|
||||
width="800px"
|
||||
@@ -286,6 +288,17 @@ import {
|
||||
Monitor,
|
||||
Cpu,
|
||||
DataAnalysis,
|
||||
Upload,
|
||||
Download,
|
||||
MagicStick,
|
||||
TakeawayBox,
|
||||
CollectionTag,
|
||||
Position,
|
||||
Dish,
|
||||
Bowl,
|
||||
HomeFilled,
|
||||
Odometer,
|
||||
Sunrise,
|
||||
} from '@element-plus/icons-vue'
|
||||
import {
|
||||
islandInfoadd,
|
||||
@@ -314,7 +327,7 @@ const queryForm = reactive({
|
||||
// 分页
|
||||
const pagination = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 9,
|
||||
})
|
||||
|
||||
// 抽屉相关
|
||||
@@ -352,44 +365,44 @@ const formRules = {
|
||||
const getIslandIcon = (name: string) => {
|
||||
if (!name) return Box
|
||||
|
||||
// 根据名称关键词匹配图标
|
||||
const nameLower = name.toLowerCase()
|
||||
if (nameLower.includes('加液') || nameLower.includes('ph') || nameLower.includes('涡旋')) {
|
||||
return Watermelon
|
||||
} else if (nameLower.includes('水浴') || nameLower.includes('恒温')) {
|
||||
return Sunny
|
||||
} else if (nameLower.includes('震荡')) {
|
||||
return Connection
|
||||
} else if (nameLower.includes('超声')) {
|
||||
return Histogram
|
||||
} else if (nameLower.includes('离心')) {
|
||||
return RefreshRight
|
||||
} else if (nameLower.includes('移液')) {
|
||||
return Aim
|
||||
} else if (nameLower.includes('萃取')) {
|
||||
return Goblet
|
||||
} else if (nameLower.includes('氮吹')) {
|
||||
return WindPower
|
||||
} else if (nameLower.includes('过膜') || nameLower.includes('过滤')) {
|
||||
return Filter
|
||||
} else if (nameLower.includes('人工')) {
|
||||
return User
|
||||
} else if (nameLower.includes('系统') || nameLower.includes('管理')) {
|
||||
return Setting
|
||||
} else if (nameLower.includes('工具')) {
|
||||
return Tools
|
||||
} else if (nameLower.includes('数据') || nameLower.includes('分析')) {
|
||||
return DataAnalysis
|
||||
} else if (nameLower.includes('监控') || nameLower.includes('显示')) {
|
||||
return Monitor
|
||||
} else if (nameLower.includes('处理') || nameLower.includes('计算')) {
|
||||
return Cpu
|
||||
} else if (nameLower.includes('网格') || nameLower.includes('布局')) {
|
||||
return Grid
|
||||
}
|
||||
|
||||
// 默认图标
|
||||
return Box
|
||||
// 预设功能岛与唯一图标的映射(避免重复)
|
||||
const iconRules = [
|
||||
{ keywords: ['涡旋'], icon: MagicStick },
|
||||
{ keywords: ['加液', '加样'], icon: Watermelon },
|
||||
{ keywords: ['进样'], icon: Upload },
|
||||
{ keywords: ['分液'], icon: TakeawayBox },
|
||||
{ keywords: ['浓缩'], icon: CollectionTag },
|
||||
{ keywords: ['移上清'], icon: Position },
|
||||
{ keywords: ['取液'], icon: Dish },
|
||||
{ keywords: ['金属浴', '金属'], icon: Bowl },
|
||||
{ keywords: ['干燥', '硫酸钠'], icon: Sunrise },
|
||||
{ keywords: ['温室', '静置'], icon: HomeFilled },
|
||||
{ keywords: ['ph', '酸碱'], icon: Odometer },
|
||||
{ keywords: ['出样'], icon: Download },
|
||||
{ keywords: ['水浴', '恒温'], icon: Sunny },
|
||||
{ keywords: ['震荡'], icon: Connection },
|
||||
{ keywords: ['超声'], icon: Histogram },
|
||||
{ keywords: ['离心'], icon: RefreshRight },
|
||||
{ keywords: ['移液'], icon: Aim },
|
||||
{ keywords: ['萃取'], icon: Goblet },
|
||||
{ keywords: ['氮吹'], icon: WindPower },
|
||||
{ keywords: ['过膜', '过滤'], icon: Filter },
|
||||
{ keywords: ['人工'], icon: User },
|
||||
{ keywords: ['系统', '管理'], icon: Setting },
|
||||
{ keywords: ['工具'], icon: Tools },
|
||||
{ keywords: ['数据', '分析'], icon: DataAnalysis },
|
||||
{ keywords: ['监控', '显示'], icon: Monitor },
|
||||
{ keywords: ['处理', '计算'], icon: Cpu },
|
||||
{ keywords: ['网格', '布局'], icon: Grid },
|
||||
]
|
||||
|
||||
const matched = iconRules.find(rule =>
|
||||
rule.keywords.some(keyword => nameLower.includes(keyword.toLowerCase()))
|
||||
)
|
||||
|
||||
return matched ? matched.icon : Box
|
||||
}
|
||||
|
||||
// 处理名称输入
|
||||
@@ -632,7 +645,6 @@ const handleSubmit = async () => {
|
||||
}
|
||||
|
||||
let res: any
|
||||
let newIslandId: any = null
|
||||
|
||||
if (isEdit.value && formData.id) {
|
||||
// 编辑 - 需要传入ID,其他字段可选(非空则更新)
|
||||
@@ -640,42 +652,12 @@ const handleSubmit = async () => {
|
||||
id: formData.id,
|
||||
...submitData,
|
||||
})
|
||||
newIslandId = formData.id
|
||||
} else {
|
||||
// 新增
|
||||
res = await islandInfoadd(submitData)
|
||||
// 获取新增后的ID
|
||||
if (res.code === '0' || res.code === 0) {
|
||||
newIslandId = res.data?.id || res.id
|
||||
}
|
||||
}
|
||||
|
||||
if (res.code === '0' || res.code === 0) {
|
||||
// 如果是新增模式且有绑定的设备,需要更新设备的islandId
|
||||
if (!isEdit.value && newIslandId && boundDevices.value.length > 0) {
|
||||
try {
|
||||
const bindPromises = boundDevices.value.map((device: any) => {
|
||||
return devInfoupd({
|
||||
id: device.id,
|
||||
devName: device.devName, // 必填字段
|
||||
islandId: newIslandId,
|
||||
})
|
||||
})
|
||||
const bindResults = await Promise.all(bindPromises)
|
||||
// 检查是否有失败的请求
|
||||
const failedResults = bindResults.filter((res: any) => {
|
||||
return res && (res.code !== '0' && res.code !== 0 && !res.success)
|
||||
})
|
||||
if (failedResults.length > 0) {
|
||||
console.warn('部分设备绑定失败:', failedResults)
|
||||
// 不阻止功能岛创建成功,只提示警告
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('绑定设备失败:', error)
|
||||
// 不阻止功能岛创建成功,只记录错误
|
||||
}
|
||||
}
|
||||
|
||||
ElMessage.success(isEdit.value ? '编辑成功' : '新增成功')
|
||||
drawerVisible.value = false
|
||||
getIslandList()
|
||||
@@ -694,13 +676,16 @@ const handleSubmit = async () => {
|
||||
|
||||
// 打开绑定设备对话框
|
||||
const handleBindDevice = async () => {
|
||||
if (!isEdit.value || !formData.id) {
|
||||
// 新增功能岛不允许绑定设备(仅新增功能岛信息)
|
||||
return
|
||||
}
|
||||
try {
|
||||
deviceLoading.value = true
|
||||
const res: any = await devselect({})
|
||||
const allDevices = res?.data ?? res ?? []
|
||||
|
||||
if (Array.isArray(allDevices)) {
|
||||
if (isEdit.value && formData.id) {
|
||||
// 编辑模式:显示未绑定的设备 + 已绑定该功能岛的设备,排除设备型号为PLC的设备
|
||||
deviceListForBind.value = allDevices.filter((device: any) => {
|
||||
// 排除设备型号为PLC的设备
|
||||
@@ -716,21 +701,6 @@ const handleBindDevice = async () => {
|
||||
device.islandId === '0'
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// 新增模式:只显示未绑定的设备,排除设备型号为PLC的设备
|
||||
deviceListForBind.value = allDevices.filter((device: any) => {
|
||||
// 排除设备型号为PLC的设备
|
||||
if (device.devModel && String(device.devModel).toUpperCase() === 'PLC') {
|
||||
return false
|
||||
}
|
||||
// 筛选条件:islandId为0或空的设备
|
||||
return (
|
||||
!device.islandId ||
|
||||
device.islandId === 0 ||
|
||||
device.islandId === '0'
|
||||
)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
deviceListForBind.value = []
|
||||
}
|
||||
@@ -769,7 +739,8 @@ const handleSaveDeviceBind = async () => {
|
||||
// 获取当前选中的设备ID列表
|
||||
const selectedDeviceIds = selectedDevices.value.map((d: any) => d.id)
|
||||
|
||||
if (isEdit.value && formData.id) {
|
||||
if (!isEdit.value || !formData.id) return
|
||||
|
||||
// 编辑模式:立即保存绑定关系
|
||||
// 获取之前已绑定的设备ID列表
|
||||
const previousBoundDeviceIds = boundDevices.value.map((d: any) => d.id)
|
||||
@@ -796,7 +767,8 @@ const handleSaveDeviceBind = async () => {
|
||||
|
||||
// 执行解绑操作
|
||||
const unbindPromises = devicesToUnbind.map((deviceId: any) => {
|
||||
const device = deviceListForBind.value.find((d: any) => d.id === deviceId) ||
|
||||
const device =
|
||||
deviceListForBind.value.find((d: any) => d.id === deviceId) ||
|
||||
boundDevices.value.find((d: any) => d.id === deviceId)
|
||||
if (device) {
|
||||
// 包含设备名称等必填字段
|
||||
@@ -831,13 +803,6 @@ const handleSaveDeviceBind = async () => {
|
||||
await loadBoundDevices(formData.id)
|
||||
|
||||
ElMessage.success('保存成功')
|
||||
} else {
|
||||
// 新增模式:只更新本地列表,不调用接口(等创建功能岛后再绑定)
|
||||
boundDevices.value = deviceListForBind.value.filter((device: any) =>
|
||||
selectedDeviceIds.includes(device.id)
|
||||
)
|
||||
ElMessage.success('已选择设备,将在创建功能岛后自动绑定')
|
||||
}
|
||||
|
||||
bindDeviceDialogVisible.value = false
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="manage-log-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>系统管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>操作日志管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="position-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>系统管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>职位管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="role-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>系统管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>角色管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="step-info-wrapper">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>流程管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>流程创建</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
@@ -221,7 +222,24 @@ import {
|
||||
WindPower,
|
||||
Filter,
|
||||
User,
|
||||
Setting,
|
||||
Tools,
|
||||
Box,
|
||||
Grid,
|
||||
Monitor,
|
||||
Cpu,
|
||||
DataAnalysis,
|
||||
Upload,
|
||||
Download,
|
||||
MagicStick,
|
||||
TakeawayBox,
|
||||
CollectionTag,
|
||||
Position,
|
||||
Dish,
|
||||
Bowl,
|
||||
HomeFilled,
|
||||
Odometer,
|
||||
Sunrise,
|
||||
} from '@element-plus/icons-vue'
|
||||
import { islandInfolist } from '@/api/tb/islandinfo'
|
||||
import { devselect } from '@/api/tb/devinfo'
|
||||
@@ -416,32 +434,48 @@ const getIslandIconCached = (name: string) => {
|
||||
return islandIconCache.get(key)!
|
||||
}
|
||||
|
||||
// 获取功能岛图标
|
||||
// 获取功能岛图标(根据名称自动生成)
|
||||
const getIslandIcon = (name: string) => {
|
||||
if (!name) return Box
|
||||
|
||||
const nameLower = name.toLowerCase()
|
||||
if (nameLower.includes('加液') || nameLower.includes('ph') || nameLower.includes('涡旋')) {
|
||||
return Watermelon
|
||||
} else if (nameLower.includes('水浴') || nameLower.includes('恒温')) {
|
||||
return Sunny
|
||||
} else if (nameLower.includes('震荡')) {
|
||||
return Connection
|
||||
} else if (nameLower.includes('超声')) {
|
||||
return Histogram
|
||||
} else if (nameLower.includes('离心')) {
|
||||
return RefreshRight
|
||||
} else if (nameLower.includes('移液')) {
|
||||
return Aim
|
||||
} else if (nameLower.includes('萃取')) {
|
||||
return Goblet
|
||||
} else if (nameLower.includes('氮吹')) {
|
||||
return WindPower
|
||||
} else if (nameLower.includes('过膜') || nameLower.includes('过滤')) {
|
||||
return Filter
|
||||
} else if (nameLower.includes('人工')) {
|
||||
return User
|
||||
}
|
||||
return Box
|
||||
|
||||
// 预设功能岛与唯一图标的映射(避免重复)
|
||||
const iconRules = [
|
||||
{ keywords: ['涡旋'], icon: MagicStick },
|
||||
{ keywords: ['加液', '加样'], icon: Watermelon },
|
||||
{ keywords: ['进样'], icon: Upload },
|
||||
{ keywords: ['分液'], icon: TakeawayBox },
|
||||
{ keywords: ['浓缩'], icon: CollectionTag },
|
||||
{ keywords: ['移上清'], icon: Position },
|
||||
{ keywords: ['取液'], icon: Dish },
|
||||
{ keywords: ['金属浴', '金属'], icon: Bowl },
|
||||
{ keywords: ['干燥', '硫酸钠'], icon: Sunrise },
|
||||
{ keywords: ['温室', '静置'], icon: HomeFilled },
|
||||
{ keywords: ['ph', '酸碱'], icon: Odometer },
|
||||
{ keywords: ['出样'], icon: Download },
|
||||
{ keywords: ['水浴', '恒温'], icon: Sunny },
|
||||
{ keywords: ['震荡'], icon: Connection },
|
||||
{ keywords: ['超声'], icon: Histogram },
|
||||
{ keywords: ['离心'], icon: RefreshRight },
|
||||
{ keywords: ['移液'], icon: Aim },
|
||||
{ keywords: ['萃取'], icon: Goblet },
|
||||
{ keywords: ['氮吹'], icon: WindPower },
|
||||
{ keywords: ['过膜', '过滤'], icon: Filter },
|
||||
{ keywords: ['人工'], icon: User },
|
||||
{ keywords: ['系统', '管理'], icon: Setting },
|
||||
{ keywords: ['工具'], icon: Tools },
|
||||
{ keywords: ['数据', '分析'], icon: DataAnalysis },
|
||||
{ keywords: ['监控', '显示'], icon: Monitor },
|
||||
{ keywords: ['处理', '计算'], icon: Cpu },
|
||||
{ keywords: ['网格', '布局'], icon: Grid },
|
||||
]
|
||||
|
||||
const matched = iconRules.find(rule =>
|
||||
rule.keywords.some(keyword => nameLower.includes(keyword.toLowerCase()))
|
||||
)
|
||||
|
||||
return matched ? matched.icon : Box
|
||||
}
|
||||
|
||||
// 获取功能岛描述关键词
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="user-role-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>系统管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>用户角色管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="user-page">
|
||||
<el-breadcrumb separator="/" style="margin-bottom: 16px">
|
||||
<el-breadcrumb-item><router-link to="/home">首页</router-link></el-breadcrumb-item>
|
||||
<el-breadcrumb-item>系统管理</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
|
||||
Reference in New Issue
Block a user