Parcourir la source

feat:风险等级,管理单位,建筑信息,智慧消防

LAPTOP-U5GOA5HA\zz il y a 1 an
Parent
commit
f2ffccd122

BIN
app/src/assets/images/Group 1321314647.png


BIN
app/src/assets/images/Group 1321314648.png


BIN
app/src/assets/images/Group 1321314649.png


BIN
app/src/assets/images/Group 1321314650.png


BIN
app/src/assets/images/Group 1321314651.png


BIN
app/src/assets/images/Rectangle 3726.png


BIN
app/src/assets/images/Rectangle 3728.png


BIN
app/src/assets/images/image 13.png


+ 423 - 0
app/src/components/Monitor3D.vue

@@ -0,0 +1,423 @@
+<script setup>
+import { onMounted, ref } from "vue";
+import * as echarts from "echarts";
+import "echarts-gl";
+
+let chart, option;
+const pieChart3d = ref();
+onMounted(() => {
+  console.log(pieChart3d);
+  chart = echarts.init(pieChart3d.value);
+  // 传入数据生成 option
+  option = getPie3D(
+    [
+      {
+        name: "生命通道监控点位",
+        value: 100,
+      },
+      {
+        name: "电气火灾监测点位",
+        value: 12,
+      },
+      {
+        name: "水压检测点位",
+        value: 46,
+      },
+      
+    ],
+    0.75
+  );
+
+  // 监听鼠标事件,实现饼图选中效果(单选),近似实现高亮(放大)效果。
+  let hoveredIndex = "";
+  // 准备重新渲染扇形所需的参数
+  let isSelected;
+  let isHovered;
+  let startRatio;
+  let endRatio;
+  let k;
+
+  // 监听 mouseover,近似实现高亮(放大)效果
+  chart.on("mouseover", function (params) {
+    // 如果触发 mouseover 的扇形当前已高亮,则不做操作
+    if (hoveredIndex === params.seriesIndex) {
+      return;
+
+      // 否则进行高亮及必要的取消高亮操作
+    } else {
+      // 如果当前有高亮的扇形,取消其高亮状态(对 option 更新)
+      if (hoveredIndex !== "") {
+        // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 false。
+        isSelected = option.series[hoveredIndex].pieStatus.selected;
+        isHovered = false;
+        startRatio = option.series[hoveredIndex].pieData.startRatio;
+        endRatio = option.series[hoveredIndex].pieData.endRatio;
+        k = option.series[hoveredIndex].pieStatus.k;
+
+        // 对当前点击的扇形,执行取消高亮操作(对 option 更新)
+        option.series[hoveredIndex].parametricEquation = getParametricEquation(
+          startRatio,
+          endRatio,
+          isSelected,
+          isHovered,
+          k,
+          option.series[hoveredIndex].pieData.value
+        );
+        option.series[hoveredIndex].pieStatus.hovered = isHovered;
+
+        // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
+        hoveredIndex = "";
+      }
+
+      // 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新)
+      if (params.seriesName !== "mouseoutSeries") {
+        // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
+        isSelected = option.series[params.seriesIndex].pieStatus.selected;
+        isHovered = true;
+        startRatio = option.series[params.seriesIndex].pieData.startRatio;
+        endRatio = option.series[params.seriesIndex].pieData.endRatio;
+        k = option.series[params.seriesIndex].pieStatus.k;
+
+        // 对当前点击的扇形,执行高亮操作(对 option 更新)
+        option.series[params.seriesIndex].parametricEquation =
+          getParametricEquation(
+            startRatio,
+            endRatio,
+            isSelected,
+            isHovered,
+            k,
+            option.series[params.seriesIndex].pieData.value + 5
+          );
+        option.series[params.seriesIndex].pieStatus.hovered = isHovered;
+
+        // 记录上次高亮的扇形对应的系列号 seriesIndex
+        hoveredIndex = params.seriesIndex;
+      }
+
+      // 使用更新后的 option,渲染图表
+      chart.setOption(option);
+    }
+  });
+
+  // 修正取消高亮失败的 bug
+  chart.on("globalout", function () {
+    if (hoveredIndex !== "") {
+      // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
+      isSelected = option.series[hoveredIndex].pieStatus.selected;
+      isHovered = false;
+      k = option.series[hoveredIndex].pieStatus.k;
+      startRatio = option.series[hoveredIndex].pieData.startRatio;
+      endRatio = option.series[hoveredIndex].pieData.endRatio;
+
+      // 对当前点击的扇形,执行取消高亮操作(对 option 更新)
+      option.series[hoveredIndex].parametricEquation = getParametricEquation(
+        startRatio,
+        endRatio,
+        isSelected,
+        isHovered,
+        k,
+        option.series[hoveredIndex].pieData.value
+      );
+      option.series[hoveredIndex].pieStatus.hovered = isHovered;
+
+      // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
+      hoveredIndex = "";
+    }
+
+    // 使用更新后的 option,渲染图表
+    chart.setOption(option);
+  });
+
+  if (option && typeof option === "object") {
+    chart.setOption(option);
+  }
+});
+
+// 生成扇形的曲面参数方程
+function getParametricEquation(
+  startRatio,
+  endRatio,
+  isSelected,
+  isHovered,
+  k,
+  h
+) {
+  // 计算
+  const midRatio = (startRatio + endRatio) / 2;
+  const startRadian = startRatio * Math.PI * 2;
+  const endRadian = endRatio * Math.PI * 2;
+  const midRadian = midRatio * Math.PI * 2;
+
+  // 如果只有一个扇形,则不实现选中效果。
+  if (startRatio === 0 && endRatio === 1) {
+    // eslint-disable-next-line no-param-reassign
+    isSelected = false;
+  }
+
+  // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
+  // eslint-disable-next-line no-param-reassign
+  k = typeof k !== "undefined" ? k : 1 / 3;
+
+  // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
+  const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
+  const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
+
+  // 计算高亮效果的放大比例(未高亮,则比例为 1)
+  const hoverRate = isHovered ? 1.05 : 1;
+
+  // 返回曲面参数方程
+  return {
+    u: {
+      min: -Math.PI,
+      max: Math.PI * 3,
+      step: Math.PI / 32,
+    },
+
+    v: {
+      min: 0,
+      max: Math.PI * 2,
+      step: Math.PI / 20,
+    },
+
+    x(u, v) {
+      if (u < startRadian) {
+        return (
+          offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
+        );
+      }
+      if (u > endRadian) {
+        return (
+          offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
+        );
+      }
+      return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
+    },
+
+    y(u, v) {
+      if (u < startRadian) {
+        return (
+          offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
+        );
+      }
+      if (u > endRadian) {
+        return (
+          offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
+        );
+      }
+      return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
+    },
+
+    z(u, v) {
+      if (u < -Math.PI * 0.5) {
+        return Math.sin(u);
+      }
+      if (u > Math.PI * 2.5) {
+        return Math.sin(u) * h * 0.1;
+      }
+      // 当前图形的高度是Z根据h(每个value的值决定的)
+      return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
+    },
+  };
+}
+// 生成模拟 3D 饼图的配置项
+function getPie3D(pieData, internalDiameterRatio) {
+  const series = [];
+  // 总和
+  let sumValue = 0;
+  let startValue = 0;
+  let endValue = 0;
+  const legendData = [];
+  const k =
+    typeof internalDiameterRatio !== "undefined"
+      ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
+      : 1 / 3;
+  // 为每一个饼图数据,生成一个 series-surface 配置
+  for (let i = 0; i < pieData.length; i += 1) {
+    sumValue += pieData[i].value;
+    // console.log(pieData[i].name);
+    const seriesItem = {
+      name:
+        typeof pieData[i].name === "undefined" ? `series${i}` : pieData[i].name,
+      type: "surface",
+      parametric: true,
+      wireframe: {
+        show: false,
+      },
+      pieData: pieData[i],
+      pieStatus: {
+        selected: false,
+        hovered: false,
+        k,
+      },
+    };
+    if (typeof pieData[i].itemStyle !== "undefined") {
+      const { itemStyle } = pieData[i];
+      typeof pieData[i].itemStyle.color !== "undefined"
+        ? (itemStyle.color = pieData[i].itemStyle.color)
+        : null;
+      typeof pieData[i].itemStyle.opacity !== "undefined"
+        ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
+        : null;
+      seriesItem.itemStyle = itemStyle;
+    }
+    series.push(seriesItem);
+  }
+  // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
+  // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
+  for (let i = 0; i < series.length; i += 1) {
+    endValue = startValue + series[i].pieData.value;
+    series[i].pieData.startRatio = startValue / sumValue;
+    series[i].pieData.endRatio = endValue / sumValue;
+    series[i].parametricEquation = getParametricEquation(
+      series[i].pieData.startRatio,
+      series[i].pieData.endRatio,
+      false,
+      false,
+      k,
+      // ,使除了第一个之外的值都是10
+      series[i].pieData.value
+    );
+    startValue = endValue;
+    legendData.push(series[i].name);
+  }
+  // 准备待返回的配置项,把准备好的 legendData、series 传入。
+  const option = {
+    color: [ "#5ef8c9", "#5ed3f8", "#EDE400"],
+    legend: {
+      // type: "scroll",
+      data: legendData,
+      icon: "roundRect",
+    //   orient: "vertical",
+      padding: 5,
+      itemGap: 20,
+      bottom:'5%',
+      left:'2%',
+      itemWidth: 10, // 设置宽度
+      itemHeight: 10, // 设置高度
+      selectedMode: true,
+      textStyle: {
+        color: "#FFFFFF",
+        fontSize: 14,
+        lineHeight: 14,
+        rich: {
+          a: {
+            // verticalAlign: "middle",
+          },
+        },
+        padding: [0, 0, -3, 0],
+      },
+    },
+    tooltip: {
+      formatter: (params) => {
+        if (params.seriesName !== "mouseoutSeries") {
+          return `${
+            params.seriesName
+          }<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
+            params.color
+          };"></span>${option.series[params.seriesIndex].pieData.value}`;
+        }
+        return "";
+      },
+    },
+    // title:[{
+    //     text: '单位:栋',
+    //     top: 8,
+    //     left: 10,
+    //     textStyle: {
+    //         fontSize: 12,
+    //         color:'#5ed3f8',
+    //     }
+    // }],
+    xAxis3D: {
+      min: -1,
+      max: 1,
+    },
+    yAxis3D: {
+      min: -1,
+      max: 1,
+    },
+    zAxis3D: {
+      min: -1,
+      max: "dataMax",
+    },
+    grid3D: {
+      show: false,
+      boxHeight: 16,
+      top: "-17%",
+      left: "0",
+      viewControl: {
+        // 3d效果可以放大、旋转等,请自己去查看官方配置
+        alpha: 27,
+        beta: 70, //旋转角度
+        rotateSensitivity: 1,
+        zoomSensitivity: 0,
+        panSensitivity: 0,
+        // autoRotate: true,
+        distance: 150,
+      },
+      // 后处理特效可以为画面添加高光、景深、环境光遮蔽(SSAO)、调色等效果。可以让整个画面更富有质感。
+      postEffect: {
+        // 配置这项会出现锯齿,请自己去查看官方配置有办法解决
+        enable: false,
+        bloom: {
+          enable: true,
+          bloomIntensity: 0.1,
+        },
+        SSAO: {
+          enable: true,
+          quality: "medium",
+          radius: 2,
+        },
+      },
+    },
+    series,
+  };
+  return option;
+}
+</script>
+
+<template>
+  <div class="container">
+    <div ref="pieChart3d" class="chart"></div>
+  </div>
+</template>
+
+<style scoped lang="less">
+.container {
+  width: 440px;
+  height: 264px;
+  position: relative;
+}
+
+.container::after {
+  content: "";
+  position: absolute;
+  width: 290px;
+  height: 198px;
+  background: url("../assets/images/1.png") no-repeat;
+  background-size: 100% 100%;
+//   left: calc(50% - 145px);
+  bottom: 10px;
+  left: 70px;
+}
+
+.container::before {
+  content: attr(data-num);
+  position: absolute;
+  font-size: 18px;
+  font-family: YouSheBiaoTiHei;
+  color: #ffffff;
+  line-height: 42px;
+  text-shadow: 0px 2px 6px rgba(0, 0, 0, 0.5);
+  left: 50%;
+  transform: translate(-50%);
+  top: 30%;
+}
+
+.chart {
+  width: 440px;
+  height: 100%;
+  position: relative;
+  z-index: 1;
+}
+</style>

+ 133 - 0
app/src/views/BasicInfo/components/BuildingInfo.vue

@@ -0,0 +1,133 @@
+<template>
+    <div class="building">
+        <div >
+            <div class="building-info">
+                <ul>
+                    <li>
+                        <span>建筑名称:</span>
+                        <p>重庆大剧院</p>
+                    </li>
+                    <li>
+                        <span>详细地址:</span>
+                        <p>江北区文华街东路2号</p>
+                    </li>
+                    <li>
+                        <span>建成年代:</span>
+                        <p>2009年</p>
+                    </li>
+                    <li>
+                        <span>消防安全管理形式:</span>
+                        <p>xxx</p>
+                    </li>
+                    <li>
+                        <span>管理主体:</span>
+                        <p>重庆大剧院管理有限公司</p>
+                    </li>
+                  
+                </ul>
+                <ul>
+                    <li>
+                        <span>建筑楼层:</span>
+                        <p>地上7层</p>
+                    </li>
+                    <li>
+                        <span>使用功能:</span>
+                        <p>公共建筑</p>
+                    </li>
+                    <li>
+                        <span>建筑面积:</span>
+                        <p>103307.10m²</p>
+                    </li>
+                    <li>
+                        <span>管理人联系:</span>
+                        <p>张三 13999999999</p>
+                    </li>
+                    <li>
+                        <span>是否有维保:</span>
+                        <p>是</p>
+                    </li>
+                </ul>
+            </div>
+            <div class="maintenance">
+              <span class="unit-info">维保单位:</span>
+              <p class="unit">张恒峰建筑消防维保有限公司</p>
+             </div>
+        </div>
+        <div class="unit-img">
+            <div>建筑附件:</div>
+            <div class="accessory-img">
+                <img src="../../../assets/images/Rectangle 3726.png" alt="">
+                <img src="../../../assets/images/Rectangle 3728.png" alt="">
+                <img src="../../../assets/images/Rectangle 3726.png" alt="">
+                <img src="../../../assets/images/Rectangle 3728.png" alt="">
+                <img src="../../../assets/images/Rectangle 3728.png" alt="">
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+export default{
+    methods:{}
+}
+</script>
+
+<style lang="less" scoped>
+.building{
+    padding: 20px 12px;
+    font-size: 14px;
+}
+.building-info{
+    display: flex;
+    // letter-spacing: 1px;
+    line-height: 31px;
+   
+    ul:first-child{
+        flex: 1;
+    }
+    ul:last-child{
+        width: 190px;
+    }
+    li{
+        overflow: hidden;
+    }
+    p{
+        display: inline-block;
+    }
+    span{
+        color: #78C3CD;
+        font-size: 12px;
+    }
+  
+}
+.maintenance{
+    display: flex;
+    margin-top: 10px;
+}
+.unit{
+       
+        font-size: 14px;
+        width: 200px;
+    }
+    .unit-info{
+        color: #78C3CD;
+        font-size: 12px;
+    }
+.unit-img{
+    display: flex;
+    flex-direction: column;
+    margin-top: 10px;
+    font-size: 12px;
+    color: #78C3CD;
+    img{
+        display: inline-block;
+        margin: 10px 5px;
+        width: 75px;
+        height: 57px;
+    }
+ .accessory-img{
+    display: flex;
+    overflow-x: scroll;
+ }
+}
+</style>

+ 70 - 0
app/src/views/BasicInfo/components/GementUnit.vue

@@ -0,0 +1,70 @@
+<template>
+    <div class="unit">
+        <!-- 管理单位 -->
+        <div>
+            <div class="building-info">
+                <ul>
+                    <li>
+                        <span>管理形式:</span>
+                        <p>有管理单位(非物业)</p>
+                    </li>
+                    <li>
+                        <span>所属管理:</span>
+                        <p>重庆大剧院管理有限公司</p>
+                    </li>
+                    <li>
+                        <span>消防安全联系人:</span>
+                        <p>王武</p>
+                    </li>
+                </ul>
+                <ul>
+                    <li>
+                        <span>消防安全责任人:</span>
+                        <p>李四</p>
+                    </li>
+                    <li>
+                        <span>消防安全管理人:</span>
+                        <p>王五</p>
+                    </li>
+                    <li>
+                        <span>联系方式:</span>
+                        <p>13556723998</p>
+                    </li>
+                </ul>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script >
+
+</script>
+
+<style lang="less" scoped>
+.unit{
+   padding: 10px 10px;
+.building-info{
+    display: flex;
+    // letter-spacing: 1px;
+    line-height: 31px;
+   
+    ul:first-child{
+        flex: 1;
+    }
+    ul:last-child{
+        width: 190px;                          
+    }
+    li{
+        overflow: hidden;
+    }
+    p{
+        font-size: 14px;
+        display: inline-block;
+    }
+    span{
+        color: #78C3CD;
+        font-size: 12px;
+    }
+}
+}
+</style>

+ 44 - 0
app/src/views/BasicInfo/components/Risklevel.vue

@@ -0,0 +1,44 @@
+<template>
+    <div class="level">
+    <!-- 风险等级 -->
+    <div style="font-size: 18px;">主要风险点</div>
+    <div class="level-btn">
+        <span>疏通管道拥堵</span>
+        <span>火灾隐患</span>
+    </div>
+    <div>
+        <img src="../../../assets/images/image 13.png" alt="">
+    </div>
+    </div>
+</template>
+
+<script >
+
+</script>
+
+<style lang="less" scoped>
+.level{
+    padding: 12px 10px;
+    .level-btn{
+        margin-top: 12px;
+        span{
+            display: inline-block;
+            width: 90px;
+            height: 25px;
+            background:#F18787 ;
+            font-size: 14px;
+            color: #fff;
+            line-height: 25px;
+            text-align: center;
+            margin-right: 10px;
+            border-radius: 2px;
+        }
+    }
+    img{
+        display: inline-block;
+        width: 131px;
+        height: 131px;
+        margin-top: 10px;
+    }
+}
+</style>

+ 27 - 0
app/src/views/BasicInfo/components/VideoInfo.vue

@@ -0,0 +1,27 @@
+<template>
+    <div class="video-list">
+        <!-- 视频 -->
+        <div>
+            <img src="../../../assets/images/Group 1321314647.png" alt="">
+            <img src="../../../assets/images/Group 1321314649.png" alt="">
+            <img src="../../../assets/images/Group 1321314650.png" alt="">
+            <img src="../../../assets/images/Group 1321314651.png" alt="">
+        </div>
+        <div>
+            <Monitor3D/>
+        </div>
+    </div>
+</template>
+
+<script >
+import Monitor3D from '@/components/Monitor3D.vue'
+export default{
+components:{Monitor3D}
+}
+</script>
+
+<style lang="less" scoped>
+.video-list{
+    padding: 10px 10px;
+}
+</style>

+ 11 - 2
app/src/views/BasicInfo/index.vue

@@ -8,14 +8,18 @@
             style="margin-bottom: 6px"
             title="建筑信息"
           >
+          <BuildingInfo/>
           </border-panel>
           <border-panel
             height="310px"
             style="margin-bottom: 6px"
             title="管理单位"
           >
+          <GementUnit/>
           </border-panel>
           <border-panel height="270px" title="风险等级">
+            <!-- 风险等级 -->
+            <Risklevel/>
           </border-panel>
         </div>
       <div style="display: flex; flex-direction: column;">
@@ -44,6 +48,7 @@
             style="margin-bottom: 6px"
             title="智慧消防"
           >
+          <VideoInfo/>
           </border-panel>
           <border-panel
             height="421px"
@@ -55,9 +60,13 @@
   </div>
 </template>
 <script>
-
+import BuildingInfo from './components/BuildingInfo.vue'
+import VideoInfo from './components/VideoInfo.vue'
+import GementUnit from './components/GementUnit.vue'
+import Risklevel from './components/Risklevel.vue'
 export default {
-  name: 'BasicInfoPage'
+  name: 'BasicInfoPage',
+  components: {BuildingInfo,VideoInfo,GementUnit,Risklevel}
 }
 </script>