yanghao 2 weken geleden
bovenliggende
commit
2e8d201f16

+ 1 - 0
components.d.ts

@@ -26,6 +26,7 @@ declare module 'vue' {
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElIcon: typeof import('element-plus/es')['ElIcon']
+    ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
     ElLink: typeof import('element-plus/es')['ElLink']
     ElPagination: typeof import('element-plus/es')['ElPagination']

+ 1 - 1
src/App.vue

@@ -88,7 +88,7 @@ onBeforeUnmount(() => {
 
 <template>
   <motion.div
-    class="overflow-x-hidden font-sans"
+    class="overflow-x-hidden font-sans app-shell"
     :key="$route.fullPath"
     :initial="{ opacity: 0 }"
     :animate="{ opacity: 1, transition: { duration: 0.5, ease: 'easeOut' } }"

BIN
src/assets/images/QHSE驾驶舱.png


BIN
src/assets/images/banner1.png


BIN
src/assets/images/banner2.png


BIN
src/assets/images/banner4.jpeg


BIN
src/assets/images/banner4.png


BIN
src/assets/images/dr.png


BIN
src/assets/images/dr1.png


BIN
src/assets/images/drivebannere.png


BIN
src/assets/images/icon.png


BIN
src/assets/images/mobile.png


BIN
src/assets/images/供应链驾驶舱.png


BIN
src/assets/images/市场驾驶舱.png


BIN
src/assets/images/生产驾驶舱.png


BIN
src/assets/images/财务驾驶舱.png


+ 8 - 1
src/assets/style/main.css

@@ -1,10 +1,17 @@
 @import "tailwindcss";
 
 @layer base {
+  html,
   body,
   #app {
+    min-height: 100%;
+    background-color: #000613;
     overflow-x: hidden;
   }
+
+  body {
+    margin: 0;
+  }
 }
 
 /* 修改垂直滚动条 */
@@ -29,4 +36,4 @@
 /* 修改滚动条滑块悬停时的颜色 */
 ::-webkit-scrollbar-thumb:hover {
   background-color: #69696b;
-}
+}

+ 74 - 103
src/components/home/header.vue

@@ -1,6 +1,6 @@
 <template>
   <header
-    class="fixed w-full top-0 z-100 bg-white border-b border-[#f0f2f5] shadow-sm"
+    class="fixed w-full top-0 z-100 bg-[#010612] border-b border-[#131928] shadow-sm"
   >
     <div
       class="max-w-[1400px] mx-auto flex items-center justify-between px-5 h-15"
@@ -17,7 +17,7 @@
         >
       </div>
 
-      <nav class="hidden lg:flex flex-1 mx-4 ml-150 text-sm">
+      <nav class="hidden lg:flex flex-1 mx-4 ml-60 text-sm">
         <ul class="flex items-center gap-6 text-[#303133] text-md">
           <!-- 首页 -->
           <li>
@@ -98,7 +98,7 @@
             >
               <Icon
                 icon="mdi:bell"
-                class="w-5 h-5 text-[#507698] hover:text-[#409EFF]"
+                class="w-5 h-5 text-[#a7aab0] hover:text-[#409EFF]"
               />
             </el-badge>
             <Icon
@@ -219,7 +219,7 @@
                 />
               </div>
               <span
-                class="text-sm text-[#303133]"
+                class="text-sm text-[#c5cfd7]"
                 style="text-wrap-mode: nowrap"
                 >{{ userName }}</span
               >
@@ -227,107 +227,10 @@
             <template #dropdown>
               <el-dropdown-menu>
                 <el-dropdown-item command="profile">
-                  <svg
-                    xmlns="http://www.w3.org/2000/svg"
-                    width="18"
-                    height="18"
-                    viewBox="0 0 16 16"
-                  >
-                    <g fill="none">
-                      <path
-                        fill="url(#SVG3BqCJdyi)"
-                        d="M11.5 8A1.5 1.5 0 0 1 13 9.5v.5c0 1.971-1.86 4-5 4s-5-2.029-5-4v-.5A1.5 1.5 0 0 1 4.5 8z"
-                      />
-                      <path
-                        fill="url(#SVGfKhxtenh)"
-                        d="M11.5 8A1.5 1.5 0 0 1 13 9.5v.5c0 1.971-1.86 4-5 4s-5-2.029-5-4v-.5A1.5 1.5 0 0 1 4.5 8z"
-                      />
-                      <path
-                        fill="url(#SVGJYCMTblH)"
-                        d="M8 1.5A2.75 2.75 0 1 1 8 7a2.75 2.75 0 0 1 0-5.5"
-                      />
-                      <defs>
-                        <linearGradient
-                          id="SVG3BqCJdyi"
-                          x1="5.378"
-                          x2="7.616"
-                          y1="8.798"
-                          y2="14.754"
-                          gradientUnits="userSpaceOnUse"
-                        >
-                          <stop offset=".125" stop-color="#9c6cfe" />
-                          <stop offset="1" stop-color="#7a41dc" />
-                        </linearGradient>
-                        <linearGradient
-                          id="SVGfKhxtenh"
-                          x1="8"
-                          x2="11.164"
-                          y1="7.286"
-                          y2="17.139"
-                          gradientUnits="userSpaceOnUse"
-                        >
-                          <stop stop-color="#885edb" stop-opacity="0" />
-                          <stop offset="1" stop-color="#e362f8" />
-                        </linearGradient>
-                        <linearGradient
-                          id="SVGJYCMTblH"
-                          x1="6.558"
-                          x2="9.361"
-                          y1="2.231"
-                          y2="6.707"
-                          gradientUnits="userSpaceOnUse"
-                        >
-                          <stop offset=".125" stop-color="#9c6cfe" />
-                          <stop offset="1" stop-color="#7a41dc" />
-                        </linearGradient>
-                      </defs>
-                    </g>
-                  </svg>
-                  <span class="pl-2">个人中心</span>
+                  <span>个人中心</span>
                 </el-dropdown-item>
                 <el-dropdown-item command="logout">
-                  <svg
-                    xmlns="http://www.w3.org/2000/svg"
-                    width="18"
-                    height="18"
-                    viewBox="0 0 24 24"
-                  >
-                    <g fill="none">
-                      <path
-                        fill="url(#SVG0pAmxd9w)"
-                        d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2"
-                      />
-                      <path
-                        fill="url(#SVGFnXqmeDt)"
-                        d="m15.53 8.47l-.084-.073a.75.75 0 0 0-.882-.007l-.094.08L12 10.939l-2.47-2.47l-.084-.072a.75.75 0 0 0-.882-.007l-.094.08l-.073.084a.75.75 0 0 0-.007.882l.08.094L10.939 12l-2.47 2.47l-.072.084a.75.75 0 0 0-.007.882l.08.094l.084.073a.75.75 0 0 0 .882.007l.094-.08L12 13.061l2.47 2.47l.084.072a.75.75 0 0 0 .882.007l.094-.08l.073-.084a.75.75 0 0 0 .007-.882l-.08-.094L13.061 12l2.47-2.47l.072-.084a.75.75 0 0 0 .007-.882z"
-                      />
-                      <defs>
-                        <linearGradient
-                          id="SVG0pAmxd9w"
-                          x1="5.125"
-                          x2="18.25"
-                          y1="3.25"
-                          y2="22.625"
-                          gradientUnits="userSpaceOnUse"
-                        >
-                          <stop stop-color="#f83f54" />
-                          <stop offset="1" stop-color="#ca2134" />
-                        </linearGradient>
-                        <linearGradient
-                          id="SVGFnXqmeDt"
-                          x1="8.685"
-                          x2="12.591"
-                          y1="12.332"
-                          y2="16.392"
-                          gradientUnits="userSpaceOnUse"
-                        >
-                          <stop stop-color="#fdfdfd" />
-                          <stop offset="1" stop-color="#fecbe6" />
-                        </linearGradient>
-                      </defs>
-                    </g>
-                  </svg>
-                  <span class="pl-2">退出登录</span>
+                  <span>退出登录</span>
                 </el-dropdown-item>
               </el-dropdown-menu>
             </template>
@@ -946,4 +849,72 @@ const onUserCommand = async (command: string) => {
     text-align: left;
   }
 }
+
+.nav-item-default {
+  color: rgba(230, 237, 255, 0.8);
+  border-radius: 0;
+  position: relative;
+  background-color: transparent;
+}
+
+.nav-item-default:hover {
+  color: #ffffff;
+  background: rgba(255, 255, 255, 0.04);
+}
+
+.nav-item-active {
+  color: #fff !important;
+  background: linear-gradient(
+    180deg,
+    rgba(92, 103, 238, 0.32),
+    rgba(36, 53, 118, 0.18)
+  ) !important;
+  /* box-shadow: inset 0 -2px 0 #6f8bff; */
+  padding-bottom: 22px;
+  padding-top: 22px;
+  border-radius: 0;
+
+  position: relative;
+}
+
+.nav-item-active::before {
+  content: "";
+  position: absolute;
+  left: 50%;
+  bottom: -2px;
+  width: 100%;
+  height: 2px;
+  transform: translateX(-50%);
+  border-radius: 999px;
+  background: linear-gradient(
+    to right,
+    #5887f8 0%,
+    #69b5f8 30%,
+    #fff 50%,
+    #69b5f8 70%,
+    #5887f8 100%
+  );
+  box-shadow: 0 0 12px rgba(112, 120, 255, 0.95);
+}
+
+/* .nav-item-active::after {
+  content: "";
+  position: absolute;
+  left: 50%;
+  bottom: -10px;
+  width: 46px;
+  height: 3px;
+  transform: translateX(-50%);
+  border-radius: 999px;
+  background: linear-gradient(90deg, #cc82ff, #5f89ff);
+  box-shadow: 0 0 12px rgba(112, 120, 255, 0.95);
+} */
+
+.notification-dropdown {
+  width: 400px !important;
+  max-height: 500px;
+  overflow: hidden;
+  border: 1px solid rgba(109, 137, 213, 0.18);
+  background: #081225;
+}
 </style>

+ 223 - 76
src/views/drive/index.vue

@@ -4,34 +4,39 @@
 
     <main class="drive-main">
       <section class="drive-hero">
-        <p class="drive-eyebrow">Dashboard Portal</p>
-        <h1 class="drive-title">驾驶舱门户</h1>
-        <p class="drive-desc">选择一个驾驶舱,快速进入对应业务看板。</p>
+        <div class="drive-hero__copy">
+          <p class="drive-hero__eyebrow">DASHBOARD PORTAL</p>
+          <p class="drive-hero__title">驾驶舱门户</p>
+          <p class="drive-hero__desc">选择一个驾驶舱,快速进入对应业务看板。</p>
+        </div>
+        <div class="drive-hero__visual">
+          <el-image :src="banner" class="drive-hero__image" />
+        </div>
       </section>
 
-      <section class="drive-grid">
+      <section class="drive-tabs px-10">
+        <button type="button" class="drive-tab drive-tab--active">
+          全部驾驶舱
+        </button>
+        <button type="button" class="drive-tab">经营管理</button>
+        <button type="button" class="drive-tab">生产运营</button>
+        <button type="button" class="drive-tab">财务管理</button>
+        <button type="button" class="drive-tab">供应链管理</button>
+        <button type="button" class="drive-tab">市场营销</button>
+        <button type="button" class="drive-tab">QHSE</button>
+      </section>
+
+      <section class="drive-grid md:px-20">
         <button
           v-for="card in driveCards"
           :key="card.title"
           type="button"
-          class="drive-card"
+          class="drive-card overflow-hidden"
           @click="openDrive(card)"
         >
-          <div
-            class="drive-card__icon"
-            :style="{
-              backgroundColor: card.bgColor,
-            }"
-          >
-            <Icon :icon="card.icon" />
-          </div>
-          <div class="drive-card__content">
-            <h2 class="drive-card__title">{{ card.title }}</h2>
-            <p class="drive-card__text">{{ card.description }}</p>
-          </div>
-          <div class="drive-card__arrow">
-            <Icon icon="mdi:arrow-top-right" />
-          </div>
+          <!-- <div>
+            <el-image :src="dr1"></el-image>
+          </div> -->
         </button>
       </section>
     </main>
@@ -50,6 +55,14 @@ import { Icon } from "@iconify/vue";
 import { getMCSsoToken } from "@/api/user";
 import { useUserStore } from "@/stores/useUserStore";
 import { getAccessToken } from "@/utils/auth";
+import banner from "@/assets/images/drivebannere.png";
+import dr from "@/assets/images/dr.png";
+import moblie from "@/assets/images/mobile.png";
+import pruduct from "@/assets/images/生产驾驶舱.png";
+import chain from "@/assets/images/供应链驾驶舱.png";
+import money from "@/assets/images/财务驾驶舱.png";
+import market from "@/assets/images/市场驾驶舱.png";
+import qhse from "@/assets/images/QHSE驾驶舱.png";
 
 const userStore = useUserStore();
 
@@ -65,21 +78,21 @@ const driveCards: DriveCard[] = [
   {
     title: "经营驾驶舱",
     description: "查看经营分析、经营指标与执行情况。",
-    icon: "mdi:business",
+    icon: moblie,
     url: "https://report.deepoil.cc/webroot/decision/v10/entry/access/9fb42908-894a-4373-a6be-ce046a42851d?preview=true&page_number=1",
     bgColor: "#3876e0",
   },
   {
     title: "生产驾驶舱",
     description: "查看生产运营态势、核心指标与执行情况。",
-    icon: "mdi:factory",
+    icon: pruduct,
     url: "https://report.deepoil.cc/webroot/decision/v10/entry/access/dbc9cf73-81ce-43f1-9923-45cdfa5d5d3a?preview=true&page_number=1",
     bgColor: "#0f766e",
   },
   {
     title: "财务驾驶舱",
     description: "查看财务分析、预算执行与经营数据表现。",
-    icon: "mdi:finance",
+    icon: money,
     url: "https://report.deepoil.cc/webroot/decision/v10/entry/access/e836fb5b-092c-4d64-a324-3beeb4fac0cc?preview=true&page_number=1",
     bgColor: "#ca8a04",
   },
@@ -87,7 +100,7 @@ const driveCards: DriveCard[] = [
   {
     title: "供应链驾驶舱",
     description: "查看供应链分析、物料需求与执行。",
-    icon: "mdi:shield-check",
+    icon: chain,
     url: "#",
     bgColor: "#7c3aed",
   },
@@ -96,7 +109,7 @@ const driveCards: DriveCard[] = [
   {
     title: "市场驾驶舱",
     description: "查看市场分析、销售数据与执行情况。",
-    icon: "mdi:chart-line",
+    icon: market,
     url: "#",
     bgColor: "#16a34a",
   },
@@ -105,7 +118,7 @@ const driveCards: DriveCard[] = [
   {
     title: "QHSE驾驶舱",
     description: "查看安全、健康、环境与质量数据。",
-    icon: "mdi:shield-alert",
+    icon: qhse,
     url: "#",
     bgColor: "#dc2626",
   },
@@ -125,92 +138,190 @@ const openDrive = async (option: DriveCard) => {
 .drive-page {
   min-height: 100vh;
   background:
+    radial-gradient(circle at 50% 0%, rgba(30, 74, 255, 0.18), transparent 28%),
     radial-gradient(
-      circle at top left,
-      rgba(77, 138, 255, 0.16),
-      transparent 28%
+      circle at 82% 18%,
+      rgba(151, 66, 255, 0.16),
+      transparent 18%
     ),
-    linear-gradient(180deg, #f4f8fc 0%, #eef3f9 100%);
-  color: #17345f;
+    linear-gradient(180deg, #000613 0%, #000613 100%);
 }
 
 .drive-main {
-  max-width: 1200px;
+  max-width: 100vw;
   margin: 0 auto;
-  padding: 132px 24px 72px;
-  height: 100vh;
+  padding-top: 50px;
 }
 
 .drive-hero {
-  margin-bottom: 40px;
+  position: relative;
+  min-height: 340px;
+
+  overflow: hidden;
+  background:
+    linear-gradient(180deg, rgba(2, 8, 25, 0.55), rgba(2, 8, 25, 0.86)), #000613;
+  box-shadow:
+    0 24px 60px rgba(0, 0, 0, 0.42),
+    inset 0 1px 0 rgba(255, 255, 255, 0.04);
+}
+
+.drive-hero::before {
+  content: "";
+  position: absolute;
+  inset: 0;
+  background: linear-gradient(
+    90deg,
+    rgba(0, 6, 19, 0.8) 0%,
+    rgba(0, 6, 19, 0.24) 40%,
+    rgba(0, 6, 19, 0.08) 100%
+  );
+  z-index: 1;
 }
 
-.drive-eyebrow {
-  margin: 0 0 10px;
-  color: #4a78c2;
-  font-size: 13px;
+.drive-hero__copy {
+  position: absolute;
+  z-index: 2;
+  left: 56px;
+  top: 54px;
+  max-width: 560px;
+}
+
+.drive-hero__eyebrow {
+  margin: 0 0 16px;
+  color: #6d77ff;
+  font-size: 14px;
   font-weight: 700;
-  letter-spacing: 0.18em;
-  text-transform: uppercase;
+  letter-spacing: 0.22em;
 }
 
-.drive-title {
+.drive-hero__title {
   margin: 0;
-  color: #0f274a;
-  font-size: clamp(30px, 4vw, 42px);
-  font-weight: 700;
+  color: #f5f8ff;
+  font-size: clamp(20px, 5vw, 50px);
+  font-weight: 900;
+  line-height: 1.08;
+  text-shadow: 0 10px 24px rgba(0, 0, 0, 0.45);
 }
 
-.drive-desc {
-  margin: 14px 0 0;
-  max-width: 560px;
-  color: #5e7391;
-  font-size: 16px;
+.drive-hero__desc {
+  margin: 20px 0 0;
+  color: #5c6dc8;
+  font-size: 18px;
   line-height: 1.8;
 }
 
+.drive-hero__visual {
+  position: absolute;
+  inset: 0;
+}
+
+.drive-hero__image {
+  width: 100%;
+  height: 100%;
+}
+
+.drive-hero__image :deep(img) {
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+  filter: saturate(1.1) contrast(1.05);
+}
+
+.drive-tabs {
+  display: grid;
+  grid-template-columns: repeat(7, minmax(0, 1fr));
+  gap: 0;
+  margin: 0 auto;
+  padding: 12px 18px;
+  width: 90%;
+  border: 1px solid rgba(79, 110, 208, 0.16);
+  border-radius: 10px;
+  background: rgba(8, 14, 30, 0.86);
+  box-shadow: 0 16px 34px rgba(0, 0, 0, 0.2);
+}
+
+.drive-tab {
+  height: 58px;
+  border: 0;
+  border-right: 1px solid rgba(255, 255, 255, 0.06);
+  background: transparent;
+  color: rgba(220, 229, 255, 0.78);
+  font-size: 18px;
+  font-weight: 700;
+  cursor: pointer;
+}
+
+.drive-tab:last-child {
+  border-right: 0;
+}
+
+.drive-tab--active {
+  color: #fff;
+  position: relative;
+}
+
+.drive-tab--active::after {
+  content: "";
+  position: absolute;
+  left: 50%;
+  bottom: -12px;
+  width: 72px;
+  height: 4px;
+  border-radius: 999px;
+  transform: translateX(-50%);
+  background: linear-gradient(90deg, #8f65ff 0%, #4d82ff 100%);
+  box-shadow: 0 0 18px rgba(97, 111, 255, 0.85);
+}
+
 .drive-grid {
   display: grid;
   grid-template-columns: repeat(2, minmax(0, 1fr));
-  gap: 24px;
+  gap: 22px;
+  margin-top: 30px;
 }
 
 .drive-card {
+  position: relative; /* 确保内部绝对定位元素参考此容器 */
   display: flex;
-  align-items: center;
-  gap: 18px;
+  align-items: center; /* 垂直居中文字 */
+  justify-content: center; /* 水平居中文字 */
+
   width: 100%;
-  padding: 28px 26px;
-  border: 1px solid rgba(118, 154, 210, 0.18);
-  border-radius: 24px;
-  background: rgba(255, 255, 255, 0.9);
-  box-shadow: 0 18px 40px rgba(33, 77, 145, 0.08);
-  text-align: left;
+  height: 184px; /* 固定高度 */
+
+  /* 背景图设置 */
+  background-image: url("@/assets/images/dr1.png"); /* 注意:在 style 中引用静态资源可能需要 ~@ 或直接路径,Vite/Vue3通常支持 @ */
+  background-size: contain; /* 关键:覆盖整个区域,裁剪多余部分,无间距 */
+  background-position: center; /* 关键:居中显示 */
+  background-repeat: no-repeat;
+
+  text-align: center;
   cursor: pointer;
   transition:
     transform 0.2s ease,
     box-shadow 0.2s ease,
     border-color 0.2s ease;
+
+  overflow: hidden;
+  margin-top: -50px;
 }
 
 .drive-card:hover {
   transform: translateY(-4px);
-  border-color: rgba(47, 111, 219, 0.36);
-  box-shadow: 0 24px 48px rgba(33, 77, 145, 0.14);
+  border-color: rgba(115, 145, 255, 0.42);
+  box-shadow: 0 28px 54px rgba(0, 0, 0, 0.42);
 }
 
 .drive-card__icon {
   display: flex;
   align-items: center;
   justify-content: center;
-  width: 64px;
-  height: 64px;
-  border-radius: 18px;
-  /* background: linear-gradient(135deg, #2f6fdb 0%, #6ea2ff 100%); */
+  width: 120px;
+  height: 120px;
+  border-radius: 22px;
   color: #fff;
-  font-size: 30px;
+  font-size: 42px;
   flex-shrink: 0;
-  box-shadow: 0 14px 28px rgba(47, 111, 219, 0.24);
 }
 
 .drive-card__content {
@@ -220,21 +331,21 @@ const openDrive = async (option: DriveCard) => {
 
 .drive-card__title {
   margin: 0;
-  color: #17345f;
-  font-size: 24px;
+  color: #f4f7ff;
+  font-size: 28px;
   font-weight: 700;
 }
 
 .drive-card__text {
   margin: 10px 0 0;
-  color: #6c809d;
-  font-size: 14px;
+  color: rgba(191, 203, 235, 0.82);
+  font-size: 16px;
   line-height: 1.7;
 }
 
 .drive-card__arrow {
-  color: #7c93b6;
-  font-size: 26px;
+  color: rgba(210, 220, 248, 0.82);
+  font-size: 34px;
   flex-shrink: 0;
   transition:
     transform 0.2s ease,
@@ -242,25 +353,61 @@ const openDrive = async (option: DriveCard) => {
 }
 
 .drive-card:hover .drive-card__arrow {
-  color: #2f6fdb;
+  color: #ffffff;
   transform: translate(2px, -2px);
 }
 
 @media (max-width: 768px) {
   .drive-main {
-    padding: 112px 16px 56px;
+    padding: 50px 0px 56px;
+    margin-top: 0;
+  }
+
+  .drive-hero {
+    min-height: 260px;
+  }
+
+  .drive-hero__copy {
+    left: 20px;
+    right: 20px;
+    top: 24px;
+  }
+
+  .drive-tabs {
+    grid-template-columns: repeat(2, minmax(0, 1fr));
   }
 
   .drive-grid {
     grid-template-columns: 1fr;
+    gap: 16px;
+    padding-left: 0;
   }
 
   .drive-card {
-    padding: 22px 18px;
+    min-height: 100px;
+    height: 0px;
+    width: 100vw;
+    padding: 0;
+    margin-top: 0;
+
+    /* padding: 22px 18px; */
+    background-image: url("@/assets/images/mobile.png");
+    background-size: contain;
+    background-position: center center;
   }
 
+  /* .drive-card__icon {
+    width: 88px;
+    height: 88px;
+  } */
+
   .drive-card__title {
     font-size: 20px;
   }
+
+  .drive-hero__image :deep(img) {
+    object-fit: cover;
+    object-position: 68% center;
+  }
 }
 </style>

+ 1 - 1
src/views/flow/oaDoneList.vue

@@ -56,7 +56,6 @@
             prop="requestName"
             label="&#35831;&#27714;&#26631;&#39064;"
             min-width="250"
-            fixed="left"
             align="center"
           />
           <el-table-column
@@ -165,6 +164,7 @@
 </template>
 
 <script setup>
+import * as dd from "dingtalk-jsapi";
 import Header from "@components/home/header.vue";
 import { ref, onMounted } from "vue";
 import { getOATasks, ssoLogin } from "@/api/user";

+ 1 - 0
src/views/flow/todoList.vue

@@ -166,6 +166,7 @@
 
 <script setup>
 import Header from "@components/home/header.vue";
+import * as dd from "dingtalk-jsapi";
 import { ref, onMounted } from "vue";
 import { getOATasks, ssoLogin } from "@/api/user";
 import { useUserStore } from "@/stores/useUserStore";

+ 277 - 327
src/views/index.vue

@@ -6,7 +6,7 @@
       <section class="hero-banner overflow-hidden rounded-[6px] relative">
         <div class="">
           <!-- 轮播容器 -->
-          <div class="carousel-container relative h-full">
+          <div class="carousel-container relative h-[50%]">
             <!-- 轮播项 -->
             <div
               class="carousel-slide absolute inset-0 transition-opacity duration-500 ease-in-out"
@@ -90,17 +90,17 @@
           <article
             v-for="section in portalSections"
             :key="section.code"
-            class="platform-block rounded-sm"
+            class="platform-block rounded-sm md:flex"
             :style="{ minHeight: section.height }"
           >
             <div class="platform-block__header">
+              <img src="../assets//images/icon.png" alt="" class="w-20 h-20" />
               <div class="platform-block__title-wrap">
                 <p class="platform-block__title">{{ section.title }}</p>
                 <span class="platform-block__subtitle">{{
                   section.subtitle
                 }}</span>
               </div>
-              <span class="platform-block__watermark">{{ section.code }}</span>
             </div>
 
             <div
@@ -146,6 +146,7 @@
             <div class="side-card__header w-[95%] ml-[8px]">
               <div class="notice-tabs">
                 <button
+                  style="color: #fff !important"
                   v-for="tab in noticeTabs"
                   :key="tab.key"
                   type="button"
@@ -158,12 +159,13 @@
                   {{ tab.label }}
                 </button>
               </div>
-              <button type="button" class="side-card__more">
-                <Icon
-                  icon="mdi:dots-horizontal"
-                  class="text-[22px]"
-                  @click="handleNoticeMoreClick"
-                />
+              <button
+                type="button"
+                class="side-card__more"
+                @click="handleNoticeMoreClick"
+              >
+                更多
+                <Icon icon="mingcute:right-line" class="text-[18px]" />
               </button>
             </div>
 
@@ -201,13 +203,14 @@
             :style="{ minHeight: '190px' }"
           >
             <div class="side-card__header w-[91%] ml-[15px]">
-              <div class="notice-badge px-2">{{ todoPanelTitle }}</div>
+              <div class="notice-badge px-2 pb-2">{{ todoPanelTitle }}</div>
               <button
                 type="button"
                 class="side-card__more"
                 @click="router.push('/todo-list')"
               >
                 全部任务
+                <Icon icon="mingcute:right-line" class="text-[18px]" />
               </button>
             </div>
             <div class="space-y-2 p-4 pt-2">
@@ -257,9 +260,10 @@
             :style="{ minHeight: '180px' }"
           >
             <div class="side-card__header w-[90%] ml-[15px]">
-              <div class="notice-badge">{{ newsPanelTitle }}</div>
+              <div class="news notice-badge pb-2">{{ newsPanelTitle }}</div>
               <button type="button" class="side-card__more" @click="goNews">
-                <Icon icon="mdi:dots-horizontal" class="text-[22px]" />
+                更多
+                <Icon icon="mingcute:right-line" class="text-[18px]" />
               </button>
             </div>
             <div class="space-y-2 p-4 pt-2">
@@ -284,7 +288,7 @@
               >
                 <div class="min-w-0 flex-1">
                   <div
-                    class="line-clamp-1 text-[13px] font-semibold leading-[1.45] text-[#41597d]"
+                    class="line-clamp-1 text-[13px] font-semibold leading-[1.45] text-[#c8d0e5]"
                   >
                     {{ news.docsubject }}
                   </div>
@@ -369,8 +373,9 @@ import { getAccessToken } from "@/utils/auth";
 import { deleteUserCache } from "@hooks/useCache";
 import { manualLogoutKey, reloginCancelKey } from "@/config/axios/service";
 import banner1 from "@/assets/images/banner1.png";
-import banner2 from "@/assets/images/banner2.jpg";
+import banner2 from "@/assets/images/banner2.png";
 import banner3 from "@/assets/images/banner3.jpg";
+import banner4 from "@/assets/images/banner4.png";
 import oaimage from "@/assets/images/oa.jpg";
 import crmimage from "@/assets/images/crm.jpg";
 import ehrimage from "@/assets/images/ehr.jpg";
@@ -481,7 +486,7 @@ const portalSections: PortalSection[] = [
   {
     code: "AI",
     title: "Chat BI平台",
-    subtitle: "高效协同 · 战略洞察",
+    subtitle: "数据智能 · 决策驱动",
     height: "160px",
     apps: [
       { label: "全局数据治理(数据中台)", image: dataimage, active: true },
@@ -522,14 +527,14 @@ const getGreeting = () => {
 const slides = ref([
   {
     image: banner1,
-    text: getGreeting() + ",保持热爱,奔赴目标!",
+    text: "",
   },
   {
     image: banner2,
-    text: "数字化转型,驱动未来增长",
+    text: "",
   },
   {
-    image: banner3,
+    image: banner4,
     text: "智慧平台,赋能高效协同",
   },
 ]);
@@ -1007,30 +1012,52 @@ onUnmounted(() => {
 
 <style scoped>
 .portal-home {
-  --portal-blue: #2f6fdb;
-  --portal-blue-dark: #1b57bc;
-  --portal-blue-soft: #d7e7ff;
-  --portal-panel: #deebfb;
-  --portal-panel-soft: #edf5ff;
-  --portal-line: #a8c4f2;
-  background-color: #eef3f9;
-  background-image: url("../assets//images/bg666.png");
-  background-position: center bottom;
-  background-repeat: no-repeat;
-  background-size: 100% auto;
-  background-attachment: fixed;
+  --portal-bg: #050b1a;
+  --portal-bg-2: #081326;
+  --portal-line: rgba(97, 129, 206, 0.28);
+  --portal-card: rgba(10, 19, 43, 0.8);
+  --portal-card-2: rgba(12, 24, 52, 0.92);
+  --portal-accent: #6e7dff;
+  --portal-accent-2: #8d4dff;
+  color: #eaf1ff;
+  background:
+    radial-gradient(
+      circle at 18% 12%,
+      rgba(79, 82, 221, 0.34),
+      transparent 22%
+    ),
+    radial-gradient(circle at 82% 20%, rgba(28, 95, 255, 0.2), transparent 20%),
+    radial-gradient(
+      circle at 50% 100%,
+      rgba(103, 46, 255, 0.16),
+      transparent 28%
+    ),
+    linear-gradient(180deg, #040814 0%, #060d1d 46%, #040814 100%);
+  background-image:
+    linear-gradient(rgba(5, 11, 26, 0.62), rgba(5, 11, 26, 0.82)),
+    url("../assets//images/bg666.png");
+  background-position:
+    center center,
+    center bottom;
+  background-repeat: no-repeat, no-repeat;
+  background-size:
+    cover,
+    100% auto;
+  background-attachment: fixed, fixed;
 }
 
 .hero-banner {
   position: relative;
-  min-height: 220px;
-  background: linear-gradient(
-    90deg,
-    rgba(255, 255, 255, 0.96) 0%,
-    rgba(241, 247, 255, 0.92) 36%,
-    rgba(223, 237, 255, 0.95) 100%
-  );
-  box-shadow: 0 16px 34px rgba(59, 112, 190, 0.08);
+  min-height: 310px;
+  border: 1px solid rgba(113, 140, 214, 0.16);
+  border-radius: 10px;
+  background:
+    linear-gradient(135deg, rgba(63, 91, 211, 0.32), transparent 32%),
+    linear-gradient(180deg, rgba(9, 16, 36, 0.82), rgba(4, 9, 20, 0.9));
+  box-shadow:
+    0 24px 60px rgba(0, 0, 0, 0.38),
+    inset 0 1px 0 rgba(255, 255, 255, 0.06);
+  overflow: hidden;
 }
 
 .hero-banner::before {
@@ -1038,229 +1065,149 @@ onUnmounted(() => {
   position: absolute;
   inset: 0;
   background:
-    linear-gradient(140deg, rgba(206, 223, 247, 0.25) 0%, transparent 28%),
+    linear-gradient(120deg, rgba(128, 77, 255, 0.14) 0%, transparent 26%),
     radial-gradient(
-      circle at 74% 24%,
-      rgba(83, 146, 255, 0.14),
-      transparent 18%
+      circle at 20% 36%,
+      rgba(123, 84, 255, 0.22),
+      transparent 22%
     ),
     radial-gradient(
-      circle at 88% 16%,
-      rgba(255, 255, 255, 0.94),
-      transparent 14%
+      circle at 74% 52%,
+      rgba(54, 170, 255, 0.18),
+      transparent 24%
+    ),
+    linear-gradient(
+      90deg,
+      rgba(255, 255, 255, 0.04),
+      transparent 40%,
+      rgba(255, 255, 255, 0.02)
     );
   pointer-events: none;
 }
 
-.hero-banner__inner {
-  position: relative;
-  z-index: 1;
-  display: grid;
-  min-height: 220px;
-  grid-template-columns: minmax(260px, 1fr) minmax(360px, 1.3fr);
-  align-items: center;
-  gap: 24px;
-  padding: 22px 36px 18px 58px;
-}
-
 .hero-copy {
-  /* padding-top: 10px; */
+  position: relative;
+  z-index: 2;
 }
 
 .hero-script {
-  color: #0c4eb5;
-  font-size: 68px;
-  font-style: italic;
-  font-weight: 500;
-  letter-spacing: 0.04em;
-  line-height: 1;
-  font-family: "Comic Sans MS", "Segoe Script", cursive;
+  display: none;
 }
 
 .hero-text {
-  margin-top: 18px;
-  color: #5f6f83;
-  font-size: 24px;
-  letter-spacing: 0.1em;
-}
-
-.hero-progress {
-  margin-top: 48px;
-  display: flex;
-  align-items: center;
-  gap: 12px;
-}
-
-.hero-progress__active {
-  height: 4px;
-  width: 56px;
-  border-radius: 999px;
-  background: #1f67d1;
-}
-
-.hero-progress__line {
-  height: 3px;
-  width: 64px;
-  border-radius: 999px;
-  background: rgba(49, 113, 207, 0.18);
+  margin-top: 0;
+  color: rgba(234, 241, 255, 0.95);
+  font-size: 46px;
+  font-weight: 800;
+  line-height: 1.2;
+  letter-spacing: 0.02em;
+  text-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
+  max-width: 540px;
 }
 
 .hero-visual {
-  position: relative;
-  min-height: 180px;
-}
-
-.hero-orb,
-.hero-cube,
-.hero-ring {
   position: absolute;
+  inset: 0;
+  min-height: 310px;
 }
 
-.hero-orb {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-
-  border-radius: 28px;
-  background: linear-gradient(
-    180deg,
-    rgba(255, 255, 255, 0.98),
-    rgba(226, 239, 255, 0.95)
-  );
-  color: #65a4ff;
-  box-shadow:
-    0 18px 35px rgba(65, 122, 206, 0.14),
-    inset 0 1px 0 rgba(255, 255, 255, 0.88);
-}
-
-.hero-orb::after {
+.hero-visual::after {
   content: "";
   position: absolute;
-  inset: auto 16px 10px;
-  height: 10px;
-  border-radius: 999px;
-  background: rgba(93, 154, 255, 0.12);
-  filter: blur(8px);
-}
-
-.hero-orb--cloud {
-  left: 10%;
-  top: 28px;
-  height: 106px;
-  width: 126px;
-  transform: rotate(-10deg);
-}
-
-.hero-orb--shield {
-  left: 46%;
-  top: 64px;
-  height: 118px;
-  width: 120px;
-  transform: rotate(8deg);
+  inset: 0;
+  background:
+    linear-gradient(90deg, rgba(5, 11, 26, 0.28) 0%, transparent 28%),
+    linear-gradient(
+      180deg,
+      transparent 0%,
+      rgba(5, 11, 26, 0.08) 56%,
+      rgba(5, 11, 26, 0.28) 100%
+    );
+  pointer-events: none;
 }
 
-.hero-orb--chart {
-  right: 4%;
-  top: 0;
-  height: 138px;
-  width: 150px;
-  transform: rotate(6deg);
+.carousel-container {
+  position: relative;
+  height: 310px;
+  overflow: hidden;
 }
 
-.hero-cube {
+.platform-block {
+  /* display: flex; */
+  overflow: hidden;
+  border: 1px solid rgba(109, 137, 213, 0.18);
+  border-radius: 8px;
   background: linear-gradient(
     180deg,
-    rgba(255, 255, 255, 0.94),
-    rgba(226, 239, 255, 0.9)
+    rgba(10, 18, 38, 0.92),
+    rgba(8, 15, 33, 0.92)
   );
-  box-shadow: 0 18px 35px rgba(65, 122, 206, 0.1);
-}
-
-.hero-cube--one {
-  left: 26%;
-  top: -2px;
-  height: 46px;
-  width: 46px;
-  transform: rotate(36deg);
-}
-
-.hero-cube--two {
-  left: 33%;
-  top: 18px;
-  height: 34px;
-  width: 34px;
-  transform: rotate(32deg);
-}
-
-.hero-ring {
-  left: 13%;
-  top: 108px;
-  height: 42px;
-  width: 128px;
-  border-radius: 999px;
-  background: rgba(83, 146, 255, 0.1);
-  box-shadow: inset 0 0 0 10px rgba(238, 245, 255, 0.72);
-}
-
-.platform-block {
-  overflow: hidden;
-  background: linear-gradient(180deg, #dce9fb 0%, #d9e8fb 100%);
-  box-shadow: 0 12px 28px rgba(58, 110, 187, 0.08);
+  box-shadow:
+    0 16px 34px rgba(0, 0, 0, 0.22),
+    inset 0 1px 0 rgba(255, 255, 255, 0.04);
 }
 
 .platform-block__header {
   display: flex;
   align-items: center;
   justify-content: space-between;
-  min-height: 44px;
-  padding: 0 24px 0 34px;
-  background: linear-gradient(90deg, #316fd8 0%, #82aef0 100%);
+  min-height: 48px;
+  padding: 0 22px 0 24px;
+  background: linear-gradient(
+    90deg,
+    rgba(44, 70, 154, 0.5),
+    rgba(18, 28, 62, 0.1)
+  );
 }
 
 .platform-block__title-wrap {
   display: flex;
+  flex-direction: column;
   align-items: baseline;
-  gap: 28px;
+  gap: 18px;
   min-width: 0;
 }
 
 .platform-block__title {
-  color: #fff;
+  color: #f4f7ff;
   font-size: 18px;
+  font-weight: 800;
   min-width: 0;
   flex: 0 1 auto;
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
-  letter-spacing: 0.03em;
+  letter-spacing: 0.02em;
 }
 
 .platform-block__subtitle {
-  color: rgba(255, 255, 255, 0.95);
+  color: rgba(188, 205, 255, 0.82);
   font-size: 13px;
-  font-weight: 600;
+  font-weight: 500;
   flex: 0 0 auto;
   white-space: nowrap;
 }
 
 .platform-block__watermark {
-  color: rgba(255, 255, 255, 0.4);
-  font-size: 44px;
+  color: rgba(119, 145, 214, 0.24);
+  font-size: 42px;
   font-weight: 800;
   line-height: 1;
-  letter-spacing: 0.04em;
+  letter-spacing: 0.08em;
 }
 
 .platform-app {
   display: flex;
   width: 100%;
   min-width: 0;
-  min-height: 34px;
+  min-height: 40px;
   align-items: center;
   justify-content: flex-start;
-  gap: 5px;
-  border-radius: 8px;
-  padding: 0 5px;
+  gap: 8px;
+  border: 1px solid rgba(109, 137, 213, 0.16);
+  border-radius: 10px;
+  padding: 0 10px;
+  background: rgba(17, 25, 48, 0.8);
 
   font-size: 14px;
   cursor: pointer;
@@ -1272,24 +1219,34 @@ onUnmounted(() => {
 }
 
 .platform-app:hover {
-  transform: translateY(-1px);
+  transform: translateY(-2px);
+  border-color: rgba(133, 163, 255, 0.45);
+  box-shadow: 0 10px 26px rgba(34, 54, 110, 0.3);
 }
 
 .platform-app--active {
-  background: rgba(255, 255, 255, 0.66);
-  font-weight: bold;
+  /* background: linear-gradient(
+    90deg,
+    rgba(76, 103, 224, 0.2),
+    rgba(23, 30, 58, 0.88)
+  );
+  color: #f4f7ff;
+  border-color: rgba(129, 145, 255, 0.44);
+  box-shadow: inset 0 0 0 1px rgba(159, 173, 255, 0.08); */
+  font-weight: 700;
 }
 
 .platform-app--ghost {
-  background: rgba(255, 255, 255, 0.66);
-  color: #53719b;
+  background: rgba(15, 24, 45, 0.82);
+  color: rgba(201, 212, 243, 0.9);
 }
 
 .platform-app__icon {
   display: inline-flex;
   align-items: center;
   justify-content: center;
-  color: currentColor;
+  color: #79b0ff;
+  filter: drop-shadow(0 0 8px rgba(90, 122, 255, 0.24));
 }
 
 .platform-app__label {
@@ -1298,6 +1255,7 @@ onUnmounted(() => {
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
+  color: #b8b9be;
 }
 
 .portal-mobile-shortcuts {
@@ -1308,21 +1266,32 @@ onUnmounted(() => {
 
 .portal-mobile-shortcut {
   min-width: 0;
-  border: 0;
-  border-radius: 10px;
+  border: 1px solid rgba(116, 145, 223, 0.18);
+  border-radius: 12px;
   padding: 10px 8px;
-  background: linear-gradient(180deg, #ffffff 0%, #5b90e4 100%);
-  color: #0d4a9d;
+  background: linear-gradient(
+    180deg,
+    rgba(17, 26, 52, 0.86),
+    rgba(10, 16, 32, 0.92)
+  );
+  color: #dfe8ff;
   font-size: 13px;
   font-weight: 600;
-  box-shadow: 0 6px 16px rgba(58, 110, 187, 0.08);
+  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
 }
 
 .side-card {
   overflow: hidden;
-
-  background: #e8f1f8;
-  /* box-shadow: 0 12px 28px rgba(58, 110, 187, 0.06); */
+  border: 1px solid rgba(109, 137, 213, 0.16);
+  border-radius: 14px;
+  background: linear-gradient(
+    180deg,
+    rgba(10, 18, 38, 0.92),
+    rgba(7, 14, 31, 0.94)
+  );
+  box-shadow:
+    0 16px 34px rgba(0, 0, 0, 0.22),
+    inset 0 1px 0 rgba(255, 255, 255, 0.04);
 }
 
 .side-card--content {
@@ -1335,9 +1304,9 @@ onUnmounted(() => {
   justify-content: space-between;
   min-height: 20px;
   padding-right: 10px;
-
-  border-radius: 100px;
-  background: #d5e6fc;
+  /* border-radius: 999px; */
+  /* background: rgba(28, 39, 72, 0.86); */
+  border-bottom: 1px solid rgba(109, 137, 213, 0.16);
 }
 
 .notice-badge {
@@ -1347,12 +1316,22 @@ onUnmounted(() => {
   justify-content: center;
   height: 25px;
   min-width: 70px;
-  /* padding: 0 5px 0 10px; */
-  background: #004098;
+
+  color: #fff;
+  font-size: 14px;
+}
+
+.news.notice-badge {
+  position: relative;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  height: 25px;
+  min-width: 70px;
+
   color: #fff;
   font-size: 14px;
-  font-weight: bold;
-  border-radius: 100px;
+  border-bottom: 2px solid #5e45bb;
 }
 
 .notice-tabs {
@@ -1368,9 +1347,9 @@ onUnmounted(() => {
   border: 0;
   border-radius: 999px;
   background: transparent;
-  color: #4d6f98;
+  color: rgba(183, 201, 244, 0.88);
   font-size: 14px;
-  font-weight: 700;
+
   cursor: pointer;
   transition:
     background 0.2s ease,
@@ -1378,8 +1357,29 @@ onUnmounted(() => {
 }
 
 .notice-tab--active {
-  background: #004098;
-  color: #fff;
+  position: relative;
+}
+
+.notice-tab--active::before {
+  content: "";
+  position: absolute;
+  left: 50%;
+  bottom: -2px;
+  width: 90%;
+  height: 2px;
+  transform: translateX(-50%);
+  border-radius: 999px;
+  background: linear-gradient(
+    to right,
+    #5f3abf 0%,
+    #7044c5 30%,
+    #7044c5 40%,
+    rgba(255, 255, 255, 0.7) 50%,
+    #7044c5 60%,
+    #7044c5 70%,
+    #5f3abf 100%
+  );
+  box-shadow: 0 0 12px rgba(112, 120, 255, 0.95);
 }
 
 .notice-badge::after {
@@ -1395,27 +1395,27 @@ onUnmounted(() => {
   justify-content: center;
   border: 0;
   background: transparent;
-  color: #0f53b4;
+  color: rgba(187, 203, 245, 0.82);
   cursor: pointer;
   font-size: 12px;
 }
 
 .notice-item {
-  background: #fff;
+  /* background: rgba(14, 22, 42, 0.88); */
   padding: 8px 14px;
-  box-shadow: 0 8px 22px rgba(63, 107, 169, 0.06);
-  border-radius: 10px;
+  box-shadow: 0 10px 22px rgba(0, 0, 0, 0.14);
+  border-radius: 12px;
 }
 
 .notice-item:hover {
-  box-shadow: 0 12px 28px rgba(63, 107, 169, 0.1);
+  box-shadow: 0 16px 30px rgba(0, 0, 0, 0.22);
   transition: all 0.2s ease;
   transform: translateY(-1px);
 }
 
 .notice-item__title,
 .notice-item__desc {
-  color: #507698;
+  color: rgba(224, 232, 255, 0.9);
   font-size: 13px;
   line-height: 1.5;
   display: -webkit-box;
@@ -1426,15 +1426,16 @@ onUnmounted(() => {
 
 .panel-title {
   padding: 0 16px;
-  color: #2f4d79;
+  color: #eff4ff;
   font-size: 15px;
   font-weight: 700;
 }
 
 .todo-item {
-  background: rgba(255, 255, 255, 0.88);
+  border: 1px solid rgba(109, 137, 213, 0.12);
+  background: rgba(14, 22, 42, 0.88);
   padding: 8px 14px;
-  box-shadow: 0 8px 22px rgba(63, 107, 169, 0.05);
+  box-shadow: 0 10px 22px rgba(0, 0, 0, 0.14);
 }
 
 .todo-item__tag {
@@ -1451,14 +1452,15 @@ onUnmounted(() => {
   display: flex;
   align-items: center;
   gap: 12px;
-  background: rgba(255, 255, 255, 0.88);
+  border: 1px solid rgba(109, 137, 213, 0.12);
+  background: rgba(14, 22, 42, 0.88);
   padding: 5px 12px;
-  box-shadow: 0 8px 22px rgba(63, 107, 169, 0.05);
-  border: none;
+  box-shadow: 0 10px 22px rgba(0, 0, 0, 0.14);
+  border-radius: 12px;
 }
 
 .news-mini:hover {
-  box-shadow: 0 12px 28px rgba(63, 107, 169, 0.1);
+  box-shadow: 0 16px 30px rgba(0, 0, 0, 0.22);
   transition: all 0.2s ease;
   transform: translateY(-1px);
 }
@@ -1466,7 +1468,6 @@ onUnmounted(() => {
 .placeholder-panel {
   display: flex;
   height: 100%;
-  /* align-items: center; */
   padding: 16px;
   justify-content: start;
   color: #fff;
@@ -1476,25 +1477,13 @@ onUnmounted(() => {
 }
 
 @media (max-width: 1279px) {
-  .hero-banner__inner {
-    grid-template-columns: 1fr;
-    padding: 28px 28px 20px;
-  }
-
-  .hero-script {
-    font-size: 52px;
-  }
-
   .hero-text {
-    font-size: 18px;
-  }
-
-  .hero-progress {
-    margin-top: 28px;
+    font-size: 34px;
+    max-width: 420px;
   }
 
   .hero-visual {
-    min-height: 220px;
+    min-height: 260px;
   }
 }
 
@@ -1520,79 +1509,44 @@ onUnmounted(() => {
     font-size: 34px;
   }
 
-  .hero-banner__inner {
-    padding: 24px 18px 20px;
+  .hero-banner {
+    min-height: 240px;
   }
-
-  .hero-script {
-    font-size: 44px;
+  .carousel-container {
+    height: 240px;
   }
 
-  .hero-progress {
-    margin-top: 22px;
+  .carousel-caption {
+    left: 22px;
+    right: 22px;
+    top: 50%;
+    transform: translateY(-50%);
   }
-}
-
-.carousel-container {
-  position: relative;
-  height: 220px;
-  overflow: hidden;
-}
-
-.carousel-slide {
-  position: relative;
-  background-size: cover;
-  background-position: center;
-}
 
-.hero-visual img {
-  width: 100%;
-  height: 100%;
-  object-fit: cover;
-}
-
-.carousel-caption {
-  position: absolute;
-  left: 40px;
-  top: 40%;
-  z-index: 2;
-  transform: translateY(-50%);
-  text-align: left;
+  .hero-text {
+    font-size: 24px;
+    max-width: 100%;
+  }
 }
 
 .carousel-indicators {
   display: flex;
-  gap: 8px;
+  gap: 10px;
   z-index: 30;
 }
 
-.carousel-indicators button {
-  width: 12px;
-  height: 12px;
-  border-radius: 50%;
+.carousel-indicators span {
+  width: 36px;
+  height: 4px;
+  border-radius: 999px;
   cursor: pointer;
-  transition: all 0.3s ease;
-  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.8);
-}
-
-.carousel-container {
-  position: relative;
-  /* 确保容器在移动端有合适的高度,或者使用 aspect-ratio */
-  height: 220px;
-  width: 100%;
-  overflow: hidden;
+  transition: all 0.25s ease;
+  box-shadow: 0 0 16px rgba(112, 103, 255, 0.35);
 }
 
 .carousel-slide {
   position: absolute;
-  inset: 0; /* 确保填满父容器 */
-  width: 100%;
-  height: 100%;
-}
-
-.hero-visual {
-  position: absolute;
-  inset: 0; /* 关键:让背景层填满整个 slide */
+  inset: 0;
   width: 100%;
   height: 100%;
 }
@@ -1600,35 +1554,31 @@ onUnmounted(() => {
 .hero-visual img {
   width: 100%;
   height: 100%;
-  /* 关键修改:使用 cover 确保图片填满容器且不留白,即使部分被裁剪 */
   object-fit: cover;
-  /* 如果希望完整显示图片但可能有留白,改用 object-fit: contain; 但通常 banner 推荐 cover */
-  display: block; /* 消除 img 默认的底部间隙 */
+  display: block;
+  filter: saturate(1.12) contrast(1.06);
 }
 
-/* 移动端适配优化 */
-@media (max-width: 768px) {
-  .carousel-container {
-    /* 移动端可以适当减小高度,或者保持比例 */
-    height: 220px;
-  }
-
-  .carousel-caption {
-    /* 移动端调整文字位置,避免遮挡图片或超出屏幕 */
-    left: 20px;
-    right: 20px;
-    top: 50%;
-    transform: translateY(-50%);
-    text-align: center; /* 移动端居中通常更好看 */
-  }
+.carousel-caption {
+  position: absolute;
+  left: 80px;
+  top: 44%;
+  z-index: 2;
+  transform: translateY(-50%);
+  text-align: left;
+}
 
-  .hero-script {
-    font-size: 40px; /* 适当减小字体 */
-  }
+.carousel-container::before {
+  content: "";
+  position: absolute;
+  inset: auto 0 0;
+  height: 120px;
+  background: linear-gradient(180deg, transparent, rgba(5, 11, 26, 0.6));
+  z-index: 1;
+  pointer-events: none;
+}
 
-  .hero-text {
-    font-size: 16px;
-    margin-top: 10px;
-  }
+:deep(.portal-home .el-dialog) {
+  border-radius: 16px;
 }
 </style>

+ 2 - 2
src/views/login.vue

@@ -21,7 +21,7 @@
         <h1 class="text-2xl font-bold text-center">登录</h1>
 
         <!-- 用户名密码登陆 -->
-        <!-- <div>
+        <div>
           <el-form
             :model="form"
             :rules="rules"
@@ -62,7 +62,7 @@
               >
             </div>
           </div>
-        </div> -->
+        </div>
 
         <!-- 钉钉登陆 -->
         <div class="text-center">

+ 1 - 0
src/views/news/index.vue

@@ -98,6 +98,7 @@
 </template>
 
 <script setup>
+import * as dd from "dingtalk-jsapi";
 import { ref, reactive, onMounted } from "vue";
 import Header from "@components/home/header.vue";
 import Footer from "@components/home/Footer.vue";

+ 1 - 0
src/views/notices/index.vue

@@ -99,6 +99,7 @@
 
 <script setup>
 import { ref, reactive, onMounted } from "vue";
+import * as dd from "dingtalk-jsapi";
 import Header from "@components/home/header.vue";
 import Footer from "@components/home/Footer.vue";
 import { ElLoading } from "element-plus";