hejianhao
2026-01-12 80e95f6ee12c15affd0f4023172d21296ba706e8
feat(login): 新增登录页面及账号选择功能

refactor(header): 重构头部组件样式和布局

style(assets): 更新图片资源和基础样式

chore(deps): 添加vue2-captcha依赖

fix(router): 调整路由配置和默认跳转逻辑

perf(assets): 移除未使用的图片和样式文件

docs(public): 更新AMap安全配置和API密钥
7个文件已删除
41个文件已添加
9个文件已修改
2799 ■■■■■ 已修改文件
screen/package.json 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/public/index.html 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/App.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/app.css 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/basics.less 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/13@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/15@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/25@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/@3x@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Combined Shape@2x (1).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Combined Shape@2x (2).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Combined Shape@2x (3).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Combined Shape@2x (4).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Combined Shape@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Group 24 Copy@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Group@2x (1).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Group@2x (2).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Group@2x (3).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Group@2x (4).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Rectangle@2x (1).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Rectangle@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x (1).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x (11).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x (2).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x (21).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x (3).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x (4).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x (5).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x (6).png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/Shape@2x1.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/headerBox.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/home/iconx.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/account.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/active.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/bgBox.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/bgTop.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/code.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/contentBg.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/eye-close.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/eye-open.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/noActive.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/password.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/login/titleBg.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/logo.jpg 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/assets/img/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/components/titleBox.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/router/index.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/center/index.vue 426 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/center/service.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/header/index.vue 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/home/index.vue 572 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/left/index.vue 430 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/left/service.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/login/index.vue 528 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/right/index.vue 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/view/right/service.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/package.json
@@ -29,6 +29,7 @@
    "vue-cookies": "^1.8.3",
    "vue-router": "^3.6.5",
    "vue2-animate": "^2.1.4",
    "vue2-captcha": "^0.1.0",
    "vuex-persistedstate": "^4.1.0",
    "xgplayer": "^3.0.14",
    "xgplayer-hls.js": "^3.0.14"
screen/public/index.html
@@ -9,16 +9,16 @@
  name="viewport"
  content="initial-scale=1.0, user-scalable=no, width=device-width"
/>
  <!-- <script type="text/javascript">
  <script type="text/javascript">
    window._AMapSecurityConfig = {
      securityJsCode: "0f56309d00434a4696f76730f62bc3e1",
      securityJsCode: "c75eccf0742998b2ea43823e08cacccd",
    };
  </script> -->
    <!-- <script src="https://cache.amap.com/lbs/static/es5.min.js"></script>
  </script>
    <script src="https://cache.amap.com/lbs/static/es5.min.js"></script>
  <script src="https://webapi.amap.com/loader.js"></script>
  <script src="https://webapi.amap.com/maps?v=2.0&key=5b704c602d3d6b13c2de2acaec7401cd&plugin=AMap.PolylineEditor"></script> -->
  <script src="https://webapi.amap.com/maps?v=2.0&key=232929db1cb31f26d42b3645a7456154&plugin=AMap.PolylineEditor"></script>
  <!-- <script type="text/javascript" src="https://cache.amap.com/lbs/static/addToolbar.js"></script> -->
  <!-- <script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script> -->
  <script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>
  <link rel="icon" href="./logo.png">
  <title>智慧工程安全监管平台</title>
</head>
screen/src/App.vue
@@ -21,7 +21,19 @@
      renderDom: '#app',
      resize: true,
    })
  }
  },
  created() {
    if (!localStorage.getItem('token')) {
      this.$router.replace('/home');
      // this.$router.replace('/');
      return
    } else {
      this.$router.replace({
        path: "/home",
        // query: { managementId: localStorage.getItem("managementId") },
      });
    }
  },
}
</script>
screen/src/assets/app.css
@@ -70,194 +70,6 @@
    font-weight: 600;
}
.w-10 {
    width: 10px;
}
.w-13 {
    width: 13px;
}
.w-19 {
    width: 19px;
}
.w-20 {
    width: 20px;
}
.w-21 {
    width: 21px;
}
.w-22 {
    width: 22px;
}
.w-23 {
    width: 23px;
}
.w-24 {
    width: 24px;
}
.w-25 {
    width: 25px;
}
.w-27 {
    width: 27px;
}
.w-56 {
    width: 56px;
}
.w-81 {
    width: 81px;
}
.w-90 {
    width: 90px;
}
.w-92 {
    width: 92px;
}
.w-102 {
    width: 102px;
}
.h-6 {
    height: 6px;
}
.h-13 {
    height: 13px;
}
.h-18 {
    height: 18px;
}
.h-19 {
    height: 19px;
}
.h20 {
    height: 20px;
}
.h-22 {
    height: 22px;
}
.h23 {
    height: 23px;
}
.h-24 {
    height: 24px;
}
.h-25 {
    height: 25px;
}
.h-27 {
    height: 27px;
}
.h-55 {
    height: 55px;
}
.ml-8 {
    margin-left: 8px;
}
.ml-9 {
    margin-left: 9px;
}
.ml-10 {
    margin-left: 10px;
}
.mt-4 {
    margin-top: 4px;
}
.mt-7 {
    margin-top: 7px;
}
.mt-8 {
    margin-top: 8px;
}
.mt-9 {
    margin-top: 9px;
}
.mt-10 {
    margin-top: 10px;
}
.mt-13 {
    margin-top: 13px;
}
.mt-14 {
    margin-top: 14px;
}
.mt-19 {
    margin-top: 19px;
}
.mt-20 {
    margin-top: 20px;
}
.mt-24 {
    margin-top: 24px;
}
.mr-6 {
    margin-right: 6px;
}
.mb-4 {
    margin-bottom: 4px;
}
.mb-15 {
    margin-bottom: 15px;
}
.mb-16 {
    margin-bottom: 16px;
}
.mb-24 {
    margin-bottom: 24px;
}
.mb-25 {
    margin-bottom: 25px;
}
.mt-25 {
    margin-top: 25px;
}
.j-center {
    justify-content: center;
}
@@ -268,50 +80,6 @@
.shrink0 {
    flex-shrink: 0;
}
.w-12 {
    width: 12px;
}
.h-18 {
    height: 18px;
}
.mr-2 {
    margin-right: 2px;
}
.mr-1 {
    margin-right: 1px;
}
.mr-4 {
    margin-right: 4px;
}
.pr-12 {
    padding-right: 12px;
}
.pl-12 {
    padding-left: 12px;
}
.pl-14 {
    padding-left: 14px;
}
.pl-35 {
    padding-left: 35px;
}
.pr-51 {
    padding-right: 51px;
}
.lh-17 {
    line-height: 17px;
}
.flex-warp {
@@ -370,10 +138,6 @@
    overflow: auto;
}
.w--600 {
    width: 600px;
}
.postion-center {
    top: 50%;
    left: 50%;
@@ -384,6 +148,22 @@
    cursor: pointer;
}
.top0 {
    top: 0;
.SHS {
    font-family: 'Source Han Sans CN Heavy';
}
.SHSBold {
    font-family: 'Source Han Sans CN Bold';
}
.ff54- {
    font-family: '54-';
}
.SHSR {
    font-family: 'Source Han Sans CN Regular';
}
.SHSM {
    font-family: 'Source Han Sans CN Medium';
}
screen/src/assets/basics.less
@@ -110,4 +110,7 @@
    .left--@{value} {
        left: (@value * 1px);
    }
    .letter--@{value} {
        letter-spacing: (@value * 1px);
    }
})
screen/src/assets/img/home/13@2x.png
screen/src/assets/img/home/15@2x.png
screen/src/assets/img/home/25@2x.png
screen/src/assets/img/home/@3x@2x.png
screen/src/assets/img/home/Combined Shape@2x (1).png
screen/src/assets/img/home/Combined Shape@2x (2).png
screen/src/assets/img/home/Combined Shape@2x (3).png
screen/src/assets/img/home/Combined Shape@2x (4).png
screen/src/assets/img/home/Combined Shape@2x.png
screen/src/assets/img/home/Group 24 Copy@2x.png
screen/src/assets/img/home/Group@2x (1).png
screen/src/assets/img/home/Group@2x (2).png
screen/src/assets/img/home/Group@2x (3).png
screen/src/assets/img/home/Group@2x (4).png
screen/src/assets/img/home/Rectangle@2x (1).png
screen/src/assets/img/home/Rectangle@2x.png
screen/src/assets/img/home/Shape@2x (1).png
screen/src/assets/img/home/Shape@2x (11).png
screen/src/assets/img/home/Shape@2x (2).png
screen/src/assets/img/home/Shape@2x (21).png
screen/src/assets/img/home/Shape@2x (3).png
screen/src/assets/img/home/Shape@2x (4).png
screen/src/assets/img/home/Shape@2x (5).png
screen/src/assets/img/home/Shape@2x (6).png
screen/src/assets/img/home/Shape@2x.png
screen/src/assets/img/home/Shape@2x1.png
screen/src/assets/img/home/headerBox.png
screen/src/assets/img/home/iconx.png
screen/src/assets/img/login/account.png
screen/src/assets/img/login/active.png
screen/src/assets/img/login/bgBox.png
screen/src/assets/img/login/bgTop.png
screen/src/assets/img/login/code.png
screen/src/assets/img/login/contentBg.png
screen/src/assets/img/login/eye-close.png
screen/src/assets/img/login/eye-open.png
screen/src/assets/img/login/noActive.png
screen/src/assets/img/login/password.png
screen/src/assets/img/login/titleBg.png
screen/src/assets/img/logo.jpg
Binary files differ
screen/src/assets/img/logo.png
screen/src/components/titleBox.vue
@@ -1,5 +1,19 @@
<template>
  <div class="titleBox">
  <div class="relative bgcolor1">
    <div class="h--39"></div>
    <div class="titleBox">
      <div class="name">
        <slot name="title"></slot>
      </div>
      <template v-if="$slots.right">
        <div class="right">
          <slot name="right"></slot>
        </div>
      </template>
    </div>
    <template v-if="$slots.content">
      <slot name="content"></slot>
    </template>
  </div>
</template>
@@ -8,16 +22,47 @@
  props: {
    isDetail: {
      type: Boolean,
      default: false
    }
      default: false,
    },
  },
  methods: {
    handleClick() {
      this.$emit('handleClick');
    }
  }
}
      this.$emit("handleClick");
    },
  },
};
</script>
<style scoped lang="less">
.titleBox {
  position: absolute;
  top: -20px;
  background-image: url("../assets/img/home/Group@2x (1).png");
  background-size: 100% 100%;
  width: 100%;
  height: 59px;
  display: flex;
  justify-content: space-between;
  .name {
    font-family: "Source Han Sans CN Bold";
    font-weight: 800;
    font-size: 22px;
    color: #f0faff;
    line-height: 22px;
    letter-spacing: 4px;
    padding: 27px 0 0 34px;
    width: fit-content;
  }
  .right {
    margin-top: 27px;
    margin-right: 10px;
  }
}
.bgcolor1 {
  background: rgba(2, 0, 77, 0.8);
  box-shadow: inset 0px 0px 34px 0px rgba(17, 40, 255, 0.66);
  border: 2px solid #0d53b7;
}
</style>
screen/src/router/index.js
@@ -7,13 +7,18 @@
export const constantRoutes = [
  {
    path: '/',
    component: () => import('../view/login/index.vue'),
    meta: {
      title: '登录'
    }
  },
  {
    path: '/home',
    component: () => import('../view/home/index.vue'),
    meta: {
      title: '首页'
    }
  },
]
const createRouter = () => new Router({
screen/src/view/center/index.vue
File was deleted
screen/src/view/center/service.js
File was deleted
screen/src/view/header/index.vue
@@ -1,90 +1,78 @@
<template>
    <div class="txt-center h--140 w100 relative imgBg">
        <div class="flex a-center color1 absolute adress">
            <div class="fs--18 lh--18">{{ currentTime }}</div>
            <div class="h--31 w--1 color2 ml--9 mr--14"></div>
            <div class="txt-left fs--12">
                <div>{{ currentDay }}</div>
                <div>{{ currentDate }}</div>
            </div>
        </div>
        <div class="fs--43 lh--43 color3">智慧工程安全监管平台</div>
  <div class="txt-center h--85 w100 relative imgBg">
    <div class="flex a-center c-fff absolute adress1">
      <img src="../../assets/img/logo.png" class="w--30 h--30 shrink0 mr--10" />
      <div class="color2 lh--30 fs--30 SHSBold">成都市简州新城投资有限公司</div>
    </div>
    <div class="fs--43 lh--43 color3 SHSBold letter--6">
      智慧工程安全监管平台
    </div>
    <div class="flex a-center c-fff absolute adress">
      <div class="txt-left fs--24 SHSBold">
        <div>{{ currentDate }}</div>
      </div>
      <img src="../../assets/img/home/iconx.png" class="w--30 h--30 ml--28"/>
    </div>
  </div>
</template>
<script>
export default {
    data() {
        return {
            currentTime: '',
            currentDate: '',
            currentDay: ''
        }
    },
    mounted() {
        this.updateDateTime();
        this.timer = setInterval(this.updateDateTime, 1000);
    },
    beforeDestroy() {
        if (this.timer) {
            clearInterval(this.timer);
        }
    },
    methods: {
        updateDateTime() {
            const now = new Date();
            // 更新时间 (HH:MM:SS)
            this.currentTime = now.toLocaleTimeString('zh-CN', {
                hour12: false,
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit'
            });
            // 更新日期 (YYYY年MM月DD日)
            this.currentDate = now.toLocaleDateString('zh-CN', {
                year: 'numeric',
                month: 'long',
                day: 'numeric'
            });
            // 更新星期
            const days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
            this.currentDay = days[now.getDay()];
        }
  data() {
    return {
      currentDate: "",
    };
  },
  mounted() {
    this.updateDateTime();
    this.timer = setInterval(this.updateDateTime, 1000);
  },
  beforeDestroy() {
    if (this.timer) {
      clearInterval(this.timer);
    }
}
  },
  methods: {
    updateDateTime() {
      const now = new Date();
      // 更新日期 (YYYY年MM月DD日)
      this.currentDate = now.toLocaleDateString("zh-CN", {
        year: "numeric",
        month: "long",
        day: "numeric",
      });
    },
  },
};
</script>
<style scoped lang="less">
.imgBg {
    background-image: url('../../assets/img/headerBox.png');
    background-size: cover;
    background-position: center;
    padding: 20px 0;
  background-image: url("../../assets/img/home/headerBox.png");
  background-size: cover;
  background-position: center;
  padding: 20px 0;
}
.color1 {
    color: rgba(9, 185, 255, 1);
  color: rgba(9, 185, 255, 1);
}
.color2 {
    background-color: rgba(255, 255, 255, 0.40);
  color: #0adbf3;
}
.color3 {
    font-family: 'Source Han Sans CN Heavy';
    color: transparent;
    letter-spacing: 4px;
    background: linear-gradient(to bottom, #FFFFFF 40%, #BDD2FF 100%);
    -webkit-background-clip: text;
    background-clip: text;
    filter: drop-shadow(0px 2px 6px #151D4C);
  color: #ffffff;
}
.adress {
    top: 12px;
    left: 7px;
  top: 27px;
  right: 18px;
}
.adress1 {
  top: 31px;
  left: 20px;
}
</style>
screen/src/view/home/index.vue
@@ -1,179 +1,467 @@
<template>
  <div>
    <!-- <HeaderBox /> -->
    <div class="home_box">
      <!-- <LeftBox />
      <CenterBox />
      <RightBox /> -->
    </div>
    <!-- <div class="fullscreen-btn" @click="toggleFullScreen">
      <i :class="isFullScreen ? 'exit-fullscreen-icon' : 'fullscreen-icon'"></i>
    </div>
    <div v-if="!isFullScreen && showOverlay" class="fullscreen-overlay" @click="toggleFullScreen">
      <div class="overlay-content">
        <p>点击此处或按F11键进入全屏模式</p>
  <div class="relative">
    <HeaderBox />
    <div id="mapcontainer" style="width: 1920px; height: 995px"></div>
    <div class="leftBox">
      <div
        @click="handleClick"
        class="flex a-center j-between w100 px--20 h--40 relative bgcolor1"
      >
        <el-date-picker
          v-model="dateRange"
          ref="datePicker"
          type="daterange"
          range-separator=""
          start-placeholder=""
          end-placeholder=""
        >
        </el-date-picker>
        <div
          class="absolute w100 h100 flex a-center c-fff fs--14 SHS"
          style="width: calc(100% - 20px)"
        >
          {{ dateTxt }}
        </div>
        <img
          src="../../assets/img/home/Shape@2x (6).png"
          class="w--13 h--13 shrink0"
        />
      </div>
    </div> -->
      <div
        class="flex a-center j-between w100 pl--20 mt--13 h--40 relative bgcolor1 searchBox"
      >
        <input placeholder="请输入项目名称" />
        <div class="btn">搜索</div>
      </div>
      <div class="mt--33">
        <TitleBox>
          <template #title> 项目数据总览 </template>
          <template #content>
            <div class="flex px--20 mt--17 pb--16">
              <div class="flex flex-column a-center mt--17">
                <div class="bgImg1 flex a-center flex-column j-end">
                  <div class="mb--23 c-fff SHSBold lh--18 fs--18 txts1">
                    项目总数
                  </div>
                </div>
                <div
                  class="color1 fs--34 lh--39 txts2 ff54-"
                  style="margin-top: -20px"
                >
                  99
                </div>
              </div>
              <div class="ml--18">
                <div class="flex a-center pl--11 pr--13 py--6 bgimg2">
                  <div class="c-fff fs--14 SHSR mr--29 lh--14 shrink0">
                    本月检查情况
                  </div>
                  <img
                    src="../../assets/img/home/Shape@2x.png"
                    class="w--14 h--14 shrink0"
                  />
                </div>
                <div class="mt--13 flex bgcolor2 pl--9 pb--5 pt--4 pr--10">
                  <div class="flex mt--7 shrink0">
                    <img
                      src="../../assets/img/home/Shape@2x (5).png"
                      class="w--31 h--30 shrink0"
                    />
                    <div class="ml--7 SHSR">
                      <div class="color2 fs--14 lh--14">房建</div>
                      <div class="mt--9 fs--8 lh--8 color3">本月检查覆盖率</div>
                    </div>
                  </div>
                  <div class="ml--11">
                    <div class="c-fff fs--22 lh--22 SHSBold">62</div>
                    <div class="mt--9 fs--10 lh--12 color4 SHSM">50%</div>
                  </div>
                </div>
                <div class="mt--10 flex bgcolor2 pl--9 pb--5 pt--4 pr--10">
                  <div class="flex mt--7 shrink0">
                    <img
                      src="../../assets/img/home/Combined Shape@2x (4).png"
                      class="w--30 h--30 shrink0"
                    />
                    <div class="ml--7 SHSR">
                      <div class="color2 fs--14 lh--14">市政</div>
                      <div class="mt--9 fs--8 lh--8 color3">本月检查覆盖率</div>
                    </div>
                  </div>
                  <div class="ml--11">
                    <div class="c-fff fs--22 lh--22 SHSBold">62</div>
                    <div class="mt--9 fs--10 lh--12 color4 SHSM">50%</div>
                  </div>
                </div>
              </div>
            </div>
          </template>
        </TitleBox>
      </div>
      <div class="mt--25">
        <TitleBox>
          <template #title> 设备数据总览 </template>
          <template #content>
            <div class="flex j-end mt--8">
              <div class="flex a-center pl--11 pr--13 py--6 bgimg2">
                <div class="c-fff fs--14 SHSR mr--29 lh--14 shrink0">
                  本月检查情况
                </div>
                <img
                  src="../../assets/img/home/Shape@2x.png"
                  class="w--14 h--14 shrink0"
                />
              </div>
            </div>
            <div
              class="flex a-center j-center gap--40 mt--14 mx--20 br--10 py--14 bgcolor3"
            >
              <img
                src="../../assets/img/home/15@2x.png"
                class="w--72 h--77 shrink0"
              />
              <div>
                <div class="fs--34 lh--39 color1 txts2 ff54-">6829</div>
                <div class="c-fff fs--16 lh--16 SHSBold mt--10">
                  大型机械设备数
                </div>
              </div>
            </div>
            <div class="mt--14 mx--20 pb--10 rowItem">
              <div v-for="item in 10" :key="item">
                <div class="bgimg3">
                  <div class="c-fff fs--22 lh--33 SHSBold txt-center">54</div>
                </div>
                <div class="fs--12 lh--12 color5 nameTxt">塔式起重机</div>
              </div>
            </div>
          </template>
        </TitleBox>
      </div>
    </div>
    <div class="flex a-center absolute left--14 bottom--14">
      <img
        src="../../assets/img/home/Group@2x (4).png"
        class="w--110 h--110 mr--9 shrink0"
      />
      <div class="bgimg4 pt--10 c-fff">
        <div class="flex a-center ml--14">
          <div class="ripple">
            <div class="ripple-wave wave-1"></div>
            <div class="ripple-wave wave-2"></div>
            <div class="ripple-wave wave-3"></div>
          </div>
          <div class="fs--15 lh--15 ml--10">重大隐患数</div>
          <div class="color5 ml--13 fs--30 lh--30">16</div>
        </div>
        <div class="flex a-center j-center gap--52 mt--11">
          <div class="flex a-center">
            <div class="fs--14 lh--14 ml--10">未整改</div>
            <div class="color6 ml--13 fs--20 lh--24">14</div>
          </div>
          <div class="flex a-center">
            <div class="fs--14 lh--14 ml--10">已整改</div>
            <div class="color7 ml--13 fs--20 lh--24">2</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
// import HeaderBox from '../header/index.vue'
// import LeftBox from '../left/index.vue'
// import CenterBox from '../center/index.vue'
// import RightBox from '../right/index.vue'
import HeaderBox from "../header/index.vue";
import moment from "moment";
export default {
  components: {
    // HeaderBox,
    // LeftBox,
    // CenterBox,
    // RightBox
    HeaderBox,
  },
  data() {
    return {
      isFullScreen: true,
      showOverlay: true,
    }
      mapView: null,
      dateRange: [moment().startOf("month"), moment().endOf("month")], //默认本月
      dateTxt: "",
    };
  },
  watch: {
    dateRange: {
      handler(newVal, oldVal) {
        if (newVal.length > 0) {
          this.dateTxt =
            moment(newVal[0]).format("YYYY年MM月DD日") +
            " ~ " +
            moment(newVal[1]).format("YYYY年MM月DD日");
        }
      },
      immediate: true,
    },
  },
  created() {
    // 监听全屏变化事件
    // document.addEventListener('fullscreenchange', this.fullscreenChangeHandler)
    // document.addEventListener('webkitfullscreenchange', this.fullscreenChangeHandler)
    // document.addEventListener('mozfullscreenchange', this.fullscreenChangeHandler)
    // document.addEventListener('MSFullscreenChange', this.fullscreenChangeHandler)
    // // 监听键盘事件
    // window.addEventListener('keydown', this.handleKeyDown)
  },
  created() {},
  mounted() {
    // 检查当前是否为全屏状态
    this.checkFullScreenStatus()
    this.setMapload();
  },
  beforeDestroy() {
    // // 移除事件监听器
    // document.removeEventListener('fullscreenchange', this.fullscreenChangeHandler)
    // document.removeEventListener('webkitfullscreenchange', this.fullscreenChangeHandler)
    // document.removeEventListener('mozfullscreenchange', this.fullscreenChangeHandler)
    // document.removeEventListener('MSFullscreenChange', this.fullscreenChangeHandler)
    // window.removeEventListener('keydown', this.handleKeyDown)
  },
  beforeDestroy() {},
  methods: {
    toggleFullScreen() {
      if (!this.isFullScreen) {
        // 进入全屏
        const element = document.documentElement
        if (element.requestFullscreen) {
          element.requestFullscreen()
        } else if (element.webkitRequestFullscreen) {
          element.webkitRequestFullscreen()
        } else if (element.mozRequestFullScreen) {
          element.mozRequestFullScreen()
        } else if (element.msRequestFullscreen) {
          element.msRequestFullscreen()
        }
      } else {
        // 退出全屏
        if (document.exitFullscreen) {
          document.exitFullscreen()
        } else if (document.webkitExitFullscreen) {
          document.webkitExitFullscreen()
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen()
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen()
        }
      }
    handleClick() {
      this.$refs.datePicker.focus();
    },
    fullscreenChangeHandler() {
      this.checkFullScreenStatus()
    setMapload() {
      AMapLoader.load({
        key: "232929db1cb31f26d42b3645a7456154", //申请好的Web端开发者 Key,调用 load 时必填
        version: "2.0", //指定要加载的 JS API 的版本,缺省时默认为 1.4.15
      })
        .then((AMap) => {
          this.mapView = new AMap.Map("mapcontainer", {
            // resizeEnable: true, //是否监控地图容器尺寸变化
            zoom: 13,
            center: [108.357471, 22.828643], // 初始化地图中心点
            mapStyle: "amap://styles/darkblue",
          });
          this.mapView.on("click", (e) => {});
        })
        .catch((e) => {
          console.error(e); //加载错误提示
        });
    },
    checkFullScreenStatus() {
      this.isFullScreen = !!(
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement ||
        document.msFullscreenElement
      )
    },
    handleKeyDown(event) {
      // 监听F11键
      if (event.key === 'F11') {
        event.preventDefault()
        this.toggleFullScreen()
      }
    },
  }
}
  },
};
</script>
<style lang="less" scoped>
.home_box {
  display: flex;
  justify-content: space-between;
}
.leftBox {
  width: 380px;
  position: absolute;
  top: 109px;
  left: 23px;
.fullscreen-btn {
  position: fixed;
  right: 20px;
  bottom: 20px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 999;
  transition: all 0.3s;
  &:hover {
    background-color: rgba(0, 0, 0, 0.8);
  .bgImg1 {
    background-image: url("../../assets/img/home/Group@2x (3).png");
    background-size: 100% 100%;
    width: 171px;
    height: 120px;
  }
  i {
    font-size: 20px;
  .bgimg2 {
    background-image: url("../../assets/img/home/Group@2x (2).png");
    background-size: 100% 100%;
  }
  .fullscreen-icon::before {
    content: "\2922";
    /* 使用Unicode字符作为全屏图标 */
  .bgimg3 {
    background-image: url("../../assets/img/home/@3x@2x.png");
    background-size: 100% 100%;
    width: 45px;
    height: 49px;
  }
  .exit-fullscreen-icon::before {
    content: "\2923";
    /* 使用Unicode字符作为退出全屏图标 */
  .txts1 {
    text-shadow: 0px 0px 7px #132c5a;
  }
}
.fullscreen-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.7);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  .txts2 {
    text-shadow: 0px 0px 12px #1068f7;
  }
  .overlay-content {
    background-color: white;
    padding: 20px 40px;
    border-radius: 8px;
    text-align: center;
    cursor: pointer;
  .bgcolor1 {
    background: rgba(2, 0, 77, 0.8);
    box-shadow: inset 0px 0px 34px 0px rgba(17, 40, 255, 0.66);
    border: 2px solid #0d53b7;
  }
    p {
      font-size: 18px;
      margin: 0;
  .bgcolor2 {
    background: rgba(0, 113, 251, 0.1);
  }
  .bgcolor3 {
    box-shadow: inset 0px 0px 22px 0px #2548b1;
    border: 1px solid #3341b6;
  }
  .color1 {
    color: #66ffff;
  }
  .color2 {
    color: #cce0f8;
  }
  .color3 {
    color: #7cc1ff;
  }
  .color4 {
    color: #fedb65;
  }
  .color5 {
    color: rgba(204, 224, 248, 0.7);
  }
  ::v-deep .el-input__icon {
    display: none;
  }
  ::v-deep .el-input__inner {
    background: transparent;
    border: none;
    color: transparent;
  }
  ::v-deep .el-range-input {
    background: transparent;
    border: none;
    color: transparent;
  }
  .searchBox {
    input {
      background-color: transparent;
      color: #fff;
    }
    input::placeholder {
      color: rgba(255, 255, 255, 0.6);
    }
    input:focus {
      outline: none;
    }
    .btn {
      position: absolute;
      top: -2px;
      right: -2px;
      background: linear-gradient(
        90deg,
        #3467d0 0%,
        #0d226a 50.35%,
        #376fe0 100%
      );
      line-height: 38px;
      font-size: 14px;
      color: #ffffff;
      font-family: "Source Han Sans CN Heavy";
      padding: 0 26px;
      border: 1px solid #307ad9;
      box-sizing: border-box;
      cursor: pointer;
    }
  }
  .rowItem {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px 33px;
    .nameTxt {
      width: 5em;
      overflow: hidden;
      max-height: 2em;
      text-align: center;
    }
  }
}
.bgimg4 {
  background-image: url("../../assets/img/home/Group 24 Copy@2x.png");
  background-size: 100% 100%;
  width: 300px;
  height: 94px;
}
.color5 {
  color: #ff4d04;
}
.color6 {
  color: #fedb65;
}
.color7 {
  color: #47a1ff;
}
.ripple {
  position: relative;
  width: 14px;
  height: 14px;
  margin-right: 14px;
}
.ripple-wave {
  position: absolute;
  border-radius: 50%;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.wave-1 {
  width: 14px;
  height: 14px;
  background-color: rgba(255, 77, 4, 1);
}
.wave-2 {
  width: 20px;
  height: 20px;
  background-color: rgba(255, 77, 4, 0.6);
  animation: ripple-effect 2s ease-out infinite;
}
.wave-3 {
  width: 24px;
  height: 24px;
  background-color: rgba(255, 77, 4, 0.4);
  animation: ripple-effect 2s ease-out infinite 1s;
}
@keyframes ripple-effect {
  0% {
    transform: translate(-50%, -50%) scale(0.7);
    opacity: 0;
  }
  20% {
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(1.4);
    opacity: 0;
  }
}
/* 兼容性前缀 */
.wave-2, .wave-3 {
  -webkit-animation-name: ripple-effect;
  -moz-animation-name: ripple-effect;
  -o-animation-name: ripple-effect;
  animation-name: ripple-effect;
}
@-webkit-keyframes ripple-effect {
  0% {
    -webkit-transform: translate(-50%, -50%) scale(0.7);
    opacity: 0;
  }
  20% {
    opacity: 1;
  }
  100% {
    -webkit-transform: translate(-50%, -50%) scale(1.4);
    opacity: 0;
  }
}
@-moz-keyframes ripple-effect {
  0% {
    -moz-transform: translate(-50%, -50%) scale(0.7);
    opacity: 0;
  }
  20% {
    opacity: 1;
  }
  100% {
    -moz-transform: translate(-50%, -50%) scale(1.4);
    opacity: 0;
  }
}
</style>
screen/src/view/left/index.vue
File was deleted
screen/src/view/left/service.js
File was deleted
screen/src/view/login/index.vue
New file
@@ -0,0 +1,528 @@
<template>
  <div class="content">
    <div class="title">智慧工程安全监管平台</div>
    <div v-if="showLoginBox" class="form">
      <img
        src="../../assets/img/login/bgTop.png"
        style="width: 371px"
        class="h--17 mt--20"
      />
      <div class="titleTxt">
        <div>欢</div>
        <div>迎</div>
        <div>登</div>
        <div>录</div>
      </div>
      <div class="mt--64 w100 px--65">
        <div class="flex a-center py--18 pl--25 pr--74 br--16 bgcolor1">
          <img
            src="../../assets/img/login/account.png"
            class="w--29 h--29 shrink0"
          />
          <input
            v-model="form.account"
            placeholder="请输入账号"
            class="h--23 ml--20 flex1"
          />
        </div>
        <div class="flex a-center py--18 px--25 br--16 mt--40 bgcolor1">
          <img
            src="../../assets/img/login/password.png"
            class="w--29 h--29 shrink0"
          />
          <input
            :type="showPassword ? 'text' : 'password'"
            v-model="form.password"
            placeholder="请输入密码"
            class="h--23 ml--20 flex1"
          />
          <div
            class="w--29 h--29 flex a-center j-center cursor-pointer ml--20"
            @click="togglePassword"
          >
            <img
              :src="
                showPassword
                  ? '../../assets/img/login/eye-open.png'
                  : '../../assets/img/login/eye-close.png'
              "
              class="w--29 h--29 shrink0"
            />
          </div>
        </div>
        <div class="flex a-center py--13 px--25 br--16 mt--40 bgcolor1">
          <img
            src="../../assets/img/login/code.png"
            class="w--29 h--29 shrink0"
          />
          <input
            v-model="form.captcha"
            placeholder="请输入验证码"
            class="h--23 ml--20 flex1"
          />
          <div
            class="w--95 h--38 br--4 cursor-pointer relative overflow-hidden"
            style="background-color: #fff"
            @click="onCaptchaClick"
          >
            <svg class="absolute inset-0 w-full h-full">
              <!-- 波浪线 -->
              <g stroke="#999" stroke-width="1" fill="none" opacity="0.2">
                <path
                  v-for="(wave, index) in noiseData.waves"
                  :key="'wave-' + index"
                  :d="`M 0 ${wave.y} Q 24 ${wave.y - wave.amplitude} 48 ${
                    wave.y
                  } T 96 ${wave.y}`"
                />
              </g>
              <!-- 干扰线 -->
              <g stroke="#666" stroke-width="0.5" opacity="0.3">
                <line
                  v-for="(line, index) in noiseData.lines"
                  :key="'line-' + index"
                  :x1="line.x1"
                  :y1="line.y1"
                  :x2="line.x2"
                  :y2="line.y2"
                />
              </g>
              <!-- 噪点 -->
              <g fill="#999" opacity="0.4">
                <circle
                  v-for="(dot, index) in noiseData.dots"
                  :key="'dot-' + index"
                  :cx="dot.x"
                  :cy="dot.y"
                  :r="dot.size"
                />
              </g>
            </svg>
            <div
              class="relative z-10 flex items-center justify-center h-full"
              style="
                font-family: monospace;
                font-size: 24px;
                letter-spacing: 4px;
                text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
              "
            >
              <span
                v-for="(char, index) in captchaText"
                :key="index"
                class="inline-block"
                :style="{
                  color: noiseData.charStyles[index]
                    ? noiseData.charStyles[index].color
                    : '#333',
                  transform: `rotate(${
                    noiseData.charStyles[index]
                      ? noiseData.charStyles[index].rotation
                      : 0
                  }deg) translateY(${
                    noiseData.charStyles[index]
                      ? noiseData.charStyles[index].offsetY
                      : 0
                  }px)`,
                  display: 'inline-block',
                  margin: '0 2px',
                }"
              >
                {{ char }}
              </span>
            </div>
          </div>
        </div>
        <div class="buttonBox" @click="handleLogin">
          登<span class="mx--9"></span>录
        </div>
      </div>
    </div>
    <div v-else class="selectAcount">
      <div class="tipTitle">请选择登录账号</div>
      <div class="w100 mt--56 px--50 oa">
        <div
          v-for="item in accountList"
          :key="item.id"
          class="flex a-center j-between py--23 px--20 border1 cursor-pointer mb--34"
          :class="{ 'active-item': selectedAccount === item.id }"
          @click="selectAccount(item)"
        >
          <div class="fs--16 lh--16 c-fff">{{ item.name }}</div>
          <img
            v-if="selectedAccount === item.id"
            src="../../assets/img/login/active.png"
            class="w--24 h--24 shrink0"
          />
           <img
            v-else
            src="../../assets/img/login/noActive.png"
            class="w--24 h--24 shrink0"
          />
        </div>
      </div>
      <div class="flex a-center j-center c-fff mt--64 gap--30 fs--16 pb--51">
        <div class="px--59 lh--40 br--4 bgcolor2 cursor-pointer" @click="cancelSelect">取消</div>
        <div class="px--59 lh--40 br--4 bgcolor3 cursor-pointer" @click="confirmSelect">确定</div>
      </div>
    </div>
  </div>
</template>
<script>
import { Message } from "element-ui";
export default {
  components: {},
  props: {},
  data() {
    return {
      form: {
        account: "",
        password: "",
        captcha: "",
      },
      captchaText: "",
      noiseData: {
        dots: [],
        lines: [],
      },
      showPassword: false,
      showLoginBox: true,
      accountList: [
        { id: 1, name: '委托方名称111' },
        { id: 2, name: '委托方名称222' },
        { id: 3, name: '委托方名称333' },
        { id: 4, name: '委托方名称444' },
        { id: 5, name: '委托方名称555' }
      ],
      selectedAccount: null
    };
  },
  computed: {},
  watch: {},
  created() {
    this.generateCaptcha();
  },
  mounted() {},
  methods: {
    // 生成验证码
    generateCaptcha() {
      const chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
      let result = "";
      for (let i = 0; i < 4; i++) {
        result += chars.charAt(Math.floor(Math.random() * chars.length));
      }
      this.captchaText = result;
      this.generateCaptchaNoise();
    },
    // 生成噪点和干扰线数据
    generateCaptchaNoise() {
      this.noiseData = {
        dots: [],
        lines: [],
        charStyles: [],
        waves: [],
      };
      // 生成噪点
      for (let i = 0; i < 80; i++) {
        this.noiseData.dots.push({
          x: Math.random() * 95,
          y: Math.random() * 38,
          size: Math.random() * 2 + 0.5,
        });
      }
      // 生成干扰线
      for (let i = 0; i < 5; i++) {
        this.noiseData.lines.push({
          x1: Math.random() * 95,
          y1: Math.random() * 38,
          x2: Math.random() * 95,
          y2: Math.random() * 38,
        });
      }
      // 生成波浪线
      for (let i = 0; i < 2; i++) {
        this.noiseData.waves.push({
          y: 10 + i * 14,
          amplitude: 2 + Math.random() * 2,
          frequency: 0.1 + Math.random() * 0.1,
        });
      }
      // 为每个字符生成样式(旋转和颜色变化)
      const colors = ["#333", "#444", "#555", "#666", "#222"];
      for (let i = 0; i < 4; i++) {
        this.noiseData.charStyles.push({
          rotation: (Math.random() - 0.5) * 30, // -15到15度之间的随机旋转
          color: colors[Math.floor(Math.random() * colors.length)],
          offsetY: (Math.random() - 0.5) * 4, // -2到2像素的随机偏移
        });
      }
    },
    // 刷新验证码
    refreshCaptcha() {
      this.generateCaptcha();
    },
    // 表单校验
    validateForm() {
      // 校验账号
      if (!this.form.account.trim()) {
        Message({
          message: "请输入账号",
          type: "warning",
        });
        return false;
      }
      // 校验密码
      if (!this.form.password.trim()) {
        Message({
          message: "请输入密码",
          type: "warning",
        });
        return false;
      }
      // 校验验证码
      if (!this.form.captcha.trim()) {
        Message({
          message: "请输入验证码",
          type: "warning",
        });
        return false;
      } else if (
        this.form.captcha.toLowerCase() !== this.captchaText.toLowerCase()
      ) {
        Message({
          message: "验证码错误",
          type: "warning",
        });
        return false;
      }
      return true;
    },
    // 登录处理
    handleLogin() {
      if (this.validateForm()) {
        // 这里可以添加实际的登录逻辑
        console.log("登录信息:", {
          account: this.form.account,
          password: this.form.password,
          captcha: this.form.captcha,
        });
        // 模拟登录成功,显示账号选择框
        this.showLoginBox = false;
        this.selectedAccount = null;
      }
    },
    // 验证码点击事件
    onCaptchaClick() {
      this.refreshCaptcha();
    },
    // 刷新验证码
    refreshCaptcha() {
      this.generateCaptcha();
    },
    // 切换密码显示/隐藏
    togglePassword() {
      this.showPassword = !this.showPassword;
    },
    // 选择账号
    selectAccount(account) {
      this.selectedAccount = account.id;
    },
    // 取消选择账号
    cancelSelect() {
      this.showLoginBox = true;
      this.generateCaptcha();
      this.form.captcha = "";
    },
    // 确认选择账号
    confirmSelect() {
      if (this.selectedAccount) {
        // 获取选中的账号信息
        const account = this.accountList.find(item => item.id === this.selectedAccount);
        console.log('选择的账号:', account);
        // 这里可以添加实际的登录逻辑
        // 模拟跳转到首页
        this.$router.push('/home');
      } else {
        Message({
          message: "请先选择一个账号",
          type: "warning",
        });
      }
    },
  },
};
</script>
<style scoped lang="less">
.content {
  width: 100%;
  height: 100%;
  background-image: url("../../assets/img/login/contentBg.png");
  background-size: 100% 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  .bgcolor1 {
    background: rgba(255, 255, 255, 0.08);
  }
  .title {
    padding-top: 139px;
    font-family: "Source Han Sans CN Bold";
    font-weight: 800;
    font-size: 50px;
    color: #ffffff;
    line-height: 48px;
    letter-spacing: 6px;
  }
  .form {
    margin-top: 92px;
    width: 540px;
    height: 649px;
    display: flex;
    flex-direction: column;
    align-items: center;
    background-image: url("../../assets/img/login/bgBox.png");
    background-size: 100% 100%;
    .titleTxt {
      margin-top: 40px;
      font-family: "Source Han Sans CN Bold";
      font-weight: 800;
      font-size: 45px;
      color: #000000;
      line-height: 54px;
      display: flex;
      align-items: center;
      gap: 20px;
      div {
        background: linear-gradient(
          to right,
          rgba(255, 255, 255, 0.6) 1px,
          #ffffff 100%
        );
        -webkit-background-clip: text;
        /* 使用-webkit-前缀兼容部分浏览器 */
        background-clip: text;
        color: transparent;
        -webkit-text-fill-color: transparent;
      }
    }
    .buttonBox {
      margin-top: 63px;
      text-align: center;
      font-family: "Source Han Sans CN Bold";
      width: 100%;
      line-height: 70px;
      background: linear-gradient(270deg, #09b9ff 0%, #4d68ff 100%);
      border-radius: 16px;
      font-weight: bold;
      font-size: 24px;
      color: #ffffff;
    }
    input {
      background-color: transparent;
      color: #fff;
    }
    input::placeholder {
      color: rgba(255, 255, 255, 0.2);
    }
    input:focus {
      outline: none;
    }
    .buttonBox:hover {
      background: linear-gradient(270deg, #0ad0ff 0%, #5d79ff 100%);
      cursor: pointer;
    }
    .cursor-pointer:hover {
      opacity: 0.8;
    }
  }
  .selectAcount {
    margin-top: 164px;
    width: 730px;
    height: 465px;
    display: flex;
    flex-direction: column;
    align-items: center;
    background-image: url("../../assets/img/login/bgBox.png");
    background-size: 100% 100%;
  }
  .tipTitle {
    flex-shrink: 0;
    width: 100%;
    height: 80px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-image: url("../../assets/img/login/titleBg.png");
    background-size: 100% 100%;
    font-family: "Source Han Sans CN Bold";
    font-weight: bold;
    font-size: 24px;
    color: #ffffff;
    letter-spacing: 1px;
  }
  .border1 {
    border: 2px solid #0d53b7;
  }
  .bgcolor2 {
    background: #838fbb;
  }
  .bgcolor3 {
    background: linear-gradient(270deg, #09b9ff 0%, #4d68ff 100%);
  }
  .active-item {
    background-color: rgba(13, 83, 183, 0.2);
    border-color: #09b9ff;
  }
  // 按钮hover效果
  .bgcolor2:hover {
    background-color: #6c7a9f;
    transform: translateY(-2px);
    transition: all 0.3s ease;
  }
  .bgcolor3:hover {
    background: linear-gradient(270deg, #0ad0ff 0%, #5d79ff 100%);
    transform: translateY(-2px);
    transition: all 0.3s ease;
    box-shadow: 0 4px 12px rgba(9, 185, 255, 0.3);
  }
}
</style>
screen/src/view/right/index.vue
File was deleted
screen/src/view/right/service.js
File was deleted