bf95e4d3b3e96e9f6ac87a572bcbd223de50e637..88315e144ab2076ee1a75b24f80b165844fb3ff6
2025-05-08 tj
About Us update
88315e 对比 | 目录
2025-05-07 tj
home css update
fe1c5c 对比 | 目录
已修改6个文件
已添加10个文件
583 ■■■■■ 文件已修改
index.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/images/about-banner.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/about.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/certificate-1.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/certificate-2.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/certificate-3.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/certificate-4.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/icon-1.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/icon-2.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/icon-3.png 补丁 | 查看 | 原始文档 | blame | 历史
public/images/timeline-background.png 补丁 | 查看 | 原始文档 | blame | 历史
src/components/HeaderMenu.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/About.vue 344 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/Home.vue 171 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/Product.vue 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
index.html
@@ -6,7 +6,7 @@
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <!-- 引入 Bootstrap CSS -->
    <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
    <title>云游四方官网</title>
    <title>苏州云游四方信息科技有限公司</title>
  </head>
  <body>
    <div id="app"></div>
public/images/about-banner.png
public/images/about.png
public/images/certificate-1.png
public/images/certificate-2.png
public/images/certificate-3.png
public/images/certificate-4.png
public/images/icon-1.png
public/images/icon-2.png
public/images/icon-3.png
public/images/timeline-background.png
src/components/HeaderMenu.vue
@@ -41,7 +41,8 @@
const navItems = [
  { label: '首页', path: '/' },
  { label: '产品中心', path: '/product' },
  { label: '关于我们', path: '/about#third-other' }
  // { label: '关于我们', path: '/about#third-other' }
  { label: '关于我们', path: '/about2' }
];
// Handle navigation for the menu items
src/pages/About.vue
@@ -1 +1,343 @@
<template></template>
<template>
    <div class="w-100 about-container">
        <div class="w-100 about-banner d-flex align-items-center text-center text-md-start">
            <div class="top-wrap">
                <div class="fs-1 fw-bold">了解我们</div>
                <div class="fs-3">ABOUT US</div>
            </div>
        </div>
        <div class="container py-5">
            <div class="row align-items-center">
                <!-- 左侧:图片 -->
                <div class="col-md-6 mb-4 mb-md-0 text-center">
                    <img src="/images/about.png" alt="公司图片" class="img-fluid" style="max-height: 400px;" />
                </div>
                <!-- 右侧:卡片 -->
                <div class="col-md-6 d-flex justify-content-center">
                    <div class="card border-0 shadow mt-3 mb-3" style="max-width: 500px; width: 100%;">
                        <div class="card-body px-4 py-3" style="border-top: 2px solid orange;">
                            <h4 class="card-title mb-3 text-start">关于云游四方</h4>
                            <p class="card-text text-muted custom-font"
                                style="text-align: justify; font-size: 14px !important;">
                                苏州云游四方信息科技有限公司成立于2014年,坐落在美丽的苏州。公司拥有拥有三十余名专业技术同仁,20多家合作客户,涵盖汽车、医疗、电商、交通等多个领域,并且已经完成100多个项目,包括网站、APP、微信以及软硬件结合的智能硬件项目。我们主要从事软件开发工作,拥有强大的开发实力以及丰富的客户合作经验。公司现拥有成熟的MES、WMS、TMS、模具制造管理等系统。公司主营业务有:计算机信息科技领域内的技术开发、技术咨询、技术转让、技术服务;软件的设计、开发、销售;网络工程、自动化工程、通信工程;自动化控制系统集成等。
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="w-100 py-5" style="background-color: #f8f9fa;">
            <div class="row text-center">
                <div class="col-md-4 mb-4">
                    <img src="/images/icon-1.png" alt="愿景" class="mb-3" style="height: 80px;">
                    <h5 class="fw-bold">愿景</h5>
                    <p class="text-muted mb-0">助力于推动</p>
                    <p class="text-muted">中国工业制造智慧升级</p>
                </div>
                <div class="col-md-4 mb-4">
                    <img src="/images/icon-2.png" alt="价值观" class="mb-3" style="height: 80px;">
                    <h5 class="fw-bold">价值观</h5>
                    <p class="text-muted mb-0">正直人品 践行承诺</p>
                    <p class="text-muted">客户至上 质量第一</p>
                </div>
                <div class="col-md-4 mb-4">
                    <img src="/images/icon-3.png" alt="使命" class="mb-3" style="height: 80px;">
                    <h5 class="fw-bold">使命</h5>
                    <p class="text-muted mb-0">提供一流的产品为客户服务</p>
                    <p class="text-muted">创新卓越的技术引领行业</p>
                </div>
            </div>
        </div>
        <section class="text-center py-5">
            <div class="container">
                <h2 class="mb-5 fw-bold" style="color: #001441;">云游四方发展历程</h2>
                <div class="background-container ">
                    <div class="row justify-content-center align-items-center">
                        <div v-for="(year, index) in years" :key="index" class="col year-item"
                            :class="{ 'selected': selectedYear === year }" @click="selectYear(year)"
                            @mouseenter="pauseRotation(year)" @mouseleave="resumeRotation">
                            {{ year }}
                        </div>
                    </div>
                    <div class="d-flex justify-content-left text-start" >
                        <el-timeline class="p-5">
                            <el-timeline-item
                                class="timeline-item"
                                v-for="(activity, index) in curYearActivities" :key="index"
                                type="primary"  :timestamp="activity.timestamp"
                                placement="top">
                                {{ activity.content }}
                            </el-timeline-item>
                        </el-timeline>
                    </div>
                </div>
            </div>
        </section>
        <section class="cert-section text-center">
            <div class="container">
                <h2 class="mb-5 fw-bold" style="color: #001441;">企业资质及证书</h2>
                <div class="cert-card">
                    <div class="row justify-content-center g-4">
                        <div class="col-6 col-md-3" v-for="(cert, index) in certificates" :key="index">
                            <img :src="cert.src" :alt="cert.alt" class="img-fluid cert-image" style="height: 160px;" />
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </div>
</template>
<script setup lang="ts">
import { ref, onMounted,onBeforeUnmount } from 'vue';
// 定义证书类型
interface Certificate {
    src: string;
    alt: string;
}
const certificates: Certificate[] = [
    { src: '/images/certificate-1.png', alt: '江苏省民营科技企业' },
    { src: '/images/certificate-2.png', alt: '高新技术企业证书' },
    { src: '/images/certificate-3.png', alt: '质量管理体系认证证书' },
    { src: '/images/certificate-4.png', alt: '信息安全管理体系认证证书' }
];
// 定义年份和选中年份的类型
// const years: number[] = [2021, 2022, 2023, 2024, 2025]; // 给定的年份列表
const selectedYear = ref<number>(2023); // 默认选中的年份
const currentYearIndex = ref<number>(0); // 当前展示的年份索引
const curYearActivities = ref<ActivityType[]>();
// 选择年份时更新选中的年份
const selectYear = (year: number): void => {
    selectedYear.value = year;
    // 获取当前年份的activity
    getCurYearActivities(year);
};
let rotationTimer: ReturnType<typeof setInterval> | null = null;
// 启动年份轮播
const startYearRotation = (): void => {
    rotationTimer = setInterval(() => {
        currentYearIndex.value = (currentYearIndex.value + 1) % years.length;
        selectedYear.value = years[currentYearIndex.value];
        getCurYearActivities(selectedYear.value)
    }, 3000); // 每秒轮播一次年份
};
// 在组件挂载后启动年份轮播
onMounted(() => {
    startYearRotation();
});
// 在组件卸载时清除定时器
onBeforeUnmount(() => {
  if (rotationTimer) {
    clearInterval(rotationTimer); // 清除定时器
    rotationTimer = null;
  }
});
import { MoreFilled } from '@element-plus/icons-vue'
import type { TimelineItemProps } from 'element-plus'
interface ActivityType extends Partial<TimelineItemProps> {
    content: string,
    date: string,
}
const activities: ActivityType[] = [
    {
        content: 'cloudroam云游四方完成ISO27001认证',
        timestamp: '9 月',
        size: 'large',
        type: 'primary',
        icon: MoreFilled,
        date: '2022-09-01',
    },
    {
        content: 'cloudroam云游四方完成ISO9001认证',
        timestamp: '8 月',
        color: '#0bbd87',
        date: '2022-08-01',
    },
    {
        content: 'cloudroam云游四方累计申报软件著作权40项。',
        timestamp: '6 月',
        size: 'large',
        date: '2022-06-01',
    },
    {
        content: '公司拓展数字孪生和数据中台方向新业务,为企业数字化转型提供服务',
        timestamp: '11 月',
        type: 'primary',
        hollow: false,
        date: '2021-11-01',
    },
    {
        content: 'cloudroam云游四方成为省民营科技企业',
        timestamp: '6 月',
        date: '2021-06-01',
    },
    {
        content: 'cloudroam云游四方成为高新技术企业',
        timestamp: '12 月',
        date: '2020-12-01',
    },
    {
        content: 'cloudroam云游四方申报软件著作权21项',
        timestamp: '6 月',
        date: '2020-06-01',
    },
    {
        content: '公司全面拓展企业信息化系统开发,为企业信息化升级提供方案。开发系统包括企业培训认证系统、员工绩效系统、物流管理系统、仓库管理系统、会议管理系统、报修系统、实验室管理系统、电子SOP等。',
        timestamp: '8 月',
        date: '2016-08-01',
    },
    {
        content: 'cloudroam云游四方搬至苏州园区,更名苏州云游四方',
        timestamp: '5 月',
        date: '2016-05-01',
    },
    {
        content: 'cloudroam云游四方在苏州昆山正式成立',
        timestamp: '6 月',
        date: '2014-06-01',
    },
]
const years: number[] = Array.from(
    new Set(activities.map(item => new Date(item.date).getFullYear()))
).sort((a, b) => b - a);
const getCurYearActivities = (year: number) => {
    curYearActivities.value = activities
        .filter(activity => activity.date.startsWith(`${year}-`))
        .sort((a, b) => new Date(b.date).getMonth() - new Date(a.date).getMonth());
}
const pauseRotation = (year: number): void => {
    if (rotationTimer) {
        clearInterval(rotationTimer);
        rotationTimer = null;
    }
    selectedYear.value = year;
    currentYearIndex.value = years.indexOf(year);
    getCurYearActivities(year);
};
const resumeRotation = (): void => {
    startYearRotation();
};
</script>
<style lang="css" scoped>
body {
    font-family: "PingFang SC", "Century Gothic", "Microsoft YaHei", Avenir, Helvetica, Arial, sans-serif;
}
.about-container {
    overflow-x: hidden;
}
.top-wrap {
    width: 80%;
    max-width: 1440px;
    margin: 0 auto;
    color: white;
}
.custom-font {
    line-height: 25px;
}
</style>
<style scoped>
.cert-section {
    padding-top: 4rem;
    padding-bottom: 4rem;
    background-color: #f9f9f9;
}
.cert-card {
    background-color: #fff;
    padding: 2rem;
    border-radius: 1rem;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
}
.cert-image {
    max-height: 220px;
    object-fit: contain;
    /* transition: transform 0.3s ease; */
}
.cert-image:hover {
    transform: scale(1.05);
}
</style>
<style scoped>
/* 背景图片设置 */
.background-container {
    background-image: url('/public/images/timeline-background.png');
    /* 这里替换为你的背景图片路径 */
    background-size: cover;
    background-position: center;
    padding: 10px 0;
    /* 调整背景区域的内边距 */
    border-radius: 8px;
    /* 可选,给背景容器添加圆角 */
    min-height: 400px;
}
.year-item {
    font-size: 20px;
    transition: all 0.3s ease;
    cursor: pointer;
    padding: 10px 15px;
    text-align: center;
}
.year-item.selected {
    font-size: 30px;
    transform: scale(1.5);
    color: #007bff;
}
</style>
<style scoped>
.about-banner {
    background-image: url('/public/images/about-banner.png');
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center center;
    height: 450px;
}
@media (max-width: 768px) {
    .about-banner {
        height: auto;
        /* 小屏时高度自适应内容 */
        padding: 60px 0;
        /* 添加垂直内边距使内容不过于贴边 */
    }
}
</style>
src/pages/Home.vue
@@ -18,7 +18,7 @@
                                :style="{ backgroundColor: index === currentIndex ? 'yellow' : 'transparent' }"> -->
                            <div :class="[
                                'other-div',
                                'd-flex',
                                'flex-column',
                                'justify-content-between',
@@ -40,9 +40,12 @@
            <div class="our-products-title  mt-1 mt-md-3 w-100 p-2">
                <h1 class="fs-3 fs-md-2 fs-lg-1">我们的产品</h1>
            </div>
            <div style="width: 70%; margin: 0 auto;" class="d-none d-md-flex">
                <div id="carouselExample" class="carousel slide  w-100 " data-bs-ride="carousel"
                    data-bs-interval="3000">
            <!-- <div style="width: 70%; margin: 0 auto;" class="d-none d-md-flex">
                <div id="carouselExample" class="carousel slide  w-100 "
                    data-bs-ride="carousel"
                    data-bs-interval="5000"
                    data-bs-pause="hover"
                    >
                    <div class="carousel-inner">
                        <div :class="['carousel-item', { active: groupIndex === productGroupsIndex }]"
                            v-for="(group, groupIndex) in productGroups" :key="groupIndex">
@@ -50,15 +53,13 @@
                                <div class="col" v-for="(product, productIndex) in group.products" :key="productIndex">
                                    <div class="card">
                                        <div class="card-body d-flex flex-column">
                                            <!-- 标题部分 -->
                                            <h5 class="card-title mb-3" style="width: 100%; height: 50px;">{{
                                                product.title
                                            }}</h5>
                                            <!-- 内容部分 -->
                                            <p class="card-text mb-3" v-html="product.desc"
                                                style="width: 100%; height: 80px;"></p>
                                        </div>
                                        <!-- 图片部分 -->
                                        <div class="d-flex justify-content-center  p-2">
                                            <img :src="product.imgUrl" class="card-img-top" :alt="product.title"
                                                style="width: 100%; height: 150px;">
@@ -79,23 +80,57 @@
                        <span class="visually-hidden">Next</span>
                    </button>
                </div>
            </div> -->
            <div class="d-none d-md-flex" style="width: 70%; margin: 0 auto;">
                <div id="carouselExample" class="carousel slide w-100" data-bs-ride="carousel" data-bs-interval="5000"
                    data-bs-pause="hover">
                    <div class="carousel-inner">
                        <div class="carousel-item" v-for="(group, groupIndex) in productGroups"
                            :class="{ active: groupIndex === 0 }" :key="groupIndex">
                            <div class="row">
                                <div class="col" v-for="(product, productIndex) in group.products" :key="productIndex">
                                    <div class="card" @click="handleCardClick(product)">
                                        <div class="card-body d-flex flex-column">
                                            <h5 class="card-title mb-3" style="height: 50px;">{{ product.title }}</h5>
                                            <p class="card-text mb-3" v-html="product.desc" style="height: 80px;"></p>
                                        </div>
                                        <div class="d-flex justify-content-center p-2">
                                            <img :src="product.imgUrl" class="card-img-top" :alt="product.title"
                                                style="height: 150px;">
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <button class="carousel-control-prev" type="button" data-bs-target="#carouselExample"
                        data-bs-slide="prev">
                        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                    </button>
                    <button class="carousel-control-next" type="button" data-bs-target="#carouselExample"
                        data-bs-slide="next">
                        <span class="carousel-control-next-icon" aria-hidden="true"></span>
                    </button>
                </div>
            </div>
            <div style="width: 60%; margin: 0 auto; height: 300px;" class="d-block d-md-none ">
            <!-- <div style="width: 60%; margin: 0 auto; height: 300px;" class="d-block d-md-none ">
                <div id="carouselExampleMin" class="carousel slide " data-bs-ride="carousel" data-bs-interval="3000">
                    <div class="carousel-inner">
                        <div :class="['carousel-item', { active: index === productIndex }]"
                            v-for="(product, index) in allProducts" :key="index">
                            <div class="card">
                                <div class="card-body d-flex flex-column">
                                    <!-- 标题部分 -->
                                    <h5 class="card-title mb-3" style="width: 100%;">{{ product.title }}
                                    </h5>
                                    <!-- 内容部分 -->
                                    <p class="card-text mb-3" v-html="product.desc" style="width: 100%;">
                                    </p>
                                </div>
                                <!-- 图片部分 -->
                                <div class="d-flex justify-content-center p-2">
                                    <img :src="product.imgUrl" class="card-img-top" :alt="product.title"
                                        style="width: 100%; height: 100px;">
@@ -115,19 +150,50 @@
                        <span class="visually-hidden">Next</span>
                    </button>
                </div>
            </div> -->
            <div style="width: 60%; margin: 0 auto; height: 300px;" class="d-block d-md-none">
                <div id="carouselExampleMin" class="carousel slide" data-bs-ride="carousel" data-bs-interval="5000"
                    data-bs-pause="hover">
                    <div class="carousel-inner">
                        <div class="carousel-item" v-for="(product, index) in allProducts"
                            :class="{ active: index === 0 }" :key="index">
                            <div class="card" @click="handleCardClick(product)">
                                <div class="card-body d-flex flex-column">
                                    <h5 class="card-title mb-3" style="width: 100%;">{{ product.title }}</h5>
                                    <p class="card-text mb-3" v-html="product.desc" style="width: 100%;"></p>
                                </div>
                                <div class="d-flex justify-content-center p-2">
                                    <img :src="product.imgUrl" class="card-img-top" :alt="product.title"
                                        style="width: 100%; height: 100px;">
                                </div>
                            </div>
                        </div>
                    </div>
                    <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleMin"
                        data-bs-slide="prev">
                        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                        <span class="visually-hidden">Previous</span>
                    </button>
                    <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleMin"
                        data-bs-slide="next">
                        <span class="carousel-control-next-icon" aria-hidden="true"></span>
                        <span class="visually-hidden">Next</span>
                    </button>
                </div>
            </div>
        </div>
        <!-- 公司相关信息 -->
        <div  class="w-100" >
        <div class="w-100">
            <div class="row flex-md-nowrap">
                <!-- 第一列:占1份 -->
                <div class="col-12 col-md-3 text-center text-md-left">
                <div class="col-12 col-md-3 text-center text-md-start ps-md-5">
                    <!-- 产品中心 -->
                    <div class="text-center my-5 text-dark fs-4">产品中心</div>
                    <!-- <ul class="list-unstyled  m-1 text-start"></ul> -->
                    <ul class="list-unstyled  m-1">
                    <div class="my-5 text-dark fs-4">产品中心</div>
                    <ul class="list-unstyled">
                        <li v-for="(item, index) in ProductCenters" :key="index" class="mb-2">
                            <a href="javascript:void(0);" class="text-dark text-decoration-none fs-5"
                                @click.prevent="openPdf(item)">
@@ -148,36 +214,47 @@
                </div>
                <!-- 第三列:占1份 -->
                <div id="third-other" class="col-12 col-md-3 text-center text-md-left">
                <!-- <div id="third-other" class="col-12 col-md-3 text-center text-md-start "> -->
                <div id="third-other" class="col-12 col-md-3 mx-auto text-center text-md-start">
                    <!-- 公司信息 -->
                    <div class="text-center my-5 text-dark fs-4">公司信息</div>
                    <div class="container text-center">
                    <div class="my-5 text-dark fs-4">公司信息</div>
                    <div>
                        <!-- 第一行:Logo + 名称 + 简介 -->
                        <div class="d-flex flex-column align-items-center mb-4">
                            <div class="d-flex align-items-center gap-2">
                        <div class="d-flex flex-column  mb-4">
                            <div class="align-items-center ">
                                <img :src="companyInfo.logo" alt="云游四方" class="img-fluid"
                                    style="width: 48px; height: 48px; object-fit: contain;" />
                                <span class="fs-4 fw-semibold">{{ companyInfo.name }}</span>
                            </div>
                            <div class="fs-5 text-secondary mt-2" style="max-width: 600px;">
                                {{ companyInfo.desc }}
                                <span class="fs-5 fw-semibold">{{ companyInfo.name }}</span>
                                <span class="">| {{ companyInfo.desc }}</span>
                            </div>
                        </div>
                        <!-- 第二行:地址 -->
                        <div class="d-flex justify-content-center mb-4">
                            <span class="fs-5 text-dark">地址:{{ companyInfo.address }}</span>
                        <div class="text-center text-md-start mb-4">
                            <span class="fs-6 text-dark">地址:{{ companyInfo.address }}</span>
                        </div>
                        <!-- 第三行:二维码 -->
                        <div class="row justify-content-center g-4">
                        <!-- <div class="row g-2">
                            <div class="col-auto d-flex flex-column align-items-center"
                                v-for="(item, index) in companyInfo.qrCodeList" :key="index">
                                <img :src="item.url" alt="云游四方" class="img-fluid mb-2"
                                    style="width: 80px; height: 80px; object-fit: cover;" />
                                <span class="text-muted small">{{ item.name }}</span>
                            </div>
                        </div> -->
                        <!-- 外层容器设置为居中(小屏居中,大屏默认) -->
                        <div class="d-flex flex-wrap justify-content-center justify-content-md-start gap-3">
                            <div class="d-flex flex-column align-items-center"
                                v-for="(item, index) in companyInfo.qrCodeList" :key="index">
                                <img :src="item.url" alt="云游四方" class="img-fluid mb-2"
                                    style="width: 80px; height: 80px; object-fit: cover;" />
                                <span class="text-muted small text-center">{{ item.name }}</span>
                            </div>
                        </div>
                    </div>
                </div>
@@ -214,7 +291,7 @@
    </div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount ,nextTick} from 'vue'
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { CarouselItem, CooperativeClient, ProductCenter, CompanyInfo, Products, ProductGroup } from '@/models/portalModels';
import { useRoute, useRouter } from 'vue-router';
@@ -286,30 +363,43 @@
const isMobile = ref<boolean>(false) //
// 点击卡片
const handleCardClick = (item: Products) => {
    // 跳转到 /product 页面,并将item传递过去
    router.push({
        path: '/product',
        query: {
            title: item.title,
            desc: item.desc,
            imgUrl: item.imgUrl
        }
    });
}
// 初始化时设置高度
onMounted(() => {
    updateCarouselHeight();
    window.addEventListener('resize', updateCarouselHeight);
    intervalId = window.setInterval(updateIndex, 2000); // 每 1 秒执行一次
    intervalId = window.setInterval(updateIndex, 5000); // 每 1 秒执行一次
    productIntervalId = window.setInterval(updateProductIndex, 2000); // 每 1 秒执行一次
    productGroupsIntervalId = window.setInterval(updateProductGroupsIndex, 2000); // 每 1 秒执行一次
    // productGroupsIntervalId = window.setInterval(updateProductGroupsIndex, 2000); // 每 1 秒执行一次
    // productIntervalId = window.setInterval(updateProductIndex, 2000); // 每 1 秒执行一次
    isMobile.value =
    'ontouchstart' in window ||
    navigator.userAgent.toLowerCase().includes('mobi')
        'ontouchstart' in window ||
        navigator.userAgent.toLowerCase().includes('mobi')
});
// 清理事件监听
onBeforeUnmount(() => {
    window.removeEventListener('resize', updateCarouselHeight);
     // 清理定时任务
     if (intervalId) {
    // 清理定时任务
    if (intervalId) {
        window.clearInterval(intervalId);
    }
    if (productIntervalId) {
@@ -523,8 +613,9 @@
    flex-direction: column;
    gap: 10px;
}
.xuanfu {
  width: 30px;
  height: 30px;
    width: 30px;
    height: 30px;
}
</style>
src/pages/Product.vue
@@ -34,7 +34,7 @@
            </div>
            <div class="col-md-3 d-block d-md-none p-3" >
            <div class="col-md-3 d-block d-md-none p-3">
                <el-drawer v-model="drawerVisible" title="所有产品" direction="ltr" size="250px">
                    <el-menu :default-active="activeIndex" class="border-0" @select="handleSelect" @open="handleOpen"
                        @close="handleClose">
@@ -70,7 +70,7 @@
            <!-- Main Content Area -->
            <div class="col-12 col-md-9 p-3" style="overflow-y: auto; max-height: 100vh;" >
            <div class="col-12 col-md-9 p-3" style="overflow-y: auto; max-height: 100vh;">
                <!-- Upper Layer -->
                <div class="mb-3">
                    <div class="border-b border-gray-200 p-1 text-center ">
@@ -137,7 +137,7 @@
                    </div>
                    <div class="row  d-block d-md-none">
                        <div class="justify-content-center" >
                        <div class="justify-content-center">
                            <div class="col-12 col-sm-6 col-md-4 mb-4 justify-content-center"
                                v-for="(product, index) in products" :key="index">
                                <div class="card ">
@@ -165,14 +165,15 @@
        <!-- <button class="btn btn-primary rounded-circle floating-btn" @click="handleClick">
            <i class="bi bi-list fs-3 floating-btn"></i>
         </button> -->
        <img :src="menuIcon" alt="icon"
        style="width: 30px; height: 30px;" class="floating-btn d-block d-md-none" @click="handleClick" />
        <img :src="menuIcon" alt="icon" style="width: 30px; height: 30px;" class="floating-btn d-block d-md-none"
            @click="handleClick" />
    </div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router';
import { MenuItem, Products, ProductCenter } from '@/models/portalModels';
import PdfViewer from '@/components/pdf/PdfViewer.vue'
@@ -187,6 +188,8 @@
const title = ref('')
const pdfUrl = ref('')
const curSubItem = ref<MenuItem>({} as MenuItem)
const activeIndex = ref('')
@@ -255,6 +258,48 @@
        ],
    },
];
onMounted(() => {
    const route = useRoute();
    const title = route.query.title;
    if (!title) return;
    let foundIndex = '';
    let foundItem = null;
    for (const item of menuItems) {
        if (item.title === title) {
            foundIndex = item.index;
            foundItem = item;
            break;
        }
        if (item.subMenu) {
            const sub = item.subMenu.find(subItem => subItem.title === title);
            if (sub) {
                foundIndex = sub.index;
                foundItem = sub;
                break;
            }
        }
    }
    if (foundIndex && foundItem) {
        activeIndex.value = foundIndex;
        // 调用菜单选中逻辑(注意:这里你可能要加上菜单展开逻辑)
        if (foundIndex.includes('-')) {
            handleSelectSubmenu(foundItem); // 子菜单点击
        } else {
            handleSelect(foundIndex); // 顶层菜单点击(如果你需要)
        }
    }
});
const products = ref<Products[]>([
    { imgUrl: 'https://portal2.tos-cn-beijing.volces.com/portal/product-our/外部供应商管理系统.png', title: '外部供应商管理系统', desc: '通过数字化整合上下游资源<br/>打通多级分销信息壁垒,助力供应商增效增收。' },
@@ -326,6 +371,9 @@
</script>
<style>
body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
/* .el-menu .el-menu-item.is-active {
    font-weight: bold;
    color: #ffd04b;
src/router/index.ts
@@ -10,6 +10,7 @@
  { path: '/product', component: Product },
  { path: '/contact', component: Contact },
  { path: '/about',component: Home},
  { path: '/about2',component: About},
  {
    path: '/pdf-preview',
    name: 'PdfPreview',