Przeglądaj źródła

refactor(components):组件更新
refactor(permission):组态页面取消登录校验

HMY 7 miesięcy temu
rodzic
commit
1ae8845575

+ 1 - 0
ui/src/components/GeneralComponents/ArrowComponent.vue

@@ -84,6 +84,7 @@ const handleClick = () => {
 
     .arrow_text {
         color: #fff;
+        text-align: center;
     }
 }
 </style>

+ 51 - 30
ui/src/components/GeneralComponents/MTypeHollowTankComponent.vue

@@ -1,9 +1,9 @@
 <template>
     <!-- 下锥形镂空罐 -->
-    <div class="tank_body" :style="getTankBodyStyle">
+    <div class="tank_body">
         <i class="icon iconfont-colour icon-tank1 tank_icon" :style="getTankStyle">
             <!-- 标题 -->
-            <div class="tank_title" v-if="title" :style="{ fontSize: titleFontSize }">
+            <div class="tank_title" v-if="title" :style="titleStyle">
                 {{ title }}
             </div>
         </i>
@@ -29,40 +29,61 @@ const props = defineProps({
     },
 })
 
-const iconSize = computed(() => props.iconSize ?? props.iconWidth)
-
-//罐体样式
-const getTankBodyStyle = computed(() => ({
-    width: `${props.iconWidth ?? props.iconSize}px`,
-    height: `${props.iconHeight ?? props.iconSize}px`,
-    fontSize: `${props.iconSize ?? 200}px`,
-}))
-
-
-// 罐子样式
-const getTankStyle = computed(() => {
-    const style = {
-        fontSize: iconSize.value + 'px',
-        display: 'inline-block'
+const iconSize = computed(() => {
+    // 判断是否同时传入了width和height
+    if (props.iconWidth !== null && props.iconHeight !== null) {
+        return Math.min(props.iconWidth, props.iconHeight);
     }
-    //根据传进来的iconWidth和iconHeight来控制图标的大小
+    // 没传入,使用默认的iconSize
+    return props.iconSize;
+});
+// 计算图标缩放比例
+const scaleInfo = computed(() => {
     const scaleX = props.iconWidth ? props.iconWidth / iconSize.value : 1
     const scaleY = props.iconHeight ? props.iconHeight / iconSize.value : 1
-
-    if (scaleX !== 1 || scaleY !== 1) {
-        style.transform = `scale(${scaleX}, ${scaleY})`
-    }
-
-    return style
+    return { scaleX, scaleY }
 })
+// 罐子样式
+const getTankStyle = computed(() => ({
+    fontSize: `${iconSize.value}px`,
+    display: 'inline-block',
+    transform: `scale(${scaleInfo.value.scaleX}, ${scaleInfo.value.scaleY})`
+}))
+
 // 根据标题长度动态设置字体大小
-const titleFontSize = computed(() => {
+const titleStyle = computed(() => {
+     const { scaleX, scaleY } = scaleInfo.value
     const len = props.title.length
-    if (len <= 4) return iconSize.value *0.15 + 'px'
-    if (len <= 8) return iconSize.value *0.1 + 'px'
-    if (len <= 12) return iconSize.value *0.08 + 'px'
-    return iconSize.value *0.06 + 'px'
-})
+    // 先根据长度计算基础字体大小
+    let baseSize;
+    if (len <= 4) {
+        baseSize = iconSize.value * 0.1;
+    } else if (len <= 8) {
+        baseSize = iconSize.value * 0.09;
+    } else if (len <= 12) {
+        baseSize = iconSize.value * 0.08;
+    } else {
+        baseSize = iconSize.value * 0.06;
+    }
+    // 限制最大为30px,取计算值和30px中的较小值
+    const maxSize = 30;
+    const finalSize = Math.min(baseSize, maxSize);
+    return {
+        fontSize: `${finalSize}px`,
+        position: 'absolute',
+        top: '7%',
+        left: '50%',
+        // 核心:通过反向缩放抵消图标的缩放(1/scaleX 抵消 scaleX)
+        transform: `translate(-50%, -50%) scale(${1 / scaleX}, ${1 / scaleY})`,
+        color: '#e65100',
+        fontWeight: 'bold',
+        zIndex: 20,
+        pointerEvents: 'none',
+        textAlign: 'center',
+        //不换行
+        whiteSpace: 'nowrap'
+    }
+});
 </script>
 
 <style scoped lang="scss">

+ 24 - 6
ui/src/components/GeneralComponents/MTypeTankComponent.vue

@@ -3,7 +3,7 @@
     <div class="tank">
         <!-- 下锥形罐体 -->
         <i class="icon iconfont-colour icon-initialTank1 tank_m1" :style="getTankStyle">
-            <div class="tank_title" v-if="title" :style="{ fontSize: iconSize * 0.1 + 'px' }">{{ title }}</div>
+            <div class="tank_title" v-if="title" :style="{ fontSize: titleFontSize }">{{ title }}</div>
         </i>
     </div>
 </template>
@@ -27,17 +27,17 @@ const props = defineProps({
     },
 })
 
-const fontSize = computed(() => props.iconSize ?? 200)
+const iconSize = computed(() => props.iconSize ?? props.iconWidth)
 
 // 罐子样式
 const getTankStyle = computed(() => {
     const style = {
-        fontSize: fontSize.value + 'px',
+        fontSize: iconSize.value + 'px',
         display: 'inline-block'
     }
     //根据传进来的iconWidth和iconHeight来控制图标的大小
-    const scaleX = props.iconWidth ? props.iconWidth / fontSize.value : 1
-    const scaleY = props.iconHeight ? props.iconHeight / fontSize.value : 1
+    const scaleX = props.iconWidth ? props.iconWidth / iconSize.value : 1
+    const scaleY = props.iconHeight ? props.iconHeight / iconSize.value : 1
 
     if (scaleX !== 1 || scaleY !== 1) {
         style.transform = `scale(${scaleX}, ${scaleY})`
@@ -46,6 +46,24 @@ const getTankStyle = computed(() => {
     return style
 })
 
+const titleFontSize = computed(() => {
+    const len = props.title.length
+    // 先根据长度计算基础字体大小
+    let baseSize;
+    if (len <= 4) {
+        baseSize = iconSize.value * 0.15;
+    } else if (len <= 8) {
+        baseSize = iconSize.value * 0.1;
+    } else if (len <= 12) {
+        baseSize = iconSize.value * 0.08;
+    } else {
+        baseSize = iconSize.value * 0.06;
+    }
+    // 限制最大为30px,取计算值和30px中的较小值
+    const maxSize = 30;
+    const finalSize = Math.min(baseSize, maxSize);
+    return finalSize + 'px';
+});
 </script>
 
 <style lang="scss" scoped>
@@ -63,7 +81,7 @@ const getTankStyle = computed(() => {
             top: 20%;
             left: 50%;
             transform: translate(-50%, -50%);
-            color: #FFA500;
+            color: #e65100;
             font-weight: bold;
             width: max-content;
         }

+ 1 - 1
ui/src/components/GeneralComponents/PhSliderComponent.vue

@@ -62,7 +62,7 @@ const marks = computed(() => {
 
 // 动态样式
 const sliderStyle = computed(() => ({
-    '--marks-font-size': `${Math.max(props.sensorWidth * 0.9, 18)}px`,
+    '--marks-font-size': `${Math.max(props.sensorWidth * 1.8, 18)}px`,
     '--runway-width': `${props.sensorWidth}px`,
     '--slider-height': props.sensorHeight ? `${props.sensorHeight}px` : '0.5em',
 }))

+ 4 - 7
ui/src/components/GeneralComponents/PumpComponent.vue

@@ -61,11 +61,7 @@ const getPumpClass = computed(() => {
 
 // 泵标题样式
 const getPumpTitleStyle = computed(() => {
-    return props.isReverse ? {
-        fontSize: `${props.iconSize * 0.2}px`,
-        left: 'auto',
-        right: '0%'
-    } : { fontSize: `${props.iconSize * 0.2}px` }
+    return  { fontSize: `${props.iconSize * 0.2}px` }
 })
 
 // 泵状态样式
@@ -102,8 +98,9 @@ const getPumpHzStyle = computed(() => {
     .pump_title {
         position: absolute;
         width: max-content;
-        top: -7%;
-        left: 56%;
+        transform: translate(-50%, -50%);
+        top: 116%;
+        left: 82%;
         color: aliceblue;
     }
 

+ 68 - 48
ui/src/components/GeneralComponents/STypeHollowTankComponent.vue

@@ -1,12 +1,11 @@
 <template>
-    <div class="tank">
-        <!-- 方形镂空罐体图标 -->
-        <i class="icon iconfont-colour icon-tank3 tank_s" :style="getTankStyle">
-            <div class="tank_title" v-if="title" :style="{ fontSize: titleFontSize }">
+    <!-- 方形镂空罐体 -->
+    <div class="tank_body">
+        <i class="icon iconfont-colour icon-tank3 tank_icon" :style="getTankStyle">
+            <div v-if="title" :style="titleStyle">
                 {{ title }}
             </div>
         </i>
-
     </div>
 </template>
 
@@ -18,68 +17,89 @@ const props = defineProps({
         type: String,
         required: true
     },
-    iconSize: {
+    iconSize: { // 图标大小
         type: Number,
-        default: 400
+        default: 200,
     },
-    iconWidth: {
+    iconWidth: { // 图标宽度
         type: Number,
     },
-    iconHeight: {
+    iconHeight: { // 图标高度
         type: Number,
     },
 })
 
-// 根据标题长度动态设置字体大小
-const titleFontSize = computed(() => {
-    const len = props.title.length
-    if (len <= 4) return '24px'
-    if (len <= 8) return '16px'
-    if (len <= 12) return '14px'
-    return '12px'
+// 图标尺寸计算
+const iconSize = computed(() => {
+    // 判断是否同时传入了width和height
+    if (props.iconWidth !== null && props.iconHeight !== null) {
+        return Math.min(props.iconWidth, props.iconHeight);
+    }
+    // 没传入,使用默认的iconSize
+    return props.iconSize;
+});
+
+// 计算图标缩放比例
+const scaleInfo = computed(() => {
+    const scaleX = props.iconWidth ? props.iconWidth / iconSize.value : 1
+    const scaleY = props.iconHeight ? props.iconHeight / iconSize.value : 1
+    return { scaleX, scaleY }
 })
 
-const fontSize = computed(() => props.iconSize ?? 200)
+// 罐子图标样式(包含缩放)
+const getTankStyle = computed(() => ({
+    fontSize: `${iconSize.value}px`,
+    display: 'inline-block',
+    transform: `scale(${scaleInfo.value.scaleX}, ${scaleInfo.value.scaleY})`
+}))
 
-// 罐子样式
-const getTankStyle = computed(() => {
-    const style = {
-        fontSize: fontSize.value + 'px',
-        display: 'inline-block'
+// 标题样式(应用反向缩放抵消图标缩放影响,新增最小15px限制)
+const titleStyle = computed(() => {
+    const { scaleX, scaleY } = scaleInfo.value
+    // 计算标题基础字体大小(不受缩放影响)
+    const len = props.title.length
+    let baseSize;
+    if (len <= 4) {
+        baseSize = iconSize.value * 0.11;
+    } else if (len < 8) {
+        baseSize = iconSize.value * 0.08;
+    } else if (len < 12) {
+        baseSize = iconSize.value * 0.06;
+    } else {
+        baseSize = iconSize.value * 0.04;
     }
-    const scaleX = props.iconWidth ? props.iconWidth / fontSize.value : 1
-    const scaleY = props.iconHeight ? props.iconHeight / fontSize.value : 1
+    // 限制最大30px,最小15px
+    const maxSize = 30;
+    const minSize = 15;
+    const finalSize = Math.min(Math.max(baseSize, minSize), maxSize); // 先取最小限制,再取最大限制
 
-    if (scaleX !== 1 || scaleY !== 1) {
-        style.transform = `scale(${scaleX}, ${scaleY})`
-        style['--scale-x'] = scaleX
-        style['--scale-y'] = scaleY
+    return {
+        fontSize: `${finalSize}px`,
+        position: 'absolute',
+        top: '9%', // 保持在图标内顶部9%的位置
+        left: '50%',
+        // 核心:通过反向缩放抵消图标的缩放(1/scaleX 抵消 scaleX)
+        transform: `translate(-50%, -50%) scale(${1 / scaleX}, ${1 / scaleY})`,
+        color: '#e65100',
+        fontWeight: 'bold',
+        zIndex: 20,
+        pointerEvents: 'none',
+        textAlign: 'center',
+        //不换行
+        whiteSpace: 'nowrap'
     }
-
-    return style
-})
+});
 </script>
 
-<style lang="scss" scoped>
-.tank {
+<style scoped lang="scss">
+.tank_body {
+    text-align: center;
     position: relative;
     z-index: 10;
 
-    .tank_s {
-        position: relative;
+    .tank_icon {
+        position: relative; // 作为标题的定位容器
         z-index: 10;
-
-        .tank_title {
-            position: absolute;
-            top: 6%;
-            left: 50%;
-            transform: translate(-50%, -50%) scale(calc(1 / var(--scale-x, 1)), calc(1 / var(--scale-y, 1)));
-            color: #e65100;
-            font-weight: bold;
-            z-index: 20;
-            pointer-events: none;
-            text-align: center;
-        }
     }
 }
-</style>
+</style>

+ 2 - 1
ui/src/components/GeneralComponents/STypeTankComponent.vue

@@ -68,7 +68,7 @@ const getTankStyle = computed(() => {
 
         .tank_title {
             position: absolute;
-            top: 6%;
+            top: 20%;
             left: 50%;
             transform: translate(-50%, -50%) scale(calc(1 / var(--scale-x, 1)), calc(1 / var(--scale-y, 1)));
             color: #e65100;
@@ -76,6 +76,7 @@ const getTankStyle = computed(() => {
             z-index: 20;
             pointer-events: none;
             text-align: center;
+            white-space: nowrap;
         }
     }
 }

+ 2 - 2
ui/src/components/GeneralComponents/SeparatorComponent.vue

@@ -68,10 +68,10 @@ const getTankStyle = computed(() => {
         //罐子名称
         .tank_title {
             position: absolute;
-            top: 39%;
+            top: 47%;
             left: 50%;
             transform: translate(-50%, -50%);
-            font-size: 30px;
+            font-size: 16px;
             color: #d3e600;
             font-weight: bold;
         }

+ 34 - 9
ui/src/components/GeneralComponents/TempSliderComponent.vue

@@ -21,6 +21,10 @@ const props = defineProps({
     sensorHeight: { // 进度条高度
         type: Number,
     },
+    specialCondition: {// 特殊条件
+        type: JSON,
+        default: () => ({ iconFirst: true })
+    }
 })
 
 // 处理默认值:如果为空数组或无效,使用默认值
@@ -56,15 +60,36 @@ const marks = computed(() => {
         },
     }
 })
-
+//计算刻度字体长度
+const marksFontLength = computed(() => {
+    const temp = safeSensorValue.value[0]
+    if (temp == null || isNaN(temp)) return 0
+    const valueNum = Number(temp)    // 数值型 key
+    const valueLabel = Math.round(valueNum)//取整
+    return (valueLabel.toString().length) * props.sensorWidth * 1.8 // 刻度字体长度
+})
 // slider 动态样式
-const sliderStyle = computed(() => ({
-    '--marks-font-size': `${props.sensorWidth * 1.8}px`,// 刻度字体大小
-    '--runway-width': `${props.sensorWidth}px`, // 进度条宽度
-    '--slider-height': props.sensorHeight
-        ? `${props.sensorHeight}px`
-        : '0.5em',                   // 进度条高度
-}))
+const sliderStyle = computed(() => {
+    // 兜底逻辑
+    let iconFirst = true
+
+    if (props.specialCondition && props.specialCondition.iconFirst != null) {
+        // 转换成布尔
+        iconFirst = String(props.specialCondition.iconFirst).toLowerCase() === 'true'
+    }
+
+    return {
+        '--marks-font-size': `${props.sensorWidth * 1.8}px`, // 刻度字体大小
+        '--runway-width': `${props.sensorWidth}px`, // 进度条宽度
+        '--slider-position-left': iconFirst
+            ? `${props.sensorWidth + 5}px`
+            : `${-marksFontLength.value - 10}px`, // 刻度字体位置
+        '--slider-height': props.sensorHeight
+            ? `${props.sensorHeight}px`
+            : '0.5em', // 进度条高度
+    }
+})
+
 </script>
 
 <style scoped lang="scss">
@@ -93,7 +118,7 @@ const sliderStyle = computed(() => ({
 
     .el-slider__marks-text {
         font-size: var(--marks-font-size); // 刻度字体大小
-        left: 130%; // 刻度字体位置
+        left: var(--slider-position-left) // 刻度字体位置
     }
 
     .el-slider__runway {

+ 1 - 1
ui/src/components/GeneralComponents/control/PageNavComponent.vue

@@ -1,5 +1,5 @@
-<!-- src/components/GeneralComponents/control/PageNavComponent.vue -->
 <template>
+    <!-- 上方导航栏 -->
     <div class="custom_nav">
         <div v-for="item in items" :key="item.code" class="nav_item" :class="{ active: item.code === currentCode }"
             @click="goToPage(item)">

+ 2 - 2
ui/src/components/GeneralComponents/control/TankNavigationComponent.vue

@@ -1,10 +1,10 @@
 <template>
     <div v-if="tanks.length > 0" class="equipment_nav">
-        <div class="nav_title">罐体导航</div>
+        <div class="nav_title">设备导航</div>
 
         <!-- 搜索框 -->
         <div class="nav_search">
-            <input type="text" v-model="searchKeyword" placeholder="搜索罐体..." @input="handleSearch">
+            <input type="text" v-model="searchKeyword" placeholder="搜索设备..." @input="handleSearch">
             <i class="search_icon">🔍</i>
         </div>
 

+ 1 - 1
ui/src/permission.js

@@ -11,7 +11,7 @@ import usePermissionStore from '@/store/modules/permission'
 
 NProgress.configure({ showSpinner: false })
 
-const whiteList = ['/login', '/register', '/CaSO4_1', '/CaSO4_2', '/CaSO4_3', '/CaSO4_4', '/SeparationTower/SingleGroup', '/HeatExchange', '/IronAlloy', '/m1sj', '/hr', '/m2cl', '/pd','/flowSelect','/flowSelect/m1','/flowSelect/m2','/flowSelect/paramSetting']
+const whiteList = ['/login', '/register', '/CaSO4_1', '/CaSO4_2', '/CaSO4_3', '/CaSO4_4', '/SeparationTower/SingleGroup', '/HeatExchange', '/IronAlloy', '/m1sj', '/hr', '/m2cl', '/pd','/flowSelect','/flowSelect/m1','/flowSelect/m2','/flowSelect/paramSetting','/configuratePage/*',]
 
 const isWhiteList = (path) => {
   return whiteList.some(pattern => isPathMatch(pattern, path))