yanghao há 4 dias atrás
pai
commit
89aaa3c7a9

+ 22 - 0
src/api/user.ts

@@ -69,3 +69,25 @@ export const getMCSsoToken = async () => {
     url: "/admin-api/rq/iot-fine-report/createSsoToken",
   });
 };
+
+// 分组接口
+export const getGroups = async () => {
+  return await request.get({
+    url: "/admin-api/portal/flow-group/page",
+  });
+};
+
+// 根据id获取分组详情
+export const getGroupById = async (id: string) => {
+  return await request.get({
+    url: "/admin-api/portal/flow/get?groupId=" + id,
+  });
+};
+
+// 获取所有的flow
+export const getFlows = async (params) => {
+  return await request.get({
+    url: "/admin-api/portal/flow-group/all",
+    params,
+  });
+};

BIN
src/assets/images/banner1.jpg


+ 18 - 18
src/components/home/CardItem.vue

@@ -5,10 +5,7 @@
       :style="{ backgroundImage: `url(${bg})` }"
     >
       <div class="absolute inset-0 bg-white/0"></div>
-      <div
-        class="relative h-full flex items-center gap-3 px-4 cursor-pointer"
-        @click="goDetail"
-      >
+      <div class="relative h-full flex items-center gap-3 px-4 cursor-pointer">
         <div class="min-w-0 flex-1">
           <div class="text-[20px] font-bold text-[#0050b3]">{{ title }}</div>
           <div class="text-[#606266] text-sm mt-1 leading-snug">{{ desc }}</div>
@@ -178,16 +175,6 @@ const getIconByLabel = (label: string) => {
   return iconMap[label] || oaimage; // 默认返回oa图标,以防某些标签没有对应图标
 };
 
-const goDetail = () => {
-  if (props.id === "management") {
-    router.push({ path: "/management" });
-  } else if (props.id === "command") {
-    router.push({ path: "/command" });
-  } else if (props.id === "chatbi") {
-    router.push({ path: "/chatbi" });
-  }
-};
-
 // 处理查看按钮点击事件
 const handleView = async (item: Item) => {
   if (item.label === "OA办公") {
@@ -197,10 +184,19 @@ const handleView = async (item: Item) => {
       });
 
       if (res) {
-        window.open(
-          "https://yfoa.keruioil.com/wui/index.html?ssoToken=" + res + "#/main",
-          "_blank",
-        );
+        const newTab = window.open("", "_blank");
+        // window.open(
+        //   "https://yfoa.keruioil.com/wui/index.html?ssoToken=" + res + "#/main",
+        //   "_blank",
+        // );
+
+        newTab!.location.href =
+          "https://yfoa.keruioil.com/wui/index.html?ssoToken=" + res + "#/main";
+
+        setTimeout(function () {
+          newTab!.location.href =
+            "https://yfoa.keruioil.com/spa/workflow/static4form/index.html?_rdm=1775701877695#/main/workflow/req?iscreate=1&workflowid=681";
+        }, 0);
       }
     } else {
       router.push({ path: "/login" });
@@ -339,6 +335,10 @@ const handleView = async (item: Item) => {
       router.push({ path: "/login" });
     }
   }
+
+  if (item.label === "人力资源(EHR)") {
+    router.push({ path: "/ehr" });
+  }
 };
 </script>
 

+ 8 - 8
src/components/home/header.vue

@@ -3,7 +3,7 @@
     class="fixed w-full top-0 z-100 bg-white border-b border-[#f0f2f5] shadow-sm"
   >
     <div
-      class="w-full mx-auto flex items-center justify-between px-10 pr-0 h-18"
+      class="w-full mx-auto flex items-center justify-between px-10 pr-0 h-20"
     >
       <div class="flex items-center gap-2 cursor-pointer" @click="goHome">
         <img :src="logo" alt="logo" class="w-20 h-9" />
@@ -13,13 +13,13 @@
       </div>
 
       <nav class="hidden lg:flex flex-1 mx-4 ml-10 text-sm">
-        <ul class="flex items-center gap-6 text-[#303133]">
-          <li><a class="hover:text-[#409EFF] cursor-pointer">产品</a></li>
-          <li><a class="hover:text-[#409EFF] cursor-pointer">解决方案</a></li>
-          <li><a class="hover:text-[#409EFF] cursor-pointer">典型案例</a></li>
-          <li><a class="hover:text-[#409EFF] cursor-pointer">平台服务</a></li>
-          <li><a class="hover:text-[#409EFF] cursor-pointer">应用市场</a></li>
-          <li><a class="hover:text-[#409EFF] cursor-pointer">开源社区</a></li>
+        <ul class="flex items-center gap-6 text-[#303133] text-lg">
+          <li><a class="hover:text-[#02409b] cursor-pointer">产品</a></li>
+          <li><a class="hover:text-[#02409b] cursor-pointer">解决方案</a></li>
+          <li><a class="hover:text-[#02409b] cursor-pointer">典型案例</a></li>
+          <li><a class="hover:text-[#02409b] cursor-pointer">平台服务</a></li>
+          <li><a class="hover:text-[#02409b] cursor-pointer">应用市场</a></li>
+          <li><a class="hover:text-[#02409b] cursor-pointer">开源社区</a></li>
         </ul>
       </nav>
 

+ 7 - 24
src/router/index.ts

@@ -5,9 +5,7 @@ import {
 } from "vue-router";
 
 import Home from "@/views/index.vue";
-import Management from "@/views/management.vue";
-import Command from "@/views/command.vue";
-import ChatBI from "@/views/chatbi.vue";
+import EHR from "@/views/ehr/index.vue";
 import Login from "@/views/login.vue";
 
 import { getAccessToken } from "@utils/auth";
@@ -31,28 +29,13 @@ const routes: RouteRecordRaw[] = [
       title: "DeepOil 智慧经营平台 | 登录",
     },
   },
+
   {
-    path: "/management",
-    name: "Management",
-    component: Management,
-    meta: {
-      title: "DeepOil 智慧经营平台 | 数字运营平台",
-    },
-  },
-  {
-    path: "/command",
-    name: "Command",
-    component: Command,
-    meta: {
-      title: "DeepOil 智慧经营平台 | 智慧指挥平台",
-    },
-  },
-  {
-    path: "/chatbi",
-    name: "ChatBI",
-    component: ChatBI,
+    path: "/ehr",
+    name: "EHR",
+    component: EHR,
     meta: {
-      title: "DeepOil 智慧经营平台 | Chat BI平台",
+      title: "DeepOil 智慧经营平台 | EHR",
     },
   },
 ];
@@ -109,7 +92,7 @@ const parseURL = (
   return { basePath, paramsObject };
 };
 
-const whiteList = ["/", "/login", "/social-login", "/auth-redirect"];
+const whiteList = ["/", "/login", "/social-login", "/auth-redirect", "/ehr"];
 router.beforeEach(async (to, from, next) => {
   // 设置页面标题
   const title = to.meta.title as string;

+ 0 - 88
src/views/chatbi.vue

@@ -1,88 +0,0 @@
-<template>
-  <div class="bg-white min-h-screen">
-    <Header />
-
-    <section class="max-w-[1200px] mx-auto mt-20 mb-8 px-4">
-      <div class="text-center mb-8">
-        <h2 class="text-[28px] font-bold text-[#0644a1]">Chat BI平台</h2>
-        <p class="mt-2 text-[#606266]">
-          工厂上云,高效协同,生产效率和产品质量提升
-        </p>
-      </div>
-
-      <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
-        <div
-          v-for="item in items"
-          :key="item.id"
-          class="group relative overflow-hidden rounded-lg bg-white shadow-md hover:shadow-xl transition-all duration-300 cursor-pointer"
-        >
-          <div class="relative h-48 overflow-hidden">
-            <div
-              class="absolute inset-0 bg-cover bg-center transition-transform duration-300 group-hover:scale-110"
-              :style="{ backgroundImage: `url(${item.bg})` }"
-            >
-              <div
-                class="absolute inset-0 bg-gradient-to-t from-[#0050b3]/40 to-[#0050b3]/10 group-hover:from-[#0050b3]/50 group-hover:to-[#0050b3]/20 transition-colors duration-300"
-              ></div>
-            </div>
-          </div>
-          <div class="p-4">
-            <h3 class="text-lg font-semibold text-[#1f2d3d] mb-2">
-              {{ item.title }}
-            </h3>
-            <p class="text-sm text-[#606266] leading-relaxed">
-              {{ item.desc }}
-            </p>
-          </div>
-        </div>
-      </div>
-    </section>
-
-    <Footer />
-  </div>
-</template>
-
-<script setup lang="ts">
-import Header from "@components/home/header.vue";
-import img2 from "@/assets/images/2.jpg";
-import Footer from "@components/home/Footer.vue";
-import agent from "@/assets/images/agent.png";
-import model from "@/assets/images/model.jpeg";
-import data from "@/assets/images/data.png";
-
-type GridItem = {
-  id: string;
-  title: string;
-  desc: string;
-  bg: string;
-};
-
-const items: GridItem[] = [
-  {
-    id: "1",
-    title: "全局数据治理 (数据中台)",
-    desc: "企业数据驱动的核心基础设施",
-    bg: data,
-  },
-  {
-    id: "2",
-    title: "智能决策",
-    desc: "利用数据驱动的方法来优化从油藏到输油管的整个生产价值链",
-    bg: img2,
-  },
-  {
-    id: "3",
-    title: "行业AI大模型",
-    desc: "针对油气勘探开发领域训练的垂直大模型,它将成为推动整个行业迈向智能化、自动化的核心引擎",
-    bg: model,
-  },
-  {
-    id: "4",
-    title: "AI智能体 (智能交互)",
-    desc: "在行业AI大模型基础上构建的、具备感知、决策、执行和交互能力的智能实体",
-    bg: agent,
-  },
-];
-</script>
-
-<style scoped></style>

+ 0 - 110
src/views/command.vue

@@ -1,110 +0,0 @@
-<template>
-  <div class="bg-white min-h-screen">
-    <Header />
-
-    <section class="max-w-[1200px] mx-auto mt-20 mb-8 px-4">
-      <div class="text-center mb-8">
-        <h2 class="text-[28px] font-bold text-[#0644a1]">智慧指挥平台</h2>
-        <p class="mt-2 text-[#606266]">
-          深入工业场景,为中小企业数字化升级赋能
-        </p>
-      </div>
-
-      <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
-        <div
-          v-for="item in items"
-          :key="item.id"
-          class="group relative overflow-hidden rounded-lg bg-white shadow-md hover:shadow-xl transition-all duration-300 cursor-pointer"
-        >
-          <div class="relative h-48 overflow-hidden">
-            <div
-              class="absolute inset-0 bg-cover bg-center transition-transform duration-300 group-hover:scale-110"
-              :style="{ backgroundImage: `url(${item.bg})` }"
-            >
-              <div
-                class="absolute inset-0 bg-gradient-to-t from-[#0050b3]/40 to-[#0050b3]/10 group-hover:from-[#0050b3]/50 group-hover:to-[#0050b3]/20 transition-colors duration-300"
-              ></div>
-            </div>
-          </div>
-          <div class="p-4">
-            <h3 class="text-lg font-semibold text-[#1f2d3d] mb-2">
-              {{ item.title }}
-            </h3>
-            <p class="text-sm text-[#606266] leading-relaxed">
-              {{ item.desc }}
-            </p>
-          </div>
-        </div>
-      </div>
-    </section>
-
-    <Footer />
-  </div>
-</template>
-
-<script setup lang="ts">
-import Header from "@components/home/header.vue";
-import zuanjing from "@/assets/images/zuanjing.png";
-import yalie from "@/assets/images/yalie.png";
-import pm from "@/assets/images/pm.png";
-import pms from "@/assets/images/pms.webp";
-import qhse from "@/assets/images/qhse.jpg";
-import lianyou from "@/assets/images/lianyou.png";
-import zhuqi from "@/assets/images/zhuqi.png";
-import Footer from "@components/home/Footer.vue";
-
-type GridItem = {
-  id: string;
-  title: string;
-  desc: string;
-  bg: string;
-};
-
-const items: GridItem[] = [
-  {
-    id: "6",
-    title: "设备管理系统 (PMS)",
-    desc: "将信息化了设备技术信息与现代化管理相结合,是实现研究级管理信息化的先导",
-    bg: pms,
-  },
-  {
-    id: "1",
-    title: "智能钻井系统",
-    desc: "基于传感器测量与计算机控制实现的无人化钻井系统",
-    bg: zuanjing,
-  },
-  {
-    id: "2",
-    title: "智能压裂系统",
-    desc: "通过智能化、高效化和绿色化升级,实现了压裂作业的重大突破",
-    bg: yalie,
-  },
-  {
-    id: "3",
-    title: "智能注气系统",
-    desc: "集成了物联网、大数据、人工智能和自动控制技术的综合性解决方案",
-    bg: zhuqi,
-  },
-  {
-    id: "4",
-    title: "智能连油系统",
-    desc: "集成了先进传感器、实时数据传输、井下控制工具和智能决策软件的综合性技术平台",
-    bg: lianyou,
-  },
-  {
-    id: "5",
-    title: "QHSE (安全监控、应急指挥)",
-    desc: "现代智能系统则构建了一个 “感、传、知、用” 的智能体",
-    bg: qhse,
-  },
-
-  {
-    id: "7",
-    title: "项目管理 (PM)",
-    desc: "供应链全流程管理,优化库存和物流效率",
-    bg: pm,
-  },
-];
-</script>
-
-<style scoped></style>

+ 521 - 0
src/views/ehr/index.vue

@@ -0,0 +1,521 @@
+<template>
+  <div class="ehr-page">
+    <Header />
+    <section class="hero">
+      <div class="hero-inner">
+        <h1 class="hero-title">下午好,晓华</h1>
+        <p class="hero-desc">
+          今天是 {{ new Date().toLocaleDateString() }}。您有 5 条流程待处理。
+        </p>
+      </div>
+      <div class="hero-accent" aria-hidden="true"></div>
+    </section>
+
+    <!-- 任务统计 -->
+    <section class="total">
+      <div class="total-card" v-for="(item, index) in stats" :key="index">
+        <div class="card-icon" :style="{ backgroundColor: item.bgcolor }">
+          <Icon :icon="item.icon" />
+        </div>
+        <div class="card-content">
+          <p class="card-title">{{ item.title }}</p>
+          <p class="card-number">{{ item.number }}</p>
+        </div>
+        <div v-if="item.extra" class="card-extra">
+          {{ item.extra }}
+        </div>
+      </div>
+    </section>
+
+    <div class="content">
+      <div class="tabs" role="tablist" aria-label="EHR模块">
+        <button
+          class="tab"
+          type="button"
+          role="tab"
+          :class="{ active: activeKey === 'all' }"
+          :aria-selected="activeKey === 'all'"
+          @click="setAll"
+        >
+          全部
+        </button>
+        <button
+          v-for="tab in tabs"
+          :key="tab.groupName"
+          class="tab"
+          :class="{ active: tab.groupName === activeKey }"
+          type="button"
+          role="tab"
+          :aria-selected="tab.groupName === activeKey"
+          @click="getById(tab)"
+        >
+          <span class="tab-title">{{ tab.groupName }}</span>
+          <span class="tab-sub">{{ tab.remark }}</span>
+        </button>
+      </div>
+
+      <div class="panel" role="tabpanel">
+        <div class="panel-head">
+          <div>
+            <p class="panel-title">{{ activeTab.groupName }}</p>
+            <p class="panel-subtitle">{{ activeTab.remark }}</p>
+          </div>
+          <div class="panel-meta">
+            <span class="panel-count"
+              >{{ activeTab.flowRespVOS.length }} 项</span
+            >
+            <span class="panel-note">流程与表单</span>
+          </div>
+        </div>
+
+        <div class="items-grid">
+          <div
+            v-for="item in activeTab.flowRespVOS"
+            :key="item.id"
+            class="item-card"
+            @click="go(item)"
+          >
+            <div class="item-top">
+              <div class="item-icon">
+                <Icon :icon="item.icon || 'mdi:file-document-outline'" />
+              </div>
+            </div>
+            <div class="item-body">
+              <p class="item-name">{{ item.flowName }}</p>
+              <p class="item-desc">{{ item.remark || "暂无描述" }}</p>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 修复宽度:自适应包裹按钮 -->
+
+    <Footer />
+  </div>
+</template>
+
+<script setup>
+import Header from "@components/home/header.vue";
+import Footer from "@components/home/Footer.vue";
+import { computed, ref, onMounted } from "vue";
+import { Icon } from "@iconify/vue";
+import { getFlows } from "@/api/user";
+
+const tabs = ref([]);
+
+const activeKey = ref("all");
+
+const allTab = computed(() => {
+  const flowRespVOS = tabs.value.flatMap((tab) => tab.flowRespVOS || []);
+  return {
+    groupName: "全部",
+    remark: "全部流程",
+    flowRespVOS,
+  };
+});
+
+const activeTab = computed(() => {
+  if (activeKey.value === "all") {
+    return allTab.value;
+  }
+
+  return (
+    tabs.value.find((tab) => tab.groupName === activeKey.value) || allTab.value
+  );
+});
+
+const stats = [
+  {
+    icon: "mdi:clock-outline",
+    title: "我的待办",
+    number: "05",
+    extra: "+2 今日",
+    bgcolor: "#fff7ed",
+  },
+  {
+    icon: "mdi:check-circle-outline",
+    title: "已办事项",
+    number: "128",
+    bgcolor: "#eff6ff",
+  },
+  {
+    icon: "mdi:arrow-right-bold-box-outline",
+    title: "发起流程",
+    number: "42",
+    extra: "85% 准时",
+    bgcolor: "#eff6ff",
+  },
+  {
+    icon: "mdi:file-document-outline",
+    title: "草箱箱",
+    number: "03",
+    bgcolor: "#fef3c7",
+  },
+];
+
+const getAll = async () => {
+  const res = await getFlows({
+    pageNo: 1,
+    pageSize: 99,
+  });
+
+  tabs.value = res;
+};
+
+const setAll = () => {
+  activeKey.value = "all";
+};
+
+const getById = (tab) => {
+  activeKey.value = tab.groupName;
+};
+
+const go = (item) => {
+  console.log("跳转", item);
+};
+
+onMounted(async () => {
+  getAll();
+});
+</script>
+
+<style scoped>
+:global(body) {
+  background-color: #f4f4f2;
+}
+
+/* .ehr-page {
+  color: #1f2a37;
+  background: linear-gradient(180deg, #f4f4f2 0%, #f7f6f3 50%, #f2f1ef 100%);
+  min-height: 100vh;
+} */
+
+.hero {
+  position: relative;
+  padding: 72px 6vw 48px;
+  overflow: hidden;
+  margin-top: 20px;
+}
+
+.hero-inner {
+  max-width: 920px;
+}
+
+.hero-title {
+  font-size: clamp(18px, 2vw, 22px);
+  line-height: 1.2;
+  margin: 16px 0 12px;
+  color: #111827;
+  font-weight: bold;
+}
+
+.hero-desc {
+  font-size: 16px;
+  color: #4b5563;
+  max-width: 720px;
+  line-height: 1.8;
+}
+
+.hero-accent {
+  position: absolute;
+  top: -120px;
+  right: -140px;
+  width: 360px;
+  height: 360px;
+  background: radial-gradient(
+    circle at 30% 30%,
+    rgba(2, 64, 155, 0.25),
+    transparent 65%
+  );
+  border-radius: 50%;
+  opacity: 0.9;
+  pointer-events: none;
+}
+
+.content {
+  padding: 0 6vw 80px;
+  /* height: 80vh; */
+}
+
+.tabs {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
+  gap: 16px;
+  margin-bottom: 28px;
+}
+
+.tab {
+  padding: 18px 20px;
+  border-radius: 14px;
+  /* border: 1px solid #e5e7eb; */
+  background: #ffffff;
+  text-align: left;
+  transition: all 0.25s ease;
+  cursor: pointer;
+  box-shadow: 0 12px 24px rgba(15, 23, 42, 0.05);
+}
+
+.tab:hover {
+  transform: translateY(-2px);
+  border-color: #02409b;
+}
+
+.tab.active {
+  background: linear-gradient(135deg, #02409b 0%, #0b2f6d 60%, #0b1f45 100%);
+  border-color: transparent;
+  color: #f9fafb;
+  box-shadow: 0 18px 36px rgba(2, 64, 155, 0.25);
+}
+
+.tab-title {
+  display: block;
+  font-weight: 600;
+  font-size: 16px;
+  margin-bottom: 6px;
+}
+
+.tab-sub {
+  display: block;
+  font-size: 12px;
+  color: inherit;
+  opacity: 0.75;
+}
+
+.panel {
+  background: #ffffff;
+  border-radius: 24px;
+  padding: 28px 28px 32px;
+
+  box-shadow: 0 26px 48px rgba(15, 23, 42, 0.08);
+}
+
+.panel-head {
+  display: flex;
+  align-items: flex-start;
+  justify-content: space-between;
+  gap: 24px;
+
+  padding-bottom: 20px;
+  margin-bottom: 24px;
+}
+
+.panel-title {
+  font-size: 22px;
+  color: #111827;
+  margin-bottom: 6px;
+}
+
+.panel-subtitle {
+  color: #6b7280;
+  font-size: 14px;
+}
+
+.panel-meta {
+  text-align: right;
+  color: #6b7280;
+  font-size: 12px;
+}
+
+.panel-count {
+  display: block;
+  font-size: 20px;
+  font-weight: 600;
+  color: #111827;
+}
+
+.items-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+  gap: 16px;
+}
+
+.item-card {
+  display: flex;
+  flex-direction: column;
+  gap: 18px;
+  padding: 22px 22px 18px;
+  border-radius: 22px;
+  background: #ffffff;
+  border: 1px solid #edf0f5;
+  box-shadow: 0 14px 30px rgba(15, 23, 42, 0.06);
+  transition:
+    transform 0.2s ease,
+    border-color 0.2s ease,
+    box-shadow 0.2s ease;
+  cursor: pointer;
+}
+
+.item-card:hover {
+  transform: translateY(-3px);
+  border-color: rgba(2, 64, 155, 0.25);
+  box-shadow: 0 18px 36px rgba(15, 23, 42, 0.08);
+  color: #02409b !important;
+}
+
+.item-top {
+  display: flex;
+  align-items: flex-start;
+  justify-content: space-between;
+}
+
+.item-body {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.item-icon {
+  width: 52px;
+  height: 52px;
+  border-radius: 16px;
+  background: #f5f7fb;
+  display: grid;
+  place-items: center;
+
+  font-size: 20px;
+}
+
+.item-icon :deep(svg) {
+  width: 24px;
+  height: 24px;
+}
+
+.item-role {
+  font-size: 12px;
+  letter-spacing: 0.2em;
+  color: #c7ced9;
+  font-weight: 600;
+}
+
+.item-name {
+  font-size: 16px;
+
+  line-height: 1.45;
+  /* font-weight: 600; */
+}
+
+.item-desc {
+  font-size: 13px;
+  color: #6b7280;
+  line-height: 1.6;
+}
+
+.item-footer {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  color: #94a3b8;
+  font-size: 12px;
+}
+
+.item-usage {
+  display: inline-flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.item-flame {
+  width: 18px;
+  height: 18px;
+  border-radius: 50%;
+  display: grid;
+  place-items: center;
+  background: rgba(255, 108, 0, 0.12);
+  color: #ff6c00;
+  font-size: 12px;
+}
+
+.item-arrow {
+  font-size: 22px;
+  color: #cbd5e1;
+}
+
+@media (max-width: 720px) {
+  .hero {
+    padding: 56px 7vw 36px;
+  }
+
+  .panel-head {
+    flex-direction: column;
+    align-items: flex-start;
+  }
+
+  .panel-meta {
+    text-align: left;
+  }
+}
+
+.total {
+  display: flex;
+  gap: 16px;
+  padding: 0 6vw 80px;
+  /* margin-bottom: 24px; */
+}
+
+.total-card {
+  flex: 1;
+  min-width: 0;
+  background: #ffffff;
+  border-radius: 16px;
+  padding: 20px;
+  box-shadow:
+    rgba(0, 0, 0, 0.05) 0px 1px 3px 0px,
+    rgba(0, 0, 0, 0) 0px 0px 0px 0px,
+    rgba(0, 0, 0, 0.05) 0px 1px 2px 0px,
+    rgba(0, 0, 0, 0.05) 0px 2px 4px -1px,
+    rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
+  transition:
+    transform 0.2s ease,
+    box-shadow 0.2s ease;
+  cursor: pointer;
+  /* border: 1px solid #e5e7eb; */
+  /* border-top: solid 5px #02409b; */
+}
+
+.total-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
+}
+
+.card-icon {
+  width: 40px;
+  height: 40px;
+  border-radius: 12px;
+  background: #f9f9f9;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 12px;
+}
+
+.card-icon svg {
+  width: 20px;
+  height: 20px;
+  color: var(--primary-color);
+}
+
+.card-content {
+  flex: 1;
+  text-align: left;
+}
+
+.card-title {
+  font-size: 14px;
+  color: #6b7280;
+  margin-bottom: 4px;
+}
+
+.card-number {
+  font-size: 28px;
+  font-weight: 600;
+  color: #111827;
+}
+
+.card-extra {
+  font-size: 12px;
+  color: #10b981;
+  margin-top: 8px;
+  text-align: right;
+}
+</style>

+ 70 - 15
src/views/index.vue

@@ -3,28 +3,50 @@
     <Header />
 
     <section
-      class="relative w-full h-[30vh] md:h-[25vh] overflow-hidden mt-15 md:pb-30 pb-50 pt-9"
+      class="relative w-full overflow-hidden mt-15 md:pb-30 pb-50 pt-9 h-[400px]"
     >
-      <video
-        class="absolute inset-0 w-full h-full object-cover"
-        :src="bgVideo"
-        autoplay
-        muted
-        loop
-        playsinline
-      ></video>
-      <div class="absolute inset-0 bg-black/40"></div>
+      <!-- 轮播背景容器 -->
+
       <div
+        class="absolute inset-0 flex transition-transform duration-700 ease-in-out"
+        :style="{ transform: `translateX(-${currentBgIndex * 100}%)` }"
+      >
+        <div
+          v-for="(img, index) in bgImages"
+          :key="index"
+          class="min-w-full h-full bg-cover bg-center"
+          :style="{ backgroundImage: `url(${img})` }"
+        ></div>
+      </div>
+
+      <!-- 指示器 -->
+      <div
+        class="absolute bottom-4 left-1/2 transform -translate-x-1/2 z-20 flex gap-2"
+      >
+        <span
+          v-for="(img, index) in bgImages"
+          :key="index"
+          class="block w-2 h-2 rounded-full cursor-pointer transition-all duration-300"
+          :class="
+            currentBgIndex === index
+              ? 'bg-[#0644a1] w-6'
+              : 'bg-white/50 hover:bg-white/80'
+          "
+          @click="currentBgIndex = index"
+        ></span>
+      </div>
+
+      <!-- <div
         class="relative z-10 w-full mx-auto h-full px-20 flex items-center mt-5 pt-10"
       >
-        <div class="text-white max-w-4xl">
+        <div class="max-w-4xl">
           <h1
             class="text-2xl md:text-4xl pt-2 font-bold leading-tight slide-up-fade-in"
           >
             山东科瑞石油技术门户网站 · DeepOil 智慧经营平台
           </h1>
           <p
-            class="mt-3 md:mt-4 text-sm md:text-base text-white/90 leading-relaxed slide-up-fade-in"
+            class="mt-3 md:text-4 text-sm md:text-base text-white/90 leading-relaxed slide-up-fade-in"
             style="animation-delay: 0.2s"
           >
             连接经营管理、生产指挥与数据智能,打造石油能源行业的一体化数字化平台,
@@ -46,7 +68,7 @@
             </a>
           </div>
         </div>
-      </div>
+      </div> -->
     </section>
 
     <section
@@ -74,7 +96,7 @@
 </template>
 
 <script setup lang="ts">
-import { onMounted, ref } from "vue";
+import { onMounted, ref, onUnmounted } from "vue";
 import * as authUtil from "@/utils/auth";
 import * as dd from "dingtalk-jsapi";
 import { getUnreadNotifyMessageCount } from "@/api/user";
@@ -84,7 +106,10 @@ import Footer from "@components/home/Footer.vue";
 import img1 from "@/assets/images/1.jpg";
 import img2 from "@/assets/images/2.jpg";
 import img3 from "@/assets/images/3.jpg";
-import bgVideo from "@/assets/bg.mp4";
+import caiwu from "@/assets/images/caiwu.png";
+import banner1 from "@/assets/images/banner1.jpg";
+import banner2 from "@/assets/images/model.jpeg";
+
 import bg2 from "@/assets/images/e4.png";
 import g1 from "@/assets/images/g1.png";
 import { useRouter } from "vue-router";
@@ -93,6 +118,12 @@ import { useUserStore } from "@/stores/useUserStore";
 const router = useRouter();
 
 const userStore = useUserStore();
+const bgImages = [banner1, caiwu, banner2];
+// 2. 定义当前显示的图片索引
+const currentBgIndex = ref(0);
+
+// 3. 轮播定时器引用
+let bgInterval: number | null = null;
 
 type Card = {
   name: string;
@@ -229,6 +260,11 @@ const getUnreadCount = async () => {
 onMounted(() => {
   dingTalkAutoLogin();
 
+  // 启动背景轮播 (每3秒切换一次)
+  bgInterval = window.setInterval(() => {
+    currentBgIndex.value = (currentBgIndex.value + 1) % bgImages.length;
+  }, 3000);
+
   // 首次加载小红点
   // getUnreadCount();
   // 轮询刷新小红点
@@ -244,6 +280,12 @@ onMounted(() => {
     1000 * 60 * 1,
   );
 });
+
+onUnmounted(() => {
+  if (bgInterval) {
+    clearInterval(bgInterval);
+  }
+});
 </script>
 
 <style scoped>
@@ -276,6 +318,19 @@ onMounted(() => {
   animation: slideUpFadeIn 0.8s forwards ease-out;
 }
 
+@keyframes slideUpFadeIn {
+  to {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}
+
+.slide-up-fade-in {
+  opacity: 0;
+  transform: translateY(20px);
+  animation: slideUpFadeIn 0.8s forwards ease-out;
+}
+
 @keyframes slideUpFadeIn {
   to {
     opacity: 1;

+ 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">

+ 0 - 122
src/views/management.vue

@@ -1,122 +0,0 @@
-<template>
-  <div class="bg-white min-h-screen">
-    <Header />
-
-    <section class="max-w-[1200px] mx-auto mt-20 mb-8 px-4">
-      <div class="text-center mb-8">
-        <h2 class="text-[28px] font-bold text-[#0644a1]">数字运营平台</h2>
-        <p class="mt-2 text-[#606266]">
-          集成财务、研发、客户、人力等关键业务数据,为管理者提供全局态势感知和战略决策支持。
-        </p>
-      </div>
-
-      <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
-        <div
-          v-for="item in items"
-          :key="item.id"
-          class="group relative overflow-hidden rounded-lg bg-white shadow-md hover:shadow-xl transition-all duration-300 cursor-pointer"
-        >
-          <div class="relative h-48 overflow-hidden">
-            <div
-              class="absolute inset-0 bg-cover bg-center transition-transform duration-300 group-hover:scale-110"
-              :style="{ backgroundImage: `url(${item.bg})` }"
-            >
-              <div
-                class="absolute inset-0 bg-gradient-to-t from-[#0050b3]/40 to-[#0050b3]/10 group-hover:from-[#0050b3]/50 group-hover:to-[#0050b3]/20 transition-colors duration-300"
-              ></div>
-            </div>
-          </div>
-          <div class="p-4">
-            <h3 class="text-lg font-semibold text-[#1f2d3d] mb-2">
-              {{ item.title }}
-            </h3>
-            <p class="text-sm text-[#606266] leading-relaxed">
-              {{ item.desc }}
-            </p>
-          </div>
-        </div>
-      </div>
-    </section>
-    <Footer />
-  </div>
-</template>
-
-<script setup lang="ts">
-import Header from "@components/home/header.vue";
-import Footer from "@components/home/Footer.vue";
-import img2 from "@/assets/images/2.jpg";
-import ehr from "@/assets/images/ehr.png";
-import crm from "@/assets/images/crm.png";
-import scm from "@/assets/images/srm.png";
-import money from "@/assets/images/money.png";
-import caiwu from "@/assets/images/caiwu.png";
-import technology from "@/assets/images/jishu.png";
-import guifan from "@/assets/images/guifan.png";
-import drive from "@/assets/images/drive.png";
-
-type GridItem = {
-  id: string;
-  title: string;
-  desc: string;
-  bg: string;
-};
-
-const items: GridItem[] = [
-  {
-    id: "1",
-    title: "经营驾驶舱",
-    desc: "实时监控企业运营数据,提供全面的经营分析和决策支持",
-    bg: drive,
-  },
-  {
-    id: "2",
-    title: "战略解码与执行",
-    desc: "将战略目标分解为可执行的计划,确保战略落地实施",
-    bg: img2,
-  },
-  {
-    id: "3",
-    title: "财务管理",
-    desc: "收入、成本、应收账款等财务数据的全面管理与分析",
-    bg: caiwu,
-  },
-  {
-    id: "4",
-    title: "技术研发管理",
-    desc: "研发项目管理、进度跟踪、资源配置和成果管理",
-    bg: technology,
-  },
-  {
-    id: "5",
-    title: "客户管理(CRM)",
-    desc: "客户关系管理,提升客户满意度和业务转化率",
-    bg: crm,
-  },
-  {
-    id: "6",
-    title: "人力资源(EHR)",
-    desc: "员工信息管理、招聘、培训、绩效和薪酬管理",
-    bg: ehr,
-  },
-  {
-    id: "7",
-    title: "供应链管理(SCM)",
-    desc: "供应链全流程管理,优化库存和物流效率",
-    bg: scm,
-  },
-  {
-    id: "8",
-    title: "组织资产管理",
-    desc: "企业资产全生命周期管理,提升资产利用率",
-    bg: money,
-  },
-  {
-    id: "9",
-    title: "风控、合规管理",
-    desc: "风险识别、评估和控制,确保企业合规经营",
-    bg: guifan,
-  },
-];
-</script>
-
-<style scoped></style>

+ 1 - 1
vite.config.ts

@@ -62,7 +62,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
   return {
     server: {
       host: "0.0.0.0", // 监听所有网络接口
-      port: 5173, // 可选:指定端口
+      port: 5174, // 可选:指定端口
     },
     base: "./",
     plugins: [