he wei
2025-05-21 4f2e7984e3f63ac3b869f7301cda7e74914922a1
U 修改
12个文件已修改
1个文件已删除
10个文件已添加
983 ■■■■■ 已修改文件
src/assets/images/bg_bottom.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/bg_bottom0.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/img-acdc.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/img-batt.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/img-charge.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/img-hr.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/page-header.png 补丁 | 查看 | 原始文档 | blame | 历史
src/components/card.vue 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/globalComponents.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/AppMain.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/index.vue 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/modules/datas.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/modules/general.js 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/YouSheBiaoTiHei-2.ttf 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/blue.css 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/blue.less 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/index.css 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/index.less 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/datas/device.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/realtime/index.vue 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/realtime/tabs/power.vue 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/realtime/tabs/system.vue 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/bg_bottom.png

src/assets/images/bg_bottom0.png
src/assets/images/img-acdc.png
src/assets/images/img-batt.png
src/assets/images/img-charge.png
src/assets/images/img-hr.png
src/assets/images/page-header.png
Binary files differ
src/components/card.vue
New file
@@ -0,0 +1,58 @@
<script setup name="Card">
import { ref } from "vue";
const props = defineProps({
  title: {
    type: String,
    default: ''
  }
});
</script>
<template>
  <div class="card pos-r">
    <div class="title ys-title" v-if="title">{{ title }}</div>
    <div class="tools">
      <slot name="tools"></slot>
    </div>
    <div class="content pos-r">
      <div class="pos-full">
        <slot></slot>
      </div>
    </div>
  </div>
</template>
<style scoped lang="less">
  .card {
    height: 100%;
    padding: 6px;
    display: flex;
    flex-direction: column;
    background: linear-gradient(#62cee3, #62cee3) left top e('/') 16px 1px no-repeat,
          linear-gradient(#62cee3, #62cee3) left top e('/') 1px 16px no-repeat,
          linear-gradient(#62cee3, #62cee3) right top e('/') 16px 1px no-repeat,
          linear-gradient(#62cee3, #62cee3) right top e('/') 1px 16px no-repeat,
          linear-gradient(#62cee3, #62cee3) left bottom e('/') 16px 1px no-repeat,
          linear-gradient(#62cee3, #62cee3) left bottom e('/') 1px 16px no-repeat,
          linear-gradient(#62cee3, #62cee3) right bottom e('/') 16px 1px no-repeat,
          linear-gradient(#62cee3, #62cee3) right bottom e('/') 1px 16px no-repeat,
          radial-gradient(farthest-side at center center, transparent, transparent 50%, rgba(25,59,99, 0.3) 100%, #193B63 180%, #193B63) left top e('/') contain no-repeat
          ;
    .title {
      padding-left: 1.4em;
      background: url("@/assets/images/tb1.png") 6px center e('/') auto 82% no-repeat;
    }
    .tools {
      position: absolute;
      top: 6px;
      right: 6px;
    }
    .content {
      flex: 1;
    }
  }
</style>
src/globalComponents.js
@@ -1,7 +1,7 @@
// import hdwTree from '@/components/HdwTree/index.vue';
// import ycCard from '@/components/ycCard/index.vue';
import card from '@/components/card.vue';
import ycCard from '@/components/ycCard/index.vue';
export function registerGlobalComponents(app) {
  // app.component('hdwTree', hdwTree);
  // app.component('ycCard', ycCard);
  app.component('card', card);
  app.component('ycCard', ycCard);
}
src/layout/components/AppMain.vue
@@ -16,15 +16,17 @@
import { storeToRefs } from 'pinia';
const tagsViewStore = useTagsViewStore();
const { cachedViews } = storeToRefs(tagsViewStore);
</script>
<style lang="less" scoped>
.app-main {
  /* 50= navbar  50  */
  min-height: calc(100vh - 148px);
  // min-height: calc(100vh - 148px);
  width: 100%;
  position: relative;
  overflow: hidden;
  z-index: 0;
}
.fixed-header+.app-main {
@@ -34,7 +36,23 @@
.hasTagsView {
  .app-main {
    /* 84 = navbar + tags-view = 50 + 34 */
    height: 100vh;
    // height: 100vh;
    height: calc(100vh - 148px);
    background: url("@/assets/images/bg-side.png") calc(100% + 8px) top e('/') auto 80% no-repeat;
    // position: relative;
    z-index: 0;
    &::before {
      content: '';
      position: absolute;
      z-index: -1;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      transform: scaleX(-1);
      background: url("@/assets/images/bg-side.png") calc(100% + 8px) top e('/') auto 80% no-repeat;
    }
  }
  // .fixed-header+.app-main {
src/layout/index.vue
@@ -1,18 +1,20 @@
<template>
  <div :class="classObj" class="app-wrapper">
    <div
    <!-- <div
      v-if="device === 'mobile' && sidebar.opened"
      class="drawer-bg"
      @click="handleClickOutside"
    />
    /> -->
    <!--    <sidebar class="sidebar-container" />-->
    <div :class="{ hasTagsView: needTagsView }" class="main-container">
      <div :class="{ 'fixed-header': fixedHeader }">
        <navbar />
        <tags-view v-if="needTagsView" />
        <!-- <TestTagsView /> -->
      </div>
      <app-main />
      <tags-view class="tags-view" v-if="needTagsView" />
      <div class="main-wrap pos-r">
        <app-main class="app-main pos-full" />
      </div>
      <!-- <right-panel v-if="showSettings">
          <settings />
        </right-panel> -->
@@ -139,7 +141,7 @@
  position: fixed;
  top: 0;
  right: 0;
  z-index: 9;
  z-index: 0;
  width: calc(100%);
  transition: width 0.28s;
}
@@ -151,4 +153,16 @@
.mobile .fixed-header {
  width: 100%;
}
.main-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  .tags-view {
    margin-top: 120px;
  }
  .main-wrap {
    flex: 1;
  }
}
</style>
src/router/modules/datas.js
@@ -11,6 +11,12 @@
  },
  children: [
    {
      path: 'realtime',
      component: () => import('@/views/realtime/index.vue'),
      name: 'realtime',
      meta: { title: '实时监测', icon: 'component', noCache: false }
    },
    {
      path: 'device',
      component: () => import('@/views/datas/device.vue'),
      name: 'device',
src/router/modules/general.js
@@ -16,24 +16,24 @@
    //   name: 'AuthManage',
    //   meta: { title: '授权管理', icon: 'auth-hdw', noCache: false }
    // },
    {
      path: 'log',
      component: () => import('@/views/general/log/index.vue'),
      name: 'LogManage',
      meta: { title: '锁具日志', icon: 'log-hdw', noCache: false }
    },
    // {
    //   path: 'log',
    //   component: () => import('@/views/general/log/index.vue'),
    //   name: 'LogManage',
    //   meta: { title: '锁具日志', icon: 'log-hdw', noCache: false }
    // },
    {
      path: 'alarm-rt',
      component: () => import('@/views/general/alarm/alarmRt.vue'),
      name: 'alarmRt',
      meta: { title: '实时告警', icon: 'log-hdw', noCache: false }
    },
    {
      path: 'alarm-his',
      component: () => import('@/views/general/alarm/alarmHis.vue'),
      name: 'alarmHis',
      meta: { title: '历史告警', icon: 'log-hdw', noCache: false }
    },
    // {
    //   path: 'alarm-his',
    //   component: () => import('@/views/general/alarm/alarmHis.vue'),
    //   name: 'alarmHis',
    //   meta: { title: '历史告警', icon: 'log-hdw', noCache: false }
    // },
    // {
    //   path: 'map',
    //   component: () => import('@/views/general/map/index.vue'),
src/styles/YouSheBiaoTiHei-2.ttf
Binary files differ
src/styles/blue.css
@@ -25,7 +25,6 @@
  border-top: 2px solid #2f517f;
  border-bottom: 2px solid #2f517f;
  height: auto;
  margin-top: 2px;
}
html.blue-theme #app .tags-view-container .tags-view-wrapper .tags-view-item {
  color: #ffffff;
@@ -122,6 +121,14 @@
}
html.blue-theme .page-content .el-table {
  background: transparent;
}
html.blue-theme .ys-title {
  font-family: 'YouSheBiaoTiHei';
}
html.blue-theme .panel-title {
  font-family: 'YouSheBiaoTiHei';
  padding-left: 1.4em;
  background: url("@/assets/images/tb1.png") 6px center / auto 82% no-repeat;
}
.el-tree.el-tree.el-tree {
  color: #1fcbe1;
@@ -234,3 +241,27 @@
  text-align: right;
  padding-right: 10px;
}
.pos-r {
  position: relative;
}
.pos-full.pos-full.pos-full {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.page-contain {
  height: 100%;
}
.page-contain.bg-footer {
  background: url("@/assets/images/bg_bottom.png") center calc(100% - 20px) / 100% auto no-repeat;
}
.page-contain .page-main {
  padding-left: 20px;
  padding-right: 20px;
}
@font-face {
  font-family: "YouSheBiaoTiHei";
  src: url(YouSheBiaoTiHei-2.ttf) format("truetype");
}
src/styles/blue.less
@@ -45,7 +45,7 @@
      border-bottom: 2px solid #2f517f;
      // border-bottom: 1px solid #164973;
      height: auto;
      margin-top: 2px;
      // margin-top: 2px;
      .tags-view-wrapper {
        .tags-view-item {
          &:first-of-type {
@@ -161,6 +161,16 @@
    .el-table {
      background: transparent;
    }
  }
  .ys-title {
    font-family: 'YouSheBiaoTiHei';
  }
  .panel-title {
    font-family: 'YouSheBiaoTiHei';
    padding-left: 1.4em;
    background: url("@/assets/images/tb1.png") 6px center e('/') auto 82% no-repeat;
  }
}
@@ -293,3 +303,31 @@
    padding-right: 10px;
  }
}
.pos-r {
  position: relative;
}
.pos-full.pos-full.pos-full {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.page-contain {
  height: 100%;
  &.bg-footer {
    background: url("@/assets/images/bg_bottom.png") center calc(100% - 20px) e('/') 100% auto no-repeat;
  }
  .page-main {
    padding-left: 20px;
    padding-right: 20px;
  }
  // background: gray;
}
@font-face {
  font-family: "YouSheBiaoTiHei";
  src: url(./YouSheBiaoTiHei-2.ttf) format("truetype");
}
src/styles/index.css
@@ -168,6 +168,273 @@
  background: #99a9bf;
  border-radius: 20px;
}
html.blue-theme #app {
  --base-color: #4ba1fa;
  --light-color: #00feff;
  --bg-color: #072d44;
  --el-text-color-placeholder: #4ba1fa;
  --el-fill-color-lighter: #1F3C64;
  --border-light-color: #143a92;
  --filter-input-border-color: rgba(255, 227, 41, 0.2);
  --el-dialog-bg-color: var(--bg-color);
}
html.blue-theme #app .el-drawer__body {
  padding: 0;
}
html.blue-theme #app .app-wrapper {
  background: #071426;
}
html.blue-theme #app .scroll-container .el-scrollbar__wrap {
  height: auto;
}
html.blue-theme #app .app-breadcrumb.el-breadcrumb .no-redirect {
  color: #4ba1fa;
}
html.blue-theme #app .tags-view-container {
  box-sizing: border-box;
  border-top: 2px solid #2f517f;
  border-bottom: 2px solid #2f517f;
  height: auto;
}
html.blue-theme #app .tags-view-container .tags-view-wrapper .tags-view-item {
  color: #ffffff;
  height: 32px;
  line-height: 32px;
  padding: 0 16px;
  border: 0;
  margin-left: 0;
  margin-top: 0;
  background: none;
}
html.blue-theme #app .tags-view-container .tags-view-wrapper .tags-view-item:first-of-type {
  margin-left: 0;
}
html.blue-theme #app .tags-view-container .tags-view-wrapper .tags-view-item.router-link-exact-active {
  background-color: #004986;
  border-color: #004986;
  color: #fff;
}
html.blue-theme #app .hdw-card {
  box-sizing: border-box;
  color: #ffffff;
}
html.blue-theme .el-tree {
  --el-tree-node-content-height: 26px;
  --el-tree-node-hover-bg-color: #214865;
  --el-tree-text-color: var(--el-text-color-regular);
  --el-tree-expand-icon-color: #1FCBE1;
  background: none;
  color: #ffffff;
  cursor: default;
  font-size: var(--el-font-size-base);
  position: relative;
}
html.blue-theme .el-tree .is-current > .el-tree-node__content.el-tree-node__content {
  background: #214865;
}
html.blue-theme .el-tree .is-current > .el-tree-node__content.el-tree-node__content .el-text {
  color: #fff;
}
html.blue-theme .el-tree .is-current > .el-tree-node__content.el-tree-node__content:hover .el-text {
  color: #fff;
}
html.blue-theme .el-table {
  --el-table-border-color: none;
  --el-table-border: 0;
  --el-table-text-color: var(--el-text-color-regular);
  --el-table-header-text-color: #fff;
  --el-table-row-hover-bg-color: #1a5a8b;
  --el-table-current-row-bg-color: var(--el-color-primary-light-9);
  --el-table-header-bg-color: #1F3C64;
  --el-table-fixed-box-shadow: var(--el-box-shadow-light);
  --el-table-bg-color: var(--bg-color);
  --el-table-tr-bg-color: #0D2B4D;
  --el-table-expanded-cell-bg-color: var(--el-fill-color-blank);
  --el-table-index: var(--el-index-normal);
  background-color: var(--bg-color);
  color: #ffffff;
}
html.blue-theme .tools-filter .el-input {
  --el-input-text-color: #ffe329;
  --el-input-border: var(--el-border);
  --el-input-hover-border: var(--el-border-color-hover);
  --el-input-focus-border: var(--el-color-primary);
  --el-input-transparent-border: 0 0 0 1px transparent inset;
  --el-input-border-color: var(--filter-input-border-color);
  --el-input-border-radius: var(--el-border-radius-base);
  --el-input-bg-color: var(--filter-input-border-color);
  --el-input-icon-color: var(--el-text-color-placeholder);
  --el-input-placeholder-color: #ffe32990;
  --el-input-hover-border-color: var(--el-border-color-hover);
  --el-input-clear-hover-color: var(--el-text-color-secondary);
  --el-input-focus-border-color: var(--el-color-primary);
}
html.blue-theme .tools-filter .el-select {
  --el-select-border-color-hover: var(--el-border-color-hover);
  --el-select-disabled-color: var(--el-disabled-text-color);
  --el-select-disabled-border: var(--el-disabled-border-color);
  --el-select-font-size: var(--el-font-size-base);
  --el-select-close-hover-color: var(--el-text-color-secondary);
  --el-select-input-color: #ffe329;
  --el-select-multiple-input-color: var(--el-text-color-regular);
  --el-select-input-focus-border-color: var(--el-color-primary);
}
html.blue-theme .tools-filter .el-select .el-select__wrapper {
  background-color: var(--filter-input-border-color);
  box-shadow: 0 0 0 1px var(--filter-input-border-color) inset;
}
html.blue-theme .tools-filter .el-select .el-select__wrapper .el-select__placeholder {
  color: #ffe329;
}
html.blue-theme .page-content {
  padding-bottom: 20px;
}
html.blue-theme .page-content .el-table {
  background: transparent;
}
html.blue-theme .ys-title {
  font-family: 'YouSheBiaoTiHei';
}
html.blue-theme .panel-title {
  font-family: 'YouSheBiaoTiHei';
  padding-left: 1.4em;
  background: url("@/assets/images/tb1.png") 6px center / auto 82% no-repeat;
}
.el-tree.el-tree.el-tree {
  color: #1fcbe1;
}
.el-tabs--border-card > .el-tabs__header.el-tabs__header {
  border-bottom: 1px solid #00fefe;
  background-color: #00243e;
}
.el-tabs--border-card > .el-tabs__header.el-tabs__header .el-tabs__item {
  color: #00fefe;
}
.el-tabs--border-card > .el-tabs__header.el-tabs__header .el-tabs__item.is-active {
  background-color: #00fefe;
  border-color: #00fefe;
  color: #041f6c;
}
.el-pagination__sizes.el-pagination__sizes,
.el-pagination__total.el-pagination__total {
  color: #fff;
  font-size: 16px;
}
.el-pagination .el-select__wrapper.el-select__wrapper {
  background-color: #134BA8;
  color: #fff;
  box-shadow: 0 0 0 1px #436DA8 inset;
}
.el-pagination .el-select__wrapper.el-select__wrapper .el-select__placeholder,
.el-pagination .el-select__wrapper.el-select__wrapper .el-select__input {
  color: #fff;
}
.el-pagination.el-pagination.el-pagination button {
  background: transparent;
  color: #fff;
}
.el-pagination.el-pagination.el-pagination button.is-disabled,
.el-pagination.el-pagination.el-pagination button:disabled {
  background-color: transparent;
  color: #fff;
  cursor: not-allowed;
}
.el-pagination .el-pager.el-pager.el-pager li {
  background: transparent;
  color: #fff;
}
.el-pagination .el-pager.el-pager.el-pager li.is-active,
.el-pagination .el-pager.el-pager.el-pager li:hover {
  color: #529ac1;
}
.el-pagination__jump.el-pagination__jump {
  color: #fff;
}
.el-pagination__jump.el-pagination__jump .el-input__wrapper {
  background-color: #134BA8;
  box-shadow: 0 0 0 1px #436DA8 inset;
}
.el-pagination__jump.el-pagination__jump .el-input__wrapper .el-input__inner {
  color: #fff;
}
.el-tree-node:focus > .el-tree-node__content.el-tree-node__content {
  background: transparent;
}
.el-tabs--border-card.el-tabs--border-card {
  background: transparent;
  border: 0 none;
}
.el-button.el-button:focus-visible {
  outline: none;
}
.el-tooltip__popper.el-tooltip__popper {
  z-index: 9999;
  /* 设置较高的 z-index */
}
.el-transfer .el-checkbox__input.is-indeterminate .el-checkbox__inner,
.el-transfer .el-checkbox__input.is-checked .el-checkbox__inner {
  background-color: #46CAFE;
  border-color: #46CAFE;
}
.el-transfer .el-checkbox__input.is-indeterminate .el-checkbox__inner::before,
.el-transfer .el-checkbox__input.is-checked .el-checkbox__inner::before {
  background-color: #333;
}
.el-transfer .el-checkbox__input.is-indeterminate .el-checkbox__inner::after,
.el-transfer .el-checkbox__input.is-checked .el-checkbox__inner::after {
  border-color: #333;
}
.page-filter {
  display: table;
  border-bottom: 1px solid #304A75;
  margin-top: 8px;
  padding: 6px;
  margin-bottom: 6px;
}
.page-filter .el-select__wrapper.el-select__wrapper {
  background-color: #103047;
  color: #48A5D0;
  box-shadow: 0 0 0 1px #103047 inset;
}
.page-filter .el-select__placeholder {
  color: #48a5d0;
}
.page-filter .table-row {
  display: table-row;
}
.page-filter .table-row .table-cell {
  display: table-cell;
  white-space: nowrap;
  color: #48A5D0;
}
.page-filter .table-cell.text-right {
  text-align: right;
  padding-right: 10px;
}
.pos-r {
  position: relative;
}
.pos-full.pos-full.pos-full {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.page-contain {
  height: 100%;
}
.page-contain.bg-footer {
  background: url("@/assets/images/bg_bottom.png") center calc(100% - 20px) / 100% auto no-repeat;
}
.page-contain .page-main {
  padding-left: 20px;
  padding-right: 20px;
}
@font-face {
  font-family: "YouSheBiaoTiHei";
  src: url(YouSheBiaoTiHei-2.ttf) format("truetype");
}
body {
  height: 100%;
  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
@@ -176,6 +443,7 @@
  text-rendering: optimizeLegibility;
  margin: 0;
  color: #ffffff;
  overflow: hidden;
}
label {
  font-weight: 700;
src/styles/index.less
@@ -18,6 +18,7 @@
  text-rendering: optimizeLegibility;
  margin: 0;
  color: #ffffff;
  overflow: hidden;
}
label {
src/views/dashboard/index.vue
@@ -3,7 +3,7 @@
</script>
<template>
  <div class="dashboard-wrapper">
  <div class="page-contain bg-footer">
    首页
  </div>
</template>
src/views/datas/device.vue
@@ -507,8 +507,8 @@
    // border-top: 1px solid var(--border-light-color);
    box-sizing: border-box;
    flex: 1;
    margin-left: 18px;
    margin-right: 18px;
    margin-left: 26px;
    margin-right: 26px;
  }
  .page-content-page {
src/views/realtime/index.vue
New file
@@ -0,0 +1,187 @@
<script setup>
import { ref, reactive } from "vue";
import tabPower from "./tabs/power.vue";
import tabSystem from "./tabs/system.vue";
const statusList = reactive([
    { label: '系统状态', value: '充电' },
    { label: '设备状态', value: '正常' },
    { label: '电源状态', value: '正常' },
    { label: '电池状态', value: '正常' },
    { label: '母线电压', value: 60 },
    { label: '在线电压', value: 60 },
    { label: '组端电压', value: 60 },
    { label: '电池电流', value: 60 },
    { label: '测试时长', value: 60 },
    { label: '测试容量', value: 60 },
    { label: '预估剩余容量', value: 60 },
    { label: '预估剩余续航', value: 60 },
    { label: '告警', value: '无' },
    { label: '更新日期', value: '2022-01-01' },
]);
const tabs = ref([
    { label: '系统概览', name: 'system' },
    { label: '电源', name: 'power' },
    { label: '电压', name: 'vol' },
    { label: '内阻', name: 'res' },
    { label: '温度', name: 'temp' },
    { label: '3D', name: '3d' },
    { label: '自愈能力', name: 'self' },
    { label: '管理信息', name: 'manage' },
    { label: '电源告警参数设置', name: 'powerAlarmSet' },
    { label: '电池告警参数设置', name: 'battAlarmSet' },
    { label: '图片', name: 'img' },
    { label: '历史测试数据', name: 'history' },
    { label: '历史实时数据', name: 'hisRt' },
]);
const acTab = ref(tabs.value[0].name);
const fullName = ref('湖北省-武汉市-武昌区-武昌机房-电池组1');
function tabClick(item) {
    acTab.value = item.name;
}
</script>
<template>
  <div class="page-contain">
    <div class="page-header">
      <div class="p-title">{{ fullName }}</div>
      <div class="status-bar">
        <div
          :class="['status-item',]"
          v-for="(item, index) in statusList"
          :key="'status_' + index"
        >
          <div class="item-value">{{ item.value }}</div>
          <div class="item-name">{{ item.label }}</div>
        </div>
      </div>
      <div class="p-tabs">
        <div
          :class="['tab-item', {'active': item.name == acTab}]"
          v-for="(item, index) in tabs"
          :key="'tab_' + index"
          @click="tabClick(item)"
        >
          {{ item.label }}
        </div>
      </div>
    </div>
    <div class="page-main">
      <div class="tab-contain" v-if="acTab == 'system'">
        <tab-system></tab-system>
      </div>
      <div class="tab-contain" v-if="acTab == 'power'">
        <tab-power></tab-power>
      </div>
      <div class="tab-contain" v-if="acTab == 'vol'">2</div>
      <div class="tab-contain" v-if="acTab == 'res'">3</div>
      <div class="tab-contain" v-if="acTab == 'temp'">4</div>
      <div class="tab-contain" v-if="acTab == '3d'">5</div>
      <div class="tab-contain" v-if="acTab == 'self'">6</div>
      <div class="tab-contain" v-if="acTab == 'manage'">7</div>
      <div class="tab-contain" v-if="acTab == 'powerAlarmSet'">8</div>
      <div class="tab-contain" v-if="acTab == 'battAlarmSet'">9</div>
      <div class="tab-contain" v-if="acTab == 'img'">10</div>
      <div class="tab-contain" v-if="acTab == 'history'">11</div>
      <div class="tab-contain" v-if="acTab == 'hisRt'">12</div>
    </div>
  </div>
</template>
<style scoped lang="less">
.page-contain {
  display: flex;
  flex-direction: column;
  .page-header {
    // border: 1px solid #0ff;
    background: #071426;
    .p-title {
      font-size: 18px;
      font-weight: 700;
      color: #50c7f1;
      height: 42px;
      display: flex;
      justify-content: center;
      align-items: center;
      border-bottom: 1px solid #497AAB;
    }
    .status-bar {
      height: 72px;
      display: flex;
      flex-direction: row;
      .status-item {
        flex: 1;
        font-size: 14px;
        font-weight: 700;
        color: #50c7f1;
        // border: 1px solid #0F6B79;
        border-radius: 6px;
        margin: 4px 6px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        box-shadow: inset 0 0 30px -10px #0F6B79;
        background: radial-gradient(circle at -10% center, #1F6571 5%, transparent 20%) no-repeat,
            radial-gradient(circle at 110% center, #1F6571 5%, transparent 20%) no-repeat,
            radial-gradient(circle at center -72%, #1F6571 12%, transparent 50%) no-repeat,
            radial-gradient(circle at center 138%, #1F6571 12%, transparent 50%) no-repeat;
        .item-value {
          margin-bottom: 6px;
          color: #ff0;
          font-size: 20px;
        }
        .item-name {
          color: #6DCCE6;
        }
      }
    }
    .p-tabs {
      display: flex;
      flex-direction: row;
      height: 46px;
      border: 1px solid #426EA0;
      padding: 4px;
      .tab-item {
        font-size: 14px;
        font-weight: 700;
        flex: 1;
        display: flex;
        justify-content: center;
        align-items: center;
        margin-left: 2px;
        margin-right: 2px;
        background: #073451;
        cursor: pointer;
        &.active {
          background: #47CAFE;
          color: #03216e;
        }
      }
    }
  }
  .page-main {
    flex: 1;
    .tab-contain {
      height: 100%;
    }
  }
}
</style>
src/views/realtime/tabs/power.vue
New file
@@ -0,0 +1,96 @@
<script setup name="Power">
import { ref } from "vue";
const lineIdx = ref(0);
</script>
<template>
  <div class="tab-content">
    <div class="p-left">
      <div class="p-item">
        <card title="交流输入电压">
          <template #tools>
            <el-radio-group class="line-idx" v-model="lineIdx" size="small">
              <el-radio-button label="一路" :value="0" />
              <el-radio-button label="二路" :value="1" />
            </el-radio-group>
          </template>
        </card>
      </div>
      <div class="p-item">
        <card title="交流母线电压"></card>
      </div>
    </div>
    <div class="p-right">
      <div class="p-item">
        <card title="整流器开关状态"></card>
      </div>
      <div class="p-item large">
        <card title="整流器输出电流"></card>
      </div>
    </div>
  </div>
</template>
<style scoped lang="less">
.tab-content {
  display: flex;
  flex-direction: row;
  height: 100%;
  .p-left {
    flex: 1;
    display: flex;
    flex-direction: column;
    .p-item {
      flex: 1;
      margin: 8px;
    }
  }
  .p-right {
    flex: 1;
    display: flex;
    flex-direction: column;
    .p-item {
      flex: 1;
      margin: 8px;
      &.large {
        flex: 2;
      }
    }
  }
  .line-idx {
    :deep(.el-radio-button:first-child .el-radio-button__inner) {
      border-left: 1px solid #4D81BA;
      border-radius: 0;
      box-shadow: none !important;
    }
    // .el-radio-button--small .el-radio-button__inner {
    //     border-radius: 0;
    //     font-size: 12px;
    //     padding: 5px 11px;
    // }
    :deep(.el-radio-button__inner) {
        background: #183A55;
        border: 1px solid #4D81BA;
        border-left: 0;
        border-radius: 0;
        color: #fff;
        font-weight: 500;
        padding: 4px 10px;
    }
    :deep(.el-radio-button.is-active .el-radio-button__original-radio:not(:disabled)+.el-radio-button__inner) {
        background: linear-gradient(69deg, #6EABE4, #6EABE4 25%,  #0A3E77 75%, #0A3E77);
        // border: 0 none;
        box-shadow: none;
        color: #fff;
    }
  }
}
</style>
src/views/realtime/tabs/system.vue
New file
@@ -0,0 +1,210 @@
<script setup>
import { ref } from "vue";
</script>
<template>
  <div class="tab-content">
    <div class="row pos-r">
      <div class="pos-full row-content">
        <div class="p-left">
          <div class="p-item">
            <div class="panel-title">当前核容信息</div>
            <div class="panel">
              <div class="panel-row">
                <div class="label">失败原因</div>
                <div class="value">无</div>
              </div>
              <div class="panel-row">
                <div class="label">停止原因</div>
                <div class="value">无</div>
              </div>
            </div>
          </div>
          <div class="p-item">
            <div class="panel-title">当前核容信息</div>
            <div class="panel">
              <div class="panel-row">
                <div class="label">停止原因</div>
                <div class="value">无</div>
              </div>
              <div class="panel-row">
                <div class="label">停止原因</div>
                <div class="value">无</div>
              </div>
              <div class="panel-row">
                <div class="label">停止原因</div>
                <div class="value">无</div>
              </div>
              <div class="panel-row">
                <div class="label">停止原因</div>
                <div class="value">无</div>
              </div>
              <div class="panel-row">
                <div class="label">停止原因</div>
                <div class="value">无</div>
              </div>
            </div>
          </div>
        </div>
        <div class="p-main"></div>
        <div class="p-right">
          <div class="control-contain">
            <div class="control-title">控制管理</div>
            <div class="control-btn">核容测试</div>
            <div class="control-btn">停止核容测试</div>
          </div>
          <div class="control-contain">
            <div class="control-title">设备管理</div>
            <div class="control-btn">远程重启</div>
            <div class="control-btn">系统参数设置</div>
            <div class="control-btn">告警参数设置</div>
          </div>
          <div class="control-contain no-wrap">
            <div class="control-btn">放电申请</div>
          </div>
        </div>
      </div>
    </div>
    <div class="row row2">
      <div class="card-item">
        <card title="交流输入"></card>
      </div>
      <div class="card-item">
        <card title="直流输入"></card>
      </div>
      <div class="card-item">
        <card title="核容设备信息"></card>
      </div>
      <div class="card-item">
        <card title="蓄电池信息"></card>
      </div>
    </div>
  </div>
</template>
<style scoped lang="less">
.tab-content {
  height: 100%;
  padding-left: 8px;
  padding-right: 8px;
  display: flex;
  flex-direction: column;
  .row {
    flex: 1.52;
    .row-content {
      display: flex;
      flex-direction: row;
      height: 100%;
    }
    .p-left {
      width: 240px;
      display: flex;
      flex-direction: column;
      .p-item {
        margin: 8px;
        display: flex;
        flex-direction: column;
        .panel {
          border: 1px solid #5FA9CF;
          background: #073451;
          border-radius: 6px;
          padding: 10px 6px;
          margin-top: 6px;
          margin-bottom: 30px;
          font-size: 12px;
          display: flex;
          flex-direction: column;
          .panel-row {
            display: flex;
            flex-direction: row;
            margin-bottom: 4px;
            .label {
              flex: 0 0 6em;
              margin-right: 0.6em;
              text-align: right;
              &::after {
                content: ":";
              }
            }
            .value {
              flex: 1;
            }
          }
        }
      }
    }
    .p-main {
      flex: 1;
    }
    .p-right {
      width: 160px;
      margin-left: 20px;
      margin-right: 6px;
      padding-top: 20px;
      display: flex;
      flex-direction: column;
      .control-contain {
        display: flex;
        flex-direction: column;
        background: #08354F;
        border-radius: 6px 6px 0 0;
        margin-top: 6px;
        margin-bottom: 8px;
        padding-bottom: 4px;
        overflow: hidden;
        font-size: 12px;
        .control-title {
          background: #0B415D;
          font-size: 20px;
          padding: 6px 0;
          text-align: center;
          font-weight: 700;
          margin-bottom: 4px;
        }
        .control-btn {
          margin: 2px 4px;
          cursor: pointer;
          border: 1px solid #3D9CC9;
          box-shadow: inset 0 0 10px 4px #3D9CC9;
          padding: 6px 0;
          text-align: center;
          border-radius: 4px;
          &:hover {
            color: #FDFE01;
            border: 1px solid #DF7B26;
            box-shadow: inset 0 0 10px 4px #DF7B26;
          }
        }
        &.no-wrap {
          background: transparent;
          .control-btn {
            flex: 1;
            border: 1px solid #0BF9FE;
            color: #0bf9fe;
            font-weight: bold;
            font-size: 14px;
            box-shadow: inset 0 0 10px 4px #0BF9FE;
            &:hover {
              color: #FDFE01;
              border: 1px solid #DF7B26;
              box-shadow: inset 0 0 10px 4px #DF7B26;
            }
          }
        }
      }
    }
    &.row2 {
      flex: 1;
      margin-top: 4px;
      display: flex;
      flex-direction: row;
      .card-item {
        flex: 1;
        margin: 4px;
      }
    }
  }
}
</style>