项目阶段性完成

This commit is contained in:
2026-05-02 21:45:20 +08:00
commit 8dd773c603
22 changed files with 5858 additions and 0 deletions

39
.gitignore vendored Normal file
View File

@@ -0,0 +1,39 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo
.eslintcache
# Cypress
/cypress/videos/
/cypress/screenshots/
# Vitest
__screenshots__/
# Vite
*.timestamp-*-*.mjs

5
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"recommendations": [
"Vue.volar"
]
}

194
PROJECT.md Normal file
View File

@@ -0,0 +1,194 @@
# TechCorp 官网项目
一个简约科技风格的多页面企业官网,基于 Vue 3 + Vite + Element Plus 构建。
## 🚀 技术栈
- **前端框架**: Vue 3.5.32
- **构建工具**: Vite 7.3.2
- **UI 组件库**: Element Plus
- **路由管理**: Vue Router 5.0.6
- **状态管理**: Pinia 3.0.4
## 📁 项目结构
```
src/
├── assets/ # 静态资源
│ └── main.css # 全局样式文件
├── module/ # 公共组件
│ ├── head_menu.vue # 顶部导航栏
│ └── footer.vue # 页脚组件
├── router/ # 路由配置
│ └── router.js
├── views/ # 页面组件
│ ├── index/ # 首页
│ ├── products/ # 产品服务页
│ ├── about/ # 关于我们页
│ └── contact/ # 联系我们页
├── App.vue # 根组件
└── main.js # 入口文件
```
## ✨ 功能特性
### 1. 首页 (Home)
- 轮播图展示(自动播放,图片自适应)
- 核心优势展示
- 数据统计区域(动态数字展示)
- 行动号召区域CTA
### 2. 产品服务页 (Products)
- 产品分类筛选功能
- 产品卡片展示
- 服务特色介绍
- 价格信息展示
### 3. 关于我们页 (About)
- 简介和基本信息
- 价值展示
- 团队介绍
- 发展历程时间线
### 4. 联系我们页 (Contact)
- 联系信息展示QQ、微信、邮箱等
- 常见问题FAQ
## 🎨 设计风格
### 配色方案
- **主色调**: 科技蓝 (#0066ff)
- **辅助色**: 青色 (#00d4ff)
- **背景色**: 纯白 (#ffffff) / 浅灰 (#f8f9fa)
- **文字色**: 深灰 (#1a1a1a) / 中灰 (#666666)
### 设计特点
- 简约现代的界面设计
- 渐变色点缀增加科技感
- 卡片式布局,层次分明
- 流畅的动画过渡效果
- 响应式设计,适配移动端
## 🛠️ 开发指南
### 安装依赖
```bash
npm install
```
### 启动开发服务器
```bash
npm run dev
```
访问 http://localhost:5174/
### 构建生产版本
```bash
npm run build
```
### 预览生产构建
```bash
npm run preview
```
## 📱 响应式支持
网站完全支持响应式设计,在以下设备上都有良好的显示效果:
- 桌面端Desktop
- 平板端Tablet
- 移动端Mobile
## 🎯 核心组件
### 导航栏 (head_menu.vue)
- 使用 router-link 实现无刷新页面切换
- 当前页面高亮显示
- 毛玻璃效果背景
- 响应式菜单布局
### 页脚 (footer.vue)
- 公司信息展示
- 快速链接导航
- 社交媒体图标
- 版权信息
### 全局样式 (main.css)
- CSS 变量定义主题色
- 通用按钮样式
- 卡片组件样式
- 动画效果定义
- 响应式断点设置
## 🔧 可定制内容
### 修改公司信息
在相应页面组件中修改:
- 公司名称
- 联系方式
- 团队成员
- 发展历程
### 修改产品信息
`products.vue` 中修改:
- 产品列表
- 产品分类
- 产品价格
- 产品特性
### 修改配色方案
`assets/main.css` 中修改 CSS 变量:
```css
:root {
--primary-color: #0066ff;
--accent-color: #00d4ff;
/* ... 更多变量 */
}
```
## 📝 注意事项
1. 图片资源需要放置在对应的 `img` 目录下
2. 联系表单目前是模拟提交需要接入后端API
3. 地图部分为占位符,可以集成百度地图或高德地图
4. 轮播图图片建议尺寸1920x600px
## 🌟 后续优化建议
1. 添加页面加载动画
2. 集成真实的数据统计图表
3. 添加多语言支持
4. 优化SEO配置
5. 添加博客/新闻模块
6. 集成在线客服系统
7. 添加用户登录注册功能
## 📄 许可证
MIT License
---
**开发者**: TechCorp Team
**最后更新**: 2026年5月

42
README.md Normal file
View File

@@ -0,0 +1,42 @@
# TechCorp 企业官网
一个简约科技风格的多页面企业官网,基于 Vue 3 + Vite + Element Plus 构建。
## 快速开始
### 安装依赖
```bash
npm install
```
### 启动开发服务器
```bash
npm run dev
```
### 构建生产版本
```bash
npm run build
```
## 功能特性
- ✅ 响应式设计,支持多端设备
- ✅ 4个完整页面首页、产品、关于、联系
- ✅ 简约科技风格设计
- ✅ 流畅的动画效果
- ✅ 组件化开发
- ✅ 路由导航
## 技术栈
- Vue 3.5.32
- Vite 7.3.2
- Element Plus
- Vue Router 5.0.6
- Pinia 3.0.4
详细文档请查看 [PROJECT.md](./PROJECT.md)

13
index.html Normal file
View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="UTF-8">
<link href="/favicon.ico" rel="icon">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script src="/src/main.js" type="module"></script>
</body>
</html>

13
jsconfig.json Normal file
View File

@@ -0,0 +1,13 @@
{
"compilerOptions": {
"paths": {
"@/*": [
"./src/*"
]
}
},
"exclude": [
"node_modules",
"dist"
]
}

3435
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
package.json Normal file
View File

@@ -0,0 +1,26 @@
{
"name": "web1",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.15.2",
"element-plus": "^2.13.7",
"pinia": "^3.0.4",
"vue": "^3.5.32",
"vue-router": "^5.0.6"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.6",
"vite": "^7.3.2",
"vite-plugin-vue-devtools": "^8.1.1"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

13
src/App.vue Normal file
View File

@@ -0,0 +1,13 @@
<script setup>
</script>
<template>
<div>
<router-view></router-view>
</div>
</template>
<style scoped>
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

152
src/assets/main.css Normal file
View File

@@ -0,0 +1,152 @@
/* 全局样式 - 简约科技风格 */
:root {
/* 主色调 - 科技蓝 */
--primary-color: #0066ff;
--primary-light: #4d94ff;
--primary-dark: #0052cc;
/* 辅助色 - 青色 */
--accent-color: #00d4ff;
--accent-light: #66e5ff;
/* 中性色 */
--text-primary: #1a1a1a;
--text-secondary: #666666;
--text-light: #999999;
--bg-white: #ffffff;
--bg-light: #f8f9fa;
--bg-gray: #f0f2f5;
--border-color: #e8e8e8;
/* 渐变色 */
--gradient-primary: linear-gradient(135deg, #0066ff 0%, #00d4ff 100%);
--gradient-dark: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif, 'Microsoft YaHei', '微软雅黑';
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: var(--text-primary);
background-color: var(--bg-white);
line-height: 1.6;
}
#app {
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* 通用容器 */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* 标题样式 */
.section-title {
font-size: 36px;
font-weight: 700;
text-align: center;
margin-bottom: 16px;
color: var(--text-primary);
position: relative;
}
.section-subtitle {
font-size: 16px;
color: var(--text-secondary);
text-align: center;
margin-bottom: 60px;
}
/* 按钮样式 */
.btn-primary {
display: inline-block;
padding: 12px 32px;
background: var(--gradient-primary);
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(0, 102, 255, 0.3);
}
.btn-outline {
display: inline-block;
padding: 12px 32px;
background: transparent;
color: var(--primary-color);
border: 2px solid var(--primary-color);
border-radius: 8px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
}
.btn-outline:hover {
background: var(--primary-color);
color: white;
}
/* 卡片样式 */
.card {
background: white;
border-radius: 12px;
padding: 32px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-8px);
box-shadow: 0 12px 40px rgba(0, 102, 255, 0.15);
}
/* 动画效果 */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-in-up {
animation: fadeInUp 0.6s ease-out;
}
/* 响应式设计 */
@media (max-width: 768px) {
.section-title {
font-size: 28px;
}
.container {
padding: 0 16px;
}
}

13
src/main.js Normal file
View File

@@ -0,0 +1,13 @@
import './assets/main.css'
import {createApp} from 'vue'
import App from './App.vue'
import router from '@/router/router.js';
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(router);
app.use(ElementPlus)
app.mount('#app')

196
src/module/footer.vue Normal file
View File

@@ -0,0 +1,196 @@
<script setup>
const currentYear = new Date().getFullYear()
const footerLinks = {
product: [
{name: '产品功能', path: '/products'},
],
company: [
{name: '关于我们', path: '/about'},
],
support: [
{name: '帮助中心', path: '/contact'},
]
}
const socialLinks = [
{name: '微信', icon: '💬', ref: 'https://weixin.qq.com/'},
{name: '微博', icon: '🌐', ref: 'https://weibo.com/'},
{name: 'GitHub', icon: '💻', ref: 'https://github.com/'},
{name: 'LinkedIn', icon: '💼', ref: 'https://weixin.qq.com/'}
]
</script>
<template>
<footer class="footer">
<div class="container">
<div class="footer-content">
<!--公司信息-->
<div class="footer-section">
<h3 class="footer-logo">团队名</h3>
<p class="footer-desc">团队简要描述</p>
<div class="social-links">
<a
v-for="social in socialLinks"
:key="social.name"
:href="social.ref"
:title="social.name"
class="social-link"
rel="noopener noreferrer"
target="_blank">
{{ social.icon }}
</a>
</div>
</div>
<!--产品链接-->
<div class="footer-section">
<h4 class="footer-title">产品</h4>
<ul class="footer-links">
<li v-for="link in footerLinks.product" :key="link.name">
<router-link :to="link.path">{{ link.name }}</router-link>
</li>
</ul>
</div>
<!--链接-->
<div class="footer-section">
<h4 class="footer-title">我们</h4>
<ul class="footer-links">
<li v-for="link in footerLinks.company" :key="link.name">
<router-link :to="link.path">{{ link.name }}</router-link>
</li>
</ul>
</div>
<!--支持链接-->
<div class="footer-section">
<h4 class="footer-title">帮助</h4>
<ul class="footer-links">
<li v-for="link in footerLinks.support" :key="link.name">
<router-link :to="link.path">{{ link.name }}</router-link>
</li>
</ul>
</div>
</div>
<!--底部版权-->
<div class="footer-bottom">
<p>&copy; {{ currentYear }} 团队名. All rights reserved.</p>
</div>
</div>
</footer>
</template>
<style scoped>
.footer {
background: var(--gradient-dark);
color: white;
padding: 60px 20px 30px;
margin-top: auto;
}
.footer-content {
display: grid;
grid-template-columns: 2fr 1fr 1fr 1fr;
gap: 40px;
margin-bottom: 40px;
}
.footer-section {
display: flex;
flex-direction: column;
}
.footer-logo {
font-size: 24px;
font-weight: 700;
margin-bottom: 16px;
background: linear-gradient(135deg, #ffffff 0%, #00d4ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.footer-desc {
font-size: 14px;
line-height: 1.8;
opacity: 0.8;
margin-bottom: 20px;
}
.social-links {
display: flex;
gap: 12px;
}
.social-link {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.1);
border-radius: 8px;
font-size: 18px;
transition: all 0.3s ease;
cursor: pointer;
}
.social-link:hover {
background: rgba(255, 255, 255, 0.2);
transform: translateY(-2px);
}
.footer-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 20px;
color: white;
}
.footer-links {
list-style: none;
padding: 0;
margin: 0;
}
.footer-links li {
margin-bottom: 12px;
}
.footer-links a {
color: rgba(255, 255, 255, 0.7);
text-decoration: none;
font-size: 14px;
transition: all 0.3s ease;
}
.footer-links a:hover {
color: white;
padding-left: 4px;
}
.footer-bottom {
border-top: 1px solid rgba(255, 255, 255, 0.1);
padding-top: 30px;
text-align: center;
}
.footer-bottom p {
font-size: 14px;
opacity: 0.7;
}
@media (max-width: 768px) {
.footer-content {
grid-template-columns: 1fr;
gap: 30px;
}
.footer {
padding: 40px 16px 20px;
}
}
</style>

133
src/module/head_menu.vue Normal file
View File

@@ -0,0 +1,133 @@
<script setup>
import {useRoute, useRouter} from 'vue-router'
const router = useRouter()
const route = useRoute()
const menuItems = [
{name: '首页', path: '/'},
{name: '产品服务', path: '/products'},
{name: '关于我们', path: '/about'},
{name: '联系我们', path: '/contact'}
]
</script>
<template>
<div class="header-wrapper">
<el-menu
:default-active="route.path"
:ellipsis="false"
class="header-menu"
mode="horizontal"
>
<div class="logo">
<span class="logo-text">团队名</span>
</div>
<div class="menu-items">
<router-link
v-for="item in menuItems"
:key="item.path"
:to="item.path"
class="menu-item"
>
{{ item.name }}
</router-link>
</div>
</el-menu>
</div>
</template>
<style scoped>
.header-wrapper {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
position: sticky;
top: 0;
z-index: 1000;
}
.header-menu {
max-width: 1200px;
margin: 0 auto;
border: none;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
height: 70px;
}
.logo {
display: flex;
align-items: center;
}
.logo-text {
font-size: 24px;
font-weight: 700;
background: linear-gradient(135deg, #0066ff 0%, #00d4ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
cursor: pointer;
}
.menu-items {
display: flex;
gap: 40px;
align-items: center;
}
.menu-item {
color: var(--text-primary);
font-size: 16px;
font-weight: 500;
text-decoration: none;
padding: 8px 16px;
border-radius: 8px;
transition: all 0.3s ease;
position: relative;
}
.menu-item:hover {
color: var(--primary-color);
background: rgba(0, 102, 255, 0.05);
}
.menu-item.router-link-active {
color: var(--primary-color);
font-weight: 600;
}
.menu-item.router-link-active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 20px;
height: 3px;
background: var(--gradient-primary);
border-radius: 2px;
}
@media (max-width: 768px) {
.header-menu {
padding: 0 16px;
}
.menu-items {
gap: 20px;
}
.menu-item {
font-size: 14px;
padding: 6px 12px;
}
.logo-text {
font-size: 20px;
}
}
</style>

31
src/router/router.js Normal file
View File

@@ -0,0 +1,31 @@
import {createRouter, createWebHistory} from "vue-router";
const routes = [
{
name: '首页',
path: '/',
component: () => import('../views/index/index.vue')
},
{
name: '产品服务',
path: '/products',
component: () => import('../views/products/products.vue')
},
{
name: '关于我们',
path: '/about',
component: () => import('../views/about/about.vue')
},
{
name: '联系我们',
path: '/contact',
component: () => import('../views/contact/contact.vue')
}
]
const router = createRouter({
routes,
history: createWebHistory()
})
export default router

474
src/views/about/about.vue Normal file
View File

@@ -0,0 +1,474 @@
<script setup>
import Head_menu from "@/module/head_menu.vue";
import Footer from "@/module/footer.vue";
// 公司信息
const companyInfo = {
name: '团队名',
founded: '2020年',
location: '中国·北京',
employees: '200+',
mission: '子标题 使命 的内容',
vision: '子标题 愿景 的内容'
}
// 团队成贝
const teamMembers = [
{
name: '姓名',
position: '职位',
avatar: '👨‍💼',
description: '简单的描述'
},
{
name: '姓名',
position: '职位',
avatar: '👨‍💻',
description: '简单的描述'
},
{
name: '姓名',
position: '职位',
avatar: '👩‍💼',
description: '简单的描述'
},
{
name: '姓名',
position: '职位',
avatar: '👨‍🎨',
description: '简单的描述'
}
]
// 发展历程
const milestones = [
{
year: 'xxxx年',
title: 'xxxxxx',
description: '简要描述'
},
{
year: 'xxxx年',
title: 'xxxxxx',
description: '简要描述'
},
{
year: 'xxxx年',
title: 'xxxxxx',
description: '简要描述'
},
{
year: 'xxxx年',
title: 'xxxxxx',
description: '简要描述'
},
{
year: 'xxxx年',
title: 'xxxxxx',
description: '简要描述'
},
{
year: 'xxxx年',
title: 'xxxxxx',
description: '简要描述'
}
]
// 核心价值
const values = [
{
icon: '🎯',
title: '核心价值 标题',
description: '核心价值 简介'
},
{
icon: '💡',
title: '核心价值 标题',
description: '核心价值 简介'
},
{
icon: '🤝',
title: '核心价值 标题',
description: '核心价值 简介'
},
{
icon: '⚡',
title: '核心价值 标题',
description: '核心价值 简介'
}
]
</script>
<template>
<div class="about-page">
<!--顶部导航栏-->
<head_menu></head_menu>
<!--简介区域-->
<section class="hero-section">
<div class="container">
<h1 class="page-title">关于我们</h1>
<p class="page-subtitle">了解我们的故事和愿景</p>
</div>
</section>
<!--介绍区域-->
<section class="intro-section container">
<div class="intro-content card">
<div class="intro-text">
<h2 class="intro-title">简介</h2>
<p class="intro-desc">这里填写一大串的介绍文本</p>
<div class="info-grid">
<div class="info-item">
<span class="info-label">成立于</span>
<span class="info-value">{{ companyInfo.founded }}</span>
</div>
<div class="info-item">
<span class="info-label">地点</span>
<span class="info-value">{{ companyInfo.location }}</span>
</div>
<div class="info-item">
<span class="info-label">规模</span>
<span class="info-value">{{ companyInfo.employees }}</span>
</div>
</div>
<div class="mission-vision">
<div class="mv-item">
<h3>使命</h3>
<p>{{ companyInfo.mission }}</p>
</div>
<div class="mv-item">
<h3>愿景</h3>
<p>{{ companyInfo.vision }}</p>
</div>
</div>
</div>
</div>
</section>
<!--核心价值区域-->
<section class="values-section">
<div class="container">
<h2 class="section-title">核心价值</h2>
<p class="section-subtitle">我们的价值观指引着每一步前行</p>
<div class="values-grid">
<div v-for="(value, index) in values" :key="index" class="value-card card">
<div class="value-icon">{{ value.icon }}</div>
<h3 class="value-title">{{ value.title }}</h3>
<p class="value-desc">{{ value.description }}</p>
</div>
</div>
</div>
</section>
<!--团队展示区域-->
<section class="team-section container">
<h2 class="section-title">核心团队</h2>
<p class="section-subtitle">优秀的团队成就卓越的事业</p>
<div class="team-grid">
<div v-for="(member, index) in teamMembers" :key="index" class="team-card card">
<div class="member-avatar">{{ member.avatar }}</div>
<h3 class="member-name">{{ member.name }}</h3>
<p class="member-position">{{ member.position }}</p>
<p class="member-desc">{{ member.description }}</p>
</div>
</div>
</section>
<!--发展历程区域-->
<section class="timeline-section">
<div class="container">
<h2 class="section-title">发展历程</h2>
<p class="section-subtitle">记录我们的成长足迹</p>
<div class="timeline">
<div v-for="(milestone, index) in milestones" :key="index" class="timeline-item">
<div class="timeline-marker"></div>
<div class="timeline-content card">
<div class="timeline-year">{{ milestone.year }}</div>
<h3 class="timeline-title">{{ milestone.title }}</h3>
<p class="timeline-desc">{{ milestone.description }}</p>
</div>
</div>
</div>
</div>
</section>
<!--页脚-->
<Footer/>
</div>
</template>
<style scoped>
.about-page {
min-height: 100vh;
}
/* 顶部区域 */
.hero-section {
background: var(--gradient-primary);
padding: 80px 20px;
text-align: center;
color: white;
}
.page-title {
font-size: 48px;
font-weight: 700;
margin-bottom: 16px;
}
.page-subtitle {
font-size: 18px;
opacity: 0.95;
}
/* 公司介绍区域 */
.intro-section {
padding: 80px 20px;
}
.intro-content {
padding: 50px;
}
.intro-title {
font-size: 32px;
font-weight: 700;
margin-bottom: 24px;
color: var(--text-primary);
}
.intro-desc {
font-size: 16px;
line-height: 1.8;
color: var(--text-secondary);
margin-bottom: 32px;
}
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 40px;
}
.info-item {
display: flex;
flex-direction: column;
gap: 8px;
}
.info-label {
font-size: 14px;
color: var(--text-light);
}
.info-value {
font-size: 18px;
font-weight: 600;
color: var(--primary-color);
}
.mission-vision {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
}
.mv-item h3 {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
color: var(--primary-color);
}
.mv-item p {
font-size: 16px;
color: var(--text-secondary);
line-height: 1.6;
}
/* 核心价值区域 */
.values-section {
background: var(--bg-light);
padding: 80px 20px;
}
.values-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
margin-top: 40px;
}
.value-card {
text-align: center;
padding: 40px 30px;
}
.value-icon {
font-size: 48px;
margin-bottom: 20px;
}
.value-title {
font-size: 22px;
font-weight: 600;
margin-bottom: 12px;
color: var(--text-primary);
}
.value-desc {
font-size: 15px;
color: var(--text-secondary);
line-height: 1.8;
}
/* 团队展示区域 */
.team-section {
padding: 80px 20px;
}
.team-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
margin-top: 40px;
}
.team-card {
text-align: center;
padding: 40px 30px;
}
.member-avatar {
width: 100px;
height: 100px;
margin: 0 auto 20px;
background: var(--gradient-primary);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 48px;
}
.member-name {
font-size: 20px;
font-weight: 600;
margin-bottom: 8px;
color: var(--text-primary);
}
.member-position {
font-size: 14px;
color: var(--primary-color);
margin-bottom: 12px;
font-weight: 500;
}
.member-desc {
font-size: 14px;
color: var(--text-secondary);
line-height: 1.6;
}
/* 发展历程区域 */
.timeline-section {
background: var(--bg-light);
padding: 80px 20px;
}
.timeline {
position: relative;
max-width: 800px;
margin: 40px auto 0;
}
.timeline::before {
content: '';
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 2px;
height: 100%;
background: var(--border-color);
}
.timeline-item {
position: relative;
margin-bottom: 40px;
display: flex;
align-items: center;
}
.timeline-item:nth-child(odd) {
flex-direction: row-reverse;
}
.timeline-marker {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 16px;
height: 16px;
background: var(--primary-color);
border-radius: 50%;
border: 3px solid white;
box-shadow: 0 0 0 3px var(--primary-color);
z-index: 1;
}
.timeline-content {
width: 45%;
padding: 24px;
}
.timeline-year {
font-size: 24px;
font-weight: 700;
color: var(--primary-color);
margin-bottom: 8px;
}
.timeline-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 8px;
color: var(--text-primary);
}
.timeline-desc {
font-size: 14px;
color: var(--text-secondary);
line-height: 1.6;
}
@media (max-width: 768px) {
.page-title {
font-size: 36px;
}
.intro-content {
padding: 30px 20px;
}
.timeline::before {
left: 20px;
}
.timeline-marker {
left: 20px;
}
.timeline-item,
.timeline-item:nth-child(odd) {
flex-direction: row;
padding-left: 50px;
}
.timeline-content {
width: 100%;
}
}
</style>

View File

@@ -0,0 +1,392 @@
<script setup>
import Head_menu from "@/module/head_menu.vue";
import Footer from "@/module/footer.vue";
import {ref} from 'vue'
// 联系表单数据
const contactForm = ref({
name: '',
email: '',
phone: '',
subject: '',
message: ''
})
// 联系方式
const contactInfo = [
{
icon: '图标 1',
title: '标题 1',
content: '内容 1'
},
{
icon: '图标 2',
title: '标题 2',
content: '内容 2'
},
{
icon: '图标 3',
title: '标题 3',
content: '内容 3'
},
{
icon: '图标 4',
title: '标题 4',
content: '内容 4'
}
]
const faqList = [
{
title: '问题 1',
content: '内容 1'
},
{
title: '问题 2',
content: '内容 2'
},
{
title: '问题 3',
content: '内容 3'
},
]
</script>
<template>
<div class="contact-page">
<!--顶部导航栏-->
<head_menu></head_menu>
<!--页面标题区域-->
<section class="hero-section">
<div class="container">
<h1 class="page-title">联系我们</h1>
<p class="page-subtitle">子标题</p>
</div>
</section>
<!--联系信息区域-->
<section class="info-section container">
<div class="info-grid">
<div v-for="(info, index) in contactInfo" :key="index" class="info-card card">
<div class="info-icon">{{ info.icon }}</div>
<h3 class="info-title">{{ info.title }}</h3>
<p class="info-content">{{ info.content }}</p>
</div>
</div>
</section>
<!--我们的信息-->
<section class="form-section container">
<div class="form-wrapper">
<!--我们的信息-->
<div class="form-container card">
<h2 class="form-title">我们的信息</h2>
<p class="form-desc">QQ微信邮箱 ...</p>
<el-container>
<el-form ref="contactForm" :model="contactForm" label-width="80px">
<div>
<div class="link-me">
<p style="font-size: 110%; font-weight: bold; margin-right: 10px;">QQ:</p>
<p style="">1234567891</p>
</div>
<div class="link-me">
<p style="font-size: 110%; font-weight: bold; margin-right: 10px;">微信:</p>
<p style="">1234567891</p>
</div>
<div class="link-me">
<p style="font-size: 110%; font-weight: bold; margin-right: 10px;">Email:</p>
<p style="">export.mail@com</p>
</div>
</div>
</el-form>
</el-container>
</div>
</div>
</section>
<!--常见问题区域-->
<section class="faq-section">
<div class="container">
<h2 class="section-title">常见问题</h2>
<p class="section-subtitle">快速找到您需要的答案</p>
<div class="faq-list">
<el-collapse accordion>
<el-collapse-item
v-for="(faq, index) in faqList"
:key="index"
:name="index + 1"
:title="faq.title"
>
<div class="faq-answer">
{{ faq.content }}
</div>
</el-collapse-item>
</el-collapse>
</div>
</div>
</section>
<!--页脚-->
<Footer/>
</div>
</template>
<style scoped>
/* 我们的信息 */
.link-me {
display: flex;
}
.contact-page {
min-height: 100vh;
}
/* 顶部区域 */
.hero-section {
background: var(--gradient-primary);
padding: 80px 20px;
text-align: center;
color: white;
}
.page-title {
font-size: 48px;
font-weight: 700;
margin-bottom: 16px;
}
.page-subtitle {
font-size: 18px;
opacity: 0.95;
}
/* 联系信息区域 */
.info-section {
padding: 60px 20px;
margin-top: -40px;
position: relative;
z-index: 10;
}
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 24px;
}
.info-card {
text-align: center;
padding: 32px 24px;
}
.info-icon {
font-size: 40px;
margin-bottom: 16px;
}
.info-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 8px;
color: var(--text-primary);
}
.info-content {
font-size: 15px;
color: var(--text-secondary);
}
/* 表单区域 */
.form-section {
padding: 60px 20px;
}
.form-wrapper {
display: grid;
grid-template-columns: 1.5fr 1fr;
gap: 30px;
}
.form-container {
padding: 40px;
}
.form-title {
font-size: 28px;
font-weight: 700;
margin-bottom: 12px;
color: var(--text-primary);
}
.form-desc {
font-size: 15px;
color: var(--text-secondary);
margin-bottom: 8px;
}
.contact-form {
margin-top: 24px;
}
.submit-btn {
width: 100%;
height: 48px;
font-size: 16px;
font-weight: 600;
}
.map-container {
padding: 40px;
display: flex;
flex-direction: column;
}
.map-title {
font-size: 28px;
font-weight: 700;
margin-bottom: 24px;
color: var(--text-primary);
}
.map-placeholder {
flex: 1;
background: var(--bg-light);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
min-height: 400px;
}
.map-content {
text-align: center;
}
.map-icon {
font-size: 64px;
margin-bottom: 16px;
}
.map-text {
font-size: 16px;
color: var(--text-secondary);
margin-bottom: 8px;
}
.map-address {
font-size: 14px;
color: var(--text-light);
}
/* FAQ区域 */
.faq-section {
background: var(--bg-light);
padding: 80px 20px;
}
.faq-list {
max-width: 900px;
margin: 40px auto 0;
}
/* Element Plus Collapse 自定义样式 */
.faq-list :deep(.el-collapse) {
border: none;
background: transparent;
}
.faq-list :deep(.el-collapse-item) {
margin-bottom: 16px;
border-radius: 12px;
overflow: hidden;
background: white;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
}
.faq-list :deep(.el-collapse-item:hover) {
box-shadow: 0 4px 20px rgba(0, 102, 255, 0.12);
transform: translateY(-2px);
}
.faq-list :deep(.el-collapse-item__header) {
background: white;
color: var(--text-primary);
font-size: 17px;
font-weight: 600;
padding: 20px 24px;
border: none;
line-height: 1.6;
transition: all 0.3s ease;
}
.faq-list :deep(.el-collapse-item__header:hover) {
background: linear-gradient(135deg, rgba(0, 102, 255, 0.03) 0%, rgba(0, 212, 255, 0.03) 100%);
color: var(--primary-color);
}
.faq-list :deep(.el-collapse-item__header.is-active) {
background: linear-gradient(135deg, rgba(0, 102, 255, 0.05) 0%, rgba(0, 212, 255, 0.05) 100%);
color: var(--primary-color);
border-bottom: 1px solid var(--border-color);
}
.faq-list :deep(.el-collapse-item__arrow) {
font-size: 14px;
color: var(--primary-color);
transition: transform 0.3s ease;
}
.faq-list :deep(.el-collapse-item__wrap) {
border: none;
background: white;
}
.faq-list :deep(.el-collapse-item__content) {
padding: 24px;
color: var(--text-secondary);
font-size: 15px;
line-height: 1.8;
background: white;
}
.faq-answer {
position: relative;
padding-left: 16px;
}
.faq-answer::before {
content: '';
position: absolute;
left: 0;
top: 8px;
width: 4px;
height: calc(100% - 16px);
background: var(--gradient-primary);
border-radius: 2px;
opacity: 0.6;
}
@media (max-width: 768px) {
.page-title {
font-size: 36px;
}
.form-wrapper {
grid-template-columns: 1fr;
}
.form-container,
.map-container {
padding: 30px 20px;
}
.info-section {
margin-top: -20px;
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

296
src/views/index/index.vue Normal file
View File

@@ -0,0 +1,296 @@
<script setup>
import Head_menu from "@/module/head_menu.vue";
import Footer from "@/module/footer.vue";
// 轮播图数据
const carouselImages = [
{id: 1, src: new URL('./img/background.png', import.meta.url).href, title: '<团队名>', desc: '<团队简介>'},
{
id: 2,
src: new URL('./img/background.png', import.meta.url).href,
title: '智能解决方案',
desc: '为您提供全方位服务'
},
{id: 3, src: new URL('./img/background.png', import.meta.url).href, title: '专业团队', desc: '打造卓越产品体验'}
]
// 核心特性数据
const features = [
{
icon: '🚀',
title: '特性&优势',
description: '简介'
},
{
icon: '🔒',
title: '特性&优势',
description: '简介'
},
{
icon: '💡',
title: '特性&优势',
description: '简介'
},
{
icon: '🌐',
title: '特性&优势',
description: '简介'
}
]
// 统计数据
const stats = [
{value: '1000+', label: '加入我们的伙伴们'},
{value: '24/7', label: '客服在线'},
{value: '50+', label: '我们的案例'}
]
</script>
<template>
<div class="home-page">
<!--顶部导航栏-->
<head_menu></head_menu>
<!--轮播图区域-->
<section class="hero-section">
<el-carousel :interval="5000" arrow="always" height="500px" indicator-position="outside">
<el-carousel-item v-for="item in carouselImages" :key="item.id">
<div class="carousel-content">
<img :alt="item.title" :src="item.src" class="carousel-img">
<div class="carousel-overlay">
<div class="carousel-text">
<h1 class="carousel-title">{{ item.title }}</h1>
<p class="carousel-desc">{{ item.desc }}</p>
<el-button class="cta-button" size="large" type="primary">了解更多</el-button>
</div>
</div>
</div>
</el-carousel-item>
</el-carousel>
</section>
<!--核心特性区域-->
<section class="features-section container">
<h2 class="section-title">核心优势</h2>
<p class="section-subtitle">我们致力于为客户提供最优质的技术服务</p>
<div class="features-grid">
<div v-for="(feature, index) in features" :key="index" class="feature-card card fade-in-up">
<div class="feature-icon">{{ feature.icon }}</div>
<h3 class="feature-title">{{ feature.title }}</h3>
<p class="feature-desc">{{ feature.description }}</p>
</div>
</div>
</section>
<!--数据统计区域-->
<section class="stats-section">
<div class="container">
<div class="stats-grid">
<div v-for="(stat, index) in stats" :key="index" class="stat-item">
<div class="stat-value">{{ stat.value }}</div>
<div class="stat-label">{{ stat.label }}</div>
</div>
</div>
</div>
</section>
<!--行动号召区域-->
<section class="cta-section container">
<div class="cta-content card">
<h2 class="cta-title">准备好开始了吗</h2>
<p class="cta-desc">点击下方立即加入我们吧</p>
<div class="cta-buttons">
<router-link class="btn-primary" to="/contact">联系我们</router-link>
<router-link class="btn-outline" to="/products">查看服务</router-link>
</div>
</div>
</section>
<!--页脚-->
<Footer/>
</div>
</template>
<style scoped>
.home-page {
min-height: 100vh;
}
/* 轮播图区域 */
.hero-section {
position: relative;
width: 100%;
}
.carousel-content {
position: relative;
width: 100%;
height: 500px;
overflow: hidden;
}
.carousel-img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.carousel-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(0, 102, 255, 0.7) 0%, rgba(0, 212, 255, 0.5) 100%);
display: flex;
align-items: center;
justify-content: center;
}
.carousel-text {
text-align: center;
color: white;
padding: 20px;
}
.carousel-title {
font-size: 48px;
font-weight: 700;
margin-bottom: 16px;
animation: fadeInUp 0.8s ease-out;
}
.carousel-desc {
font-size: 20px;
margin-bottom: 32px;
opacity: 0.95;
animation: fadeInUp 0.8s ease-out 0.2s both;
}
.cta-button {
animation: fadeInUp 0.8s ease-out 0.4s both;
}
/* 核心特性区域 */
.features-section {
padding: 80px 20px;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
margin-top: 40px;
}
.feature-card {
text-align: center;
padding: 40px 30px;
}
.feature-icon {
font-size: 48px;
margin-bottom: 20px;
}
.feature-title {
font-size: 22px;
font-weight: 600;
margin-bottom: 12px;
color: var(--text-primary);
}
.feature-desc {
font-size: 15px;
color: var(--text-secondary);
line-height: 1.8;
}
/* 数据统计区域 */
.stats-section {
background: var(--gradient-dark);
padding: 60px 20px;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 40px;
text-align: center;
}
.stat-item {
color: white;
}
.stat-value {
font-size: 48px;
font-weight: 700;
margin-bottom: 8px;
background: linear-gradient(135deg, #ffffff 0%, #00d4ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.stat-label {
font-size: 16px;
opacity: 0.9;
}
/* 行动号召区域 */
.cta-section {
padding: 80px 20px;
}
.cta-content {
text-align: center;
padding: 60px 40px;
background: var(--bg-light);
}
.cta-title {
font-size: 36px;
font-weight: 700;
margin-bottom: 16px;
color: var(--text-primary);
}
.cta-desc {
font-size: 18px;
color: var(--text-secondary);
margin-bottom: 32px;
}
.cta-buttons {
display: flex;
gap: 20px;
justify-content: center;
flex-wrap: wrap;
}
@media (max-width: 768px) {
.carousel-title {
font-size: 32px;
}
.carousel-desc {
font-size: 16px;
}
.features-section,
.cta-section {
padding: 60px 16px;
}
.stat-value {
font-size: 36px;
}
.cta-buttons {
flex-direction: column;
align-items: center;
}
}
</style>

View File

@@ -0,0 +1,373 @@
<script setup>
import Head_menu from "@/module/head_menu.vue";
import Footer from "@/module/footer.vue";
// 过滤产品
import {computed, ref} from 'vue'
// 产品分类
const categories = [
{id: 'all', name: '全部'},
{id: 'ArtCustomization', name: '子类 1'},
{id: 'ModelMaking', name: '子类 2'},
{id: 'MoreServices', name: '子类 3'}
]
const activeCategory = ref('all')
// 产品列表
const products = [
{
id: 1,
category: 'ArtCustomization',
icon: '🖼️︎',
name: '美术定制',
description: '美术定制 简介',
features: ['美术定制'],
price: '¥ 999/张 起'
},
{
id: 2,
category: 'ModelMaking',
icon: '🛩️',
name: '模型制作',
description: '模型制作 简介',
features: ['模型制作'],
price: '¥ 1999/个 起'
},
{
id: 3,
category: 'MoreServices',
icon: '🗐',
name: '更多服务...',
description: '更多服务敬请期待...',
features: ['更多服务'],
price: '¥ xxx/月 起'
}
]
const filteredProducts = computed(() => {
if (activeCategory.value === 'all') {
return products
}
return products.filter(p => p.category === activeCategory.value)
})
// 服务特色
const serviceFeatures = [
{
icon: '⚡',
title: '快速',
description: '客服极速响应,不再等待!'
},
{
icon: '🔄',
title: '持续',
description: '定期推出我们的更新'
},
{
icon: '🎯',
title: '定制',
description: '根据需求提供个性化解决方案'
},
{
icon: '💬',
title: '专属',
description: '一对一技术支持和咨询服务'
}
]
</script>
<template>
<div class="products-page">
<!--顶部导航栏-->
<head_menu></head_menu>
<!--页面标题区域-->
<section class="hero-section">
<div class="container">
<h1 class="page-title">我们的服务</h1>
<p class="page-subtitle">为您提供前所未有的服务体验</p>
</div>
</section>
<!--产品分类筛选-->
<section class="filter-section container">
<div class="filter-tabs">
<button
v-for="category in categories"
:key="category.id"
:class="['filter-tab', { active: activeCategory === category.id }]"
@click="activeCategory = category.id"
>
{{ category.name }}
</button>
</div>
</section>
<!--产品列表区域-->
<section class="products-section container">
<div class="products-grid">
<div v-for="product in filteredProducts" :key="product.id" class="product-card card">
<div class="product-header">
<div class="product-icon">{{ product.icon }}</div>
<h3 class="product-name">{{ product.name }}</h3>
</div>
<p class="product-desc">{{ product.description }}</p>
<div class="product-features">
<span v-for="(feature, index) in product.features" :key="index" class="feature-tag">
{{ feature }}
</span>
</div>
<div class="product-footer">
<div class="product-price">{{ product.price }}</div>
<el-button size="default" type="primary">了解详情</el-button>
</div>
</div>
</div>
</section>
<!--服务特色区域-->
<section class="features-section">
<div class="container">
<h2 class="section-title">服务特色</h2>
<p class="section-subtitle">为什么选择我们的产品和服务</p>
<div class="features-grid">
<div v-for="(feature, index) in serviceFeatures" :key="index" class="feature-item card">
<div class="feature-icon">{{ feature.icon }}</div>
<h3 class="feature-title">{{ feature.title }}</h3>
<p class="feature-desc">{{ feature.description }}</p>
</div>
</div>
</div>
</section>
<!--行动号召区域-->
<section class="cta-section container">
<div class="cta-content card">
<h2 class="cta-title">需要定制化解决方案</h2>
<p class="cta-desc">我们的专家团队将为您量身打造最适合的产品组合</p>
<router-link class="btn-primary" to="/contact">联系我们</router-link>
</div>
</section>
<!--页脚-->
<Footer/>
</div>
</template>
<style scoped>
.products-page {
min-height: 100vh;
}
/* 顶部区域 */
.hero-section {
background: var(--gradient-primary);
padding: 80px 20px;
text-align: center;
color: white;
}
.page-title {
font-size: 48px;
font-weight: 700;
margin-bottom: 16px;
}
.page-subtitle {
font-size: 18px;
opacity: 0.95;
}
/* 筛选区域 */
.filter-section {
padding: 40px 20px;
}
.filter-tabs {
display: flex;
justify-content: center;
gap: 16px;
flex-wrap: wrap;
}
.filter-tab {
padding: 10px 24px;
border: 2px solid var(--border-color);
background: white;
border-radius: 8px;
font-size: 15px;
font-weight: 500;
color: var(--text-secondary);
cursor: pointer;
transition: all 0.3s ease;
}
.filter-tab:hover {
border-color: var(--primary-color);
color: var(--primary-color);
}
.filter-tab.active {
background: var(--primary-color);
border-color: var(--primary-color);
color: white;
}
/* 产品列表区域 */
.products-section {
padding: 40px 20px 80px;
}
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 30px;
}
.product-card {
padding: 32px;
display: flex;
flex-direction: column;
height: 100%;
}
.product-header {
margin-bottom: 20px;
}
.product-icon {
font-size: 48px;
margin-bottom: 16px;
}
.product-name {
font-size: 22px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 12px;
}
.product-desc {
font-size: 15px;
color: var(--text-secondary);
line-height: 1.6;
margin-bottom: 20px;
flex: 1;
}
.product-features {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 24px;
}
.feature-tag {
padding: 6px 12px;
background: var(--bg-light);
color: var(--primary-color);
border-radius: 6px;
font-size: 13px;
font-weight: 500;
}
.product-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20px;
border-top: 1px solid var(--border-color);
}
.product-price {
font-size: 24px;
font-weight: 700;
color: var(--primary-color);
}
/* 服务特色区域 */
.features-section {
background: var(--bg-light);
padding: 80px 20px;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
margin-top: 40px;
}
.feature-item {
text-align: center;
padding: 40px 30px;
}
.feature-icon {
font-size: 48px;
margin-bottom: 20px;
}
.feature-title {
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
color: var(--text-primary);
}
.feature-desc {
font-size: 15px;
color: var(--text-secondary);
line-height: 1.6;
}
/* 行动号召区域 */
.cta-section {
padding: 80px 20px;
}
.cta-content {
text-align: center;
padding: 60px 40px;
background: var(--gradient-dark);
color: white;
}
.cta-title {
font-size: 32px;
font-weight: 700;
margin-bottom: 16px;
}
.cta-desc {
font-size: 16px;
opacity: 0.9;
margin-bottom: 32px;
}
@media (max-width: 768px) {
.page-title {
font-size: 36px;
}
.products-grid {
grid-template-columns: 1fr;
}
.filter-tabs {
gap: 12px;
}
.filter-tab {
padding: 8px 16px;
font-size: 14px;
}
.product-footer {
flex-direction: column;
gap: 16px;
align-items: flex-start;
}
}
</style>

18
vite.config.js Normal file
View File

@@ -0,0 +1,18 @@
import {fileURLToPath, URL} from 'node:url'
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})