yanghao hace 2 semanas
padre
commit
e8fd02ee1d
Se han modificado 2 ficheros con 156 adiciones y 74 borrados
  1. BIN
      src/assets/images/bg666.png
  2. 156 74
      src/views/index.vue

BIN
src/assets/images/bg666.png


+ 156 - 74
src/views/index.vue

@@ -2,7 +2,7 @@
   <div class="portal-home min-h-screen bg-[#eef3f9] text-[#17345f]">
     <Header />
 
-    <main class="mx-auto max-w-[1500px] px-6 pb-8 pt-24">
+    <main class="mx-auto max-w-[1200px] px-6 pb-8 pt-24">
       <section class="hero-banner overflow-hidden rounded-[6px]">
         <div class="hero-banner__inner">
           <div class="hero-copy">
@@ -41,8 +41,10 @@
           >
             <div class="platform-block__header">
               <div class="platform-block__title-wrap">
-                <h2 class="platform-block__title">{{ section.title }}</h2>
-                <span class="platform-block__subtitle">{{ section.subtitle }}</span>
+                <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>
@@ -57,7 +59,9 @@
                 type="button"
                 :class="[
                   'platform-app',
-                  app.active ? 'platform-app--active' : 'platform-app--ghost',
+                  boldLabes.includes(app.label)
+                    ? 'platform-app--active'
+                    : 'platform-app--ghost',
                 ]"
                 @click="handlePortalAppClick(app)"
               >
@@ -68,95 +72,136 @@
                     :alt="app.label"
                     class="h-7 w-7 object-contain"
                   />
-                  <Icon v-else :icon="app.icon || 'mdi:dots-grid'" class="text-[24px]" />
+                  <Icon
+                    v-else
+                    :icon="app.icon || 'mdi:dots-grid'"
+                    class="text-[24px]"
+                  />
                 </span>
-                <span>{{ app.label }}</span>
+                <span class="text-[#004098] text-sm">{{ app.label }}</span>
               </button>
             </div>
           </article>
         </div>
 
         <aside class="space-y-4">
-          <section class="side-card side-card--notice">
-            <div class="side-card__header">
+          <section class="side-card side-card--notice rounded-md p-2">
+            <div class="side-card__header w-[95%] ml-[8px]">
               <div class="notice-badge">{{ noticeLabel }}</div>
               <button type="button" class="side-card__more">
                 <Icon icon="mdi:dots-horizontal" class="text-[22px]" />
               </button>
             </div>
 
-            <div class="space-y-3 p-4 pt-3">
+            <div class="space-y-2 p-2 pt-3">
               <article
                 v-for="(notice, noticeIndex) in notices"
                 :key="`${notice.title}-${noticeIndex}`"
                 class="notice-item cursor-pointer"
               >
-                <div class="notice-item__title">{{ notice.title }}</div>
                 <div class="notice-item__desc">{{ notice.desc }}</div>
               </article>
             </div>
           </section>
 
-          <section class="side-card side-card--content" :style="{ minHeight: '190px' }">
-            <div class="panel-title">{{ todoPanelTitle }}</div>
-            <div class="space-y-3 p-4 pt-2">
+          <section
+            class="side-card side-card--notice rounded-md p-2"
+            :style="{ minHeight: '190px' }"
+          >
+            <div class="side-card__header w-[91%] ml-[15px]">
+              <div class="notice-badge px-2">{{ todoPanelTitle }}</div>
+              <button type="button" class="side-card__more">全部任务</button>
+            </div>
+            <div class="space-y-2 p-4 pt-2">
               <article
                 v-for="task in todoTasks"
                 :key="task.title"
-                class="todo-item"
+                class="todo-item rounded-md"
               >
                 <div class="flex min-w-0 items-start justify-between gap-3">
                   <div class="min-w-0">
-                    <div class="truncate text-[14px] font-semibold text-[#3a5173]">
+                    <div
+                      class="truncate text-[14px] font-semibold text-[#0d4a9d]"
+                    >
                       {{ task.title }}
                     </div>
-                    <div class="mt-2 text-[12px] text-[#8a9ab0]">{{ task.meta }}</div>
+                    <div class="mt-1 text-[12px] text-[#8a9ab0]">
+                      {{ task.meta }}
+                    </div>
                   </div>
-                  <span :class="['todo-item__tag', task.tagClass]">{{ task.tag }}</span>
+                  <span :class="['todo-item__tag', task.tagClass]">{{
+                    task.tag
+                  }}</span>
                 </div>
               </article>
             </div>
           </section>
 
-          <section class="side-card side-card--content" :style="{ minHeight: '180px' }">
-            <div class="panel-title">{{ newsPanelTitle }}</div>
-            <div class="space-y-3 p-4 pt-2">
+          <section
+            class="side-card side-card--content p-2 rounded-md"
+            :style="{ minHeight: '180px' }"
+          >
+            <div class="side-card__header w-[90%] ml-[15px]">
+              <div class="notice-badge">{{ newsPanelTitle }}</div>
+              <button type="button" class="side-card__more">
+                <Icon icon="mdi:dots-horizontal" class="text-[22px]" />
+              </button>
+            </div>
+            <div class="space-y-2 p-4 pt-2">
               <article
                 v-for="news in newsList"
                 :key="news.title"
-                class="news-mini cursor-pointer"
+                class="news-mini cursor-pointer rounded-md"
               >
                 <img
                   :src="news.image"
                   :alt="news.title"
-                  class="h-[54px] w-[72px] rounded-[8px] object-cover"
+                  class="h-[34px] w-[52px] rounded-[8px] object-cover"
                 />
                 <div class="min-w-0 flex-1">
-                  <div class="line-clamp-2 text-[13px] font-semibold leading-[1.45] text-[#41597d]">
+                  <div
+                    class="line-clamp-2 text-[13px] font-semibold leading-[1.45] text-[#41597d]"
+                  >
                     {{ news.title }}
                   </div>
-                  <div class="mt-2 text-[12px] text-[#9cadc0]">{{ news.date }}</div>
+                  <div class="mt-2 text-[12px] text-[#9cadc0]">
+                    {{ news.date }}
+                  </div>
                 </div>
               </article>
             </div>
           </section>
 
-          <section class="side-card side-card--placeholder" :style="{ minHeight: '78px' }">
-            <div class="placeholder-panel">
-              <div class="placeholder-panel__title">{{ quickEntryTitle }}</div>
+          <section
+            class="side-card side-card--placeholder rounded-md"
+            :style="{ minHeight: '78px', backgroundColor: '#3575e4' }"
+          >
+            <div class="placeholder-panel flex flex-col text-left">
+              <div class="text-sm">需要帮助?</div>
+              <div class="text-[10px]">
+                遇到系统操作问题?我们的7 x 24 小时AI助手随时待命。
+              </div>
+              <div
+                class="bg-white text-sm text-center text-[#004098] py-1 px-2 rounded-full mt-2 w-[30%] cursor-pointer"
+              >
+                立即咨询
+              </div>
             </div>
           </section>
         </aside>
       </section>
     </main>
+
+    <Footer />
   </div>
 </template>
 
 <script setup lang="ts">
-import { onMounted } from "vue";
+import { onMounted, ref } from "vue";
 import * as authUtil from "@/utils/auth";
 import * as dd from "dingtalk-jsapi";
 import Header from "@components/home/header.vue";
+import Footer from "@components/home/Footer.vue";
 import { useRouter } from "vue-router";
 import axios from "axios";
 import { Icon } from "@iconify/vue";
@@ -189,6 +234,9 @@ import youimage from "@/assets/images/youcnag.png";
 import fileagent from "@/assets/images/fileagent.png";
 import zhiduagent from "@/assets/images/zhiduagent.png";
 import jishuimage2 from "@/assets/images/jishuimage.png";
+import zhanlueimage from "@/assets/images/zhanlue.jpg"; // 战略解码
+import safeimage from "@/assets/images/safe.png"; // 安全合规管理
+import zuzhiimage from "@/assets/images/zuzhi.jpg";
 
 type PortalApp = {
   label: string;
@@ -233,8 +281,7 @@ const userStore = useUserStore();
 const heroGreeting = "早上好,保持热爱,奔赴目标!";
 const noticeLabel = "公告";
 const todoPanelTitle = "待办中心";
-const newsPanelTitle = "新闻中心";
-const quickEntryTitle = "快捷入口";
+const newsPanelTitle = "新闻";
 
 const portalSections: PortalSection[] = [
   {
@@ -254,6 +301,10 @@ const portalSections: PortalSection[] = [
       { label: "财务管理(FM)", image: erpimage },
       { label: "经营驾驶舱(MC)", image: driveimage },
       { label: "项目管理(PM)", image: pmimage },
+      { label: "技术研发管理", image: jishuimage2 },
+      { label: "战略解码与执行", image: zhanlueimage },
+      { label: "组织资产管理", image: zuzhiimage },
+      { label: "风控合规管理", image: safeimage },
       { label: "研发需求管理", image: jishuimage2 },
     ],
   },
@@ -289,6 +340,15 @@ const portalSections: PortalSection[] = [
   },
 ];
 
+let boldLabes = ref([
+  "OA办公",
+  "客户管理(CRM)",
+  "设备管理(PMS)",
+  "中航北斗",
+  "智慧连油",
+  "质量安全管理(QHSE)",
+]);
+
 const notices: NoticeItem[] = [
   {
     title: "集团总部关于办公楼设备维保的说明",
@@ -422,7 +482,9 @@ const handlePortalAppClick = async (app: PortalApp) => {
 
   if (app.label === "研发需求管理") {
     if (userStore.getUser.username && getAccessToken()) {
-      const res = await zentaoSsoLogin({ username: userStore.getUser.username });
+      const res = await zentaoSsoLogin({
+        username: userStore.getUser.username,
+      });
       if (res) {
         window.open(
           `http://project.deepoil.cc/zentao/api.php?m=user&f=apilogin&account=${res.jobNumber}&code=${res.code}&time=${res.timestamp}&token=${res.token}`,
@@ -501,9 +563,13 @@ onMounted(() => {
 .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: inset 0 0 0 1px rgba(190, 212, 243, 0.5);
+  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);
 }
 
 .hero-banner::before {
@@ -512,8 +578,16 @@ onMounted(() => {
   inset: 0;
   background:
     linear-gradient(140deg, rgba(206, 223, 247, 0.25) 0%, transparent 28%),
-    radial-gradient(circle at 74% 24%, rgba(83, 146, 255, 0.14), transparent 18%),
-    radial-gradient(circle at 88% 16%, rgba(255, 255, 255, 0.94), transparent 14%);
+    radial-gradient(
+      circle at 74% 24%,
+      rgba(83, 146, 255, 0.14),
+      transparent 18%
+    ),
+    radial-gradient(
+      circle at 88% 16%,
+      rgba(255, 255, 255, 0.94),
+      transparent 14%
+    );
   pointer-events: none;
 }
 
@@ -585,9 +659,13 @@ onMounted(() => {
   display: flex;
   align-items: center;
   justify-content: center;
-  border: 1px solid rgba(175, 205, 250, 0.88);
+
   border-radius: 28px;
-  background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(226, 239, 255, 0.95));
+  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),
@@ -629,8 +707,11 @@ onMounted(() => {
 }
 
 .hero-cube {
-  border: 1px solid rgba(171, 199, 243, 0.8);
-  background: linear-gradient(180deg, rgba(255, 255, 255, 0.94), rgba(226, 239, 255, 0.9));
+  background: linear-gradient(
+    180deg,
+    rgba(255, 255, 255, 0.94),
+    rgba(226, 239, 255, 0.9)
+  );
   box-shadow: 0 18px 35px rgba(65, 122, 206, 0.1);
 }
 
@@ -656,13 +737,14 @@ onMounted(() => {
   height: 42px;
   width: 128px;
   border-radius: 999px;
-  border: 10px solid rgba(83, 146, 255, 0.1);
+  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: inset 0 0 0 1px rgba(184, 207, 239, 0.85);
+  box-shadow: 0 12px 28px rgba(58, 110, 187, 0.08);
 }
 
 .platform-block__header {
@@ -683,7 +765,7 @@ onMounted(() => {
 .platform-block__title {
   color: #fff;
   font-size: 18px;
-  font-weight: 700;
+
   letter-spacing: 0.03em;
 }
 
@@ -710,7 +792,8 @@ onMounted(() => {
   border-radius: 8px;
   padding: 0 18px;
   font-size: 14px;
-  font-weight: 600;
+  cursor: pointer;
+
   transition:
     transform 0.2s ease,
     box-shadow 0.2s ease,
@@ -722,9 +805,8 @@ onMounted(() => {
 }
 
 .platform-app--active {
-  background: linear-gradient(180deg, #3979e0 0%, #326fd8 100%);
-  color: #fff;
-  box-shadow: 0 8px 18px rgba(42, 103, 198, 0.28);
+  background: rgba(255, 255, 255, 0.66);
+  font-weight: bold;
 }
 
 .platform-app--ghost {
@@ -741,8 +823,8 @@ onMounted(() => {
 
 .side-card {
   overflow: hidden;
-  background: rgba(245, 250, 255, 0.95);
-  box-shadow: inset 0 0 0 1px rgba(226, 237, 249, 0.95);
+  background: #e8f1f8;
+  /* box-shadow: 0 12px 28px rgba(58, 110, 187, 0.06); */
 }
 
 .side-card--content {
@@ -753,23 +835,26 @@ onMounted(() => {
   display: flex;
   align-items: center;
   justify-content: space-between;
-  min-height: 32px;
+  min-height: 20px;
   padding-right: 10px;
-  background: linear-gradient(90deg, rgba(236, 244, 255, 0.95), rgba(226, 239, 255, 0.92));
-  border-bottom: 1px solid rgba(195, 214, 239, 0.9);
+
+  border-radius: 100px;
+  background: #d5e6fc;
 }
 
 .notice-badge {
   position: relative;
   display: inline-flex;
   align-items: center;
-  height: 32px;
-  min-width: 64px;
-  padding: 0 18px 0 16px;
-  background: linear-gradient(180deg, #1661c9 0%, #0f53b4 100%);
+  justify-content: center;
+  height: 25px;
+  min-width: 54px;
+  /* padding: 0 5px 0 10px; */
+  background: #004098;
   color: #fff;
   font-size: 14px;
-  font-weight: 700;
+  font-weight: bold;
+  border-radius: 100px;
 }
 
 .notice-badge::after {
@@ -777,9 +862,6 @@ onMounted(() => {
   position: absolute;
   top: 0;
   right: -15px;
-  border-top: 16px solid transparent;
-  border-bottom: 16px solid transparent;
-  border-left: 15px solid #0f53b4;
 }
 
 .side-card__more {
@@ -790,17 +872,19 @@ onMounted(() => {
   background: transparent;
   color: #0f53b4;
   cursor: pointer;
+  font-size: 12px;
 }
 
 .notice-item {
   background: #fff;
-  padding: 12px 14px;
-  box-shadow: inset 0 0 0 1px rgba(230, 237, 246, 0.95);
+  padding: 8px 14px;
+  box-shadow: 0 8px 22px rgba(63, 107, 169, 0.06);
+  border-radius: 10px;
 }
 
 .notice-item__title,
 .notice-item__desc {
-  color: #4f5f76;
+  color: #507698;
   font-size: 13px;
   line-height: 1.5;
 }
@@ -814,8 +898,8 @@ onMounted(() => {
 
 .todo-item {
   background: rgba(255, 255, 255, 0.88);
-  padding: 12px 14px;
-  box-shadow: inset 0 0 0 1px rgba(228, 236, 246, 0.95);
+  padding: 8px 14px;
+  box-shadow: 0 8px 22px rgba(63, 107, 169, 0.05);
 }
 
 .todo-item__tag {
@@ -833,25 +917,23 @@ onMounted(() => {
   align-items: center;
   gap: 12px;
   background: rgba(255, 255, 255, 0.88);
-  padding: 10px 12px;
-  box-shadow: inset 0 0 0 1px rgba(228, 236, 246, 0.95);
+  padding: 5px 12px;
+  box-shadow: 0 8px 22px rgba(63, 107, 169, 0.05);
+  border: none;
 }
 
 .placeholder-panel {
   display: flex;
   height: 100%;
-  align-items: center;
-  justify-content: center;
-  color: #aec5e5;
+  /* align-items: center; */
+  padding: 16px;
+  justify-content: start;
+  color: #fff;
   font-size: 16px;
   font-weight: 600;
   letter-spacing: 0.08em;
 }
 
-.placeholder-panel__title {
-  opacity: 0.55;
-}
-
 @media (max-width: 1279px) {
   .hero-banner__inner {
     grid-template-columns: 1fr;