新增课程详情页面以及其他的页面
This commit is contained in:
parent
4c69fdf4fc
commit
11f10ca0c8
125
docs/Activities-Page.md
Normal file
125
docs/Activities-Page.md
Normal file
@ -0,0 +1,125 @@
|
||||
# 活动页面 (Activities Page)
|
||||
|
||||
## 📋 概述
|
||||
|
||||
活动页面是在线学习平台的重要组成部分,展示所有可用的学习活动和课程。页面设计完全按照提供的UI设计图实现,包含蓝色横幅区域和活动卡片网格布局。
|
||||
|
||||
## 🎨 页面结构
|
||||
|
||||
### 1. 蓝色横幅区域 (Hero Banner)
|
||||
- **背景**: 蓝色渐变背景 (#4A90E2 到 #357ABD)
|
||||
- **左侧内容**:
|
||||
- 分类标签: "理工/消安/药师/中经"
|
||||
- 主标题: "免费海量题库" + 橙色"小程序"标签
|
||||
- 特色说明: "优质试题 | 无需下载 | 随时刷题"
|
||||
- **右侧**: 插图占位区域(预留给后续图片)
|
||||
- **装饰元素**: 网格背景纹理
|
||||
|
||||
### 2. 活动列表区域
|
||||
- **标题**: "全部活动"
|
||||
- **布局**: 3列网格布局(响应式)
|
||||
- **活动卡片**: 6个相同样式的卡片
|
||||
|
||||
### 3. 活动卡片设计
|
||||
每个卡片包含:
|
||||
- **头部**: 蓝绿色渐变背景
|
||||
- 年份标签: "2025"
|
||||
- 课程标题: "计算机二级"
|
||||
- 课程副标题: "C语言讲练综合班"
|
||||
- **主体内容**:
|
||||
- 特色标签: "系统备考"、"考点详解"、"题考刷题"
|
||||
- 课程信息: 证书名称、开课时间、适合年级、报名人数、价格
|
||||
- **底部**: 蓝色"查看详情"按钮
|
||||
|
||||
## 🎯 功能特性
|
||||
|
||||
### 1. 响应式设计
|
||||
- **桌面端**: 3列网格布局
|
||||
- **平板端**: 2列网格布局
|
||||
- **移动端**: 1列网格布局
|
||||
|
||||
### 2. 交互效果
|
||||
- **卡片悬停**: 阴影加深 + 向上移动
|
||||
- **按钮悬停**: 颜色变化 + 轻微上移
|
||||
- **加载动画**: 骨架屏效果
|
||||
|
||||
### 3. 动画效果
|
||||
- **页面加载**: 左右滑入动画
|
||||
- **卡片显示**: 渐入上移动画(错开延迟)
|
||||
- **加载状态**: 闪烁骨架屏
|
||||
|
||||
## 🛠️ 技术实现
|
||||
|
||||
### 文件结构
|
||||
```
|
||||
src/views/Activities.vue # 活动页面主组件
|
||||
src/router/index.ts # 路由配置
|
||||
src/components/layout/AppHeader.vue # 导航栏更新
|
||||
```
|
||||
|
||||
### 核心技术
|
||||
- **Vue 3 Composition API**: 组件逻辑
|
||||
- **TypeScript**: 类型安全
|
||||
- **CSS Grid**: 响应式布局
|
||||
- **CSS Animations**: 动画效果
|
||||
- **Vue Router**: 路由导航
|
||||
|
||||
### 样式特点
|
||||
- **渐变背景**: 多层次视觉效果
|
||||
- **卡片设计**: 现代化卡片样式
|
||||
- **颜色系统**: 蓝色主题 + 橙色点缀
|
||||
- **字体层级**: 清晰的信息层次
|
||||
|
||||
## 🔗 导航集成
|
||||
|
||||
活动页面已集成到主导航栏中:
|
||||
- 导航项: "活动" (带NEW标签)
|
||||
- 路由路径: `/activities`
|
||||
- 页面标题: "全部活动 - 在线学习平台"
|
||||
|
||||
## 📱 响应式断点
|
||||
|
||||
```css
|
||||
/* 大屏幕 (>1024px) */
|
||||
.activities-grid { grid-template-columns: repeat(3, 1fr); }
|
||||
|
||||
/* 平板 (≤1024px) */
|
||||
.activities-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
|
||||
/* 手机 (≤768px) */
|
||||
.activities-grid { grid-template-columns: 1fr; }
|
||||
```
|
||||
|
||||
## 🎨 设计规范
|
||||
|
||||
### 颜色规范
|
||||
- **主色调**: #4A90E2 (蓝色)
|
||||
- **辅助色**: #44A08D (蓝绿色)
|
||||
- **强调色**: #FF6B35 (橙色)
|
||||
- **文字色**: #333 (深灰)
|
||||
- **次要文字**: #666 (中灰)
|
||||
|
||||
### 间距规范
|
||||
- **容器边距**: 20px (移动端) / 30px (桌面端)
|
||||
- **卡片间距**: 20px (移动端) / 30px (桌面端)
|
||||
- **内容边距**: 16px-24px
|
||||
|
||||
### 圆角规范
|
||||
- **卡片圆角**: 12px
|
||||
- **按钮圆角**: 6px
|
||||
- **标签圆角**: 4px
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
1. **访问页面**: 点击导航栏"活动"或直接访问 `/activities`
|
||||
2. **浏览活动**: 滚动查看所有可用活动
|
||||
3. **查看详情**: 点击"查看详情"按钮(当前为演示功能)
|
||||
4. **响应式体验**: 在不同设备上自动适配布局
|
||||
|
||||
## 📝 后续扩展
|
||||
|
||||
1. **图片集成**: 添加横幅插图和活动图片
|
||||
2. **数据接口**: 连接后端API获取真实活动数据
|
||||
3. **详情页面**: 实现活动详情页面跳转
|
||||
4. **筛选功能**: 添加活动分类和筛选功能
|
||||
5. **搜索功能**: 实现活动搜索功能
|
158
docs/Banner-Image-Setup.md
Normal file
158
docs/Banner-Image-Setup.md
Normal file
@ -0,0 +1,158 @@
|
||||
# 活动页面横幅图片设置指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
活动页面的横幅区域已经改为支持一整张图片的形式。目前显示占位内容,您可以按照以下步骤添加横幅图片。
|
||||
|
||||
## 🖼️ 当前状态
|
||||
|
||||
- ✅ 横幅区域已改为图片容器
|
||||
- ✅ 响应式设计已适配
|
||||
- ✅ 占位内容显示中
|
||||
- ⏳ 等待提供横幅图片
|
||||
|
||||
## 📐 图片规格建议
|
||||
|
||||
### 推荐尺寸
|
||||
- **桌面端**: 1200px × 400px
|
||||
- **平板端**: 1024px × 350px
|
||||
- **移动端**: 768px × 300px
|
||||
|
||||
### 文件格式
|
||||
- **推荐**: JPG/JPEG (文件小,加载快)
|
||||
- **支持**: PNG (支持透明背景)
|
||||
- **支持**: WebP (现代浏览器,更小文件)
|
||||
|
||||
### 文件大小
|
||||
- **建议**: < 500KB
|
||||
- **最大**: < 1MB
|
||||
|
||||
## 🚀 添加图片的方法
|
||||
|
||||
### 方法一:直接替换(推荐)
|
||||
|
||||
1. **将图片文件放到项目中**:
|
||||
```
|
||||
public/images/activities-banner.jpg
|
||||
```
|
||||
|
||||
2. **修改 Activities.vue 文件**:
|
||||
```typescript
|
||||
// 在 onMounted 中取消注释并设置图片路径
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 800)
|
||||
|
||||
// 设置横幅图片路径
|
||||
setBannerImage('/images/activities-banner.jpg')
|
||||
})
|
||||
```
|
||||
|
||||
### 方法二:直接设置变量
|
||||
|
||||
在 `src/views/Activities.vue` 中找到这一行:
|
||||
```typescript
|
||||
const bannerImageSrc = ref('')
|
||||
```
|
||||
|
||||
改为:
|
||||
```typescript
|
||||
const bannerImageSrc = ref('/images/activities-banner.jpg')
|
||||
```
|
||||
|
||||
## 📁 推荐的文件结构
|
||||
|
||||
```
|
||||
public/
|
||||
├── images/
|
||||
│ ├── activities-banner.jpg # 横幅图片
|
||||
│ ├── activities-banner-tablet.jpg # 平板版本(可选)
|
||||
│ └── activities-banner-mobile.jpg # 移动版本(可选)
|
||||
```
|
||||
|
||||
## 🎨 图片内容建议
|
||||
|
||||
根据原设计图,横幅图片应该包含:
|
||||
- 蓝色渐变背景
|
||||
- "理工/消安/药师/中经" 分类文字
|
||||
- "免费海量题库" 主标题
|
||||
- "小程序" 橙色标签
|
||||
- "优质试题 | 无需下载 | 随时刷题" 特色说明
|
||||
- 右侧人物和手机界面插图
|
||||
|
||||
## 🔧 技术实现细节
|
||||
|
||||
### 当前代码结构
|
||||
```vue
|
||||
<template>
|
||||
<div class="hero-banner">
|
||||
<div class="banner-image-container">
|
||||
<!-- 实际图片 -->
|
||||
<img
|
||||
v-if="hasBannerImage"
|
||||
:src="bannerImageSrc"
|
||||
alt="活动横幅"
|
||||
class="banner-image"
|
||||
/>
|
||||
<!-- 占位区域 -->
|
||||
<div v-else class="banner-placeholder">
|
||||
<!-- 占位内容 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 响应式适配
|
||||
- 桌面端:400px 高度
|
||||
- 平板端:350px 高度
|
||||
- 移动端:300px 高度
|
||||
- 小屏手机:250px 高度
|
||||
|
||||
### CSS 样式
|
||||
```css
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover; /* 保持比例,裁剪多余部分 */
|
||||
object-position: center; /* 居中显示 */
|
||||
}
|
||||
```
|
||||
|
||||
## ⚡ 性能优化建议
|
||||
|
||||
1. **图片压缩**: 使用工具压缩图片文件
|
||||
2. **懒加载**: 大图片可考虑懒加载
|
||||
3. **多尺寸**: 为不同设备提供不同尺寸的图片
|
||||
4. **WebP格式**: 现代浏览器使用WebP格式
|
||||
|
||||
## 🔄 更新步骤
|
||||
|
||||
当您准备好横幅图片时:
|
||||
|
||||
1. **准备图片文件**
|
||||
- 确保图片符合推荐规格
|
||||
- 压缩图片文件大小
|
||||
|
||||
2. **上传图片**
|
||||
- 将图片放到 `public/images/` 目录
|
||||
|
||||
3. **更新代码**
|
||||
- 按照上述方法一或方法二设置图片路径
|
||||
|
||||
4. **测试效果**
|
||||
- 刷新浏览器查看效果
|
||||
- 测试不同设备的显示效果
|
||||
|
||||
## 📞 需要帮助?
|
||||
|
||||
如果您在设置横幅图片时遇到任何问题,请:
|
||||
1. 检查图片路径是否正确
|
||||
2. 确认图片文件是否存在
|
||||
3. 查看浏览器控制台是否有错误信息
|
||||
4. 联系开发人员获取技术支持
|
||||
|
||||
---
|
||||
|
||||
**注意**: 当前页面显示占位内容,一旦您提供横幅图片并按照上述步骤设置,占位内容将自动被实际图片替换。
|
175
docs/Faculty-Banner-Setup.md
Normal file
175
docs/Faculty-Banner-Setup.md
Normal file
@ -0,0 +1,175 @@
|
||||
# 师资力量页面横幅图片设置指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
师资力量页面的横幅区域已经改为支持一整张图片的形式。目前显示占位内容,您可以按照以下步骤添加横幅图片。
|
||||
|
||||
## 🖼️ 当前状态
|
||||
|
||||
- ✅ 横幅区域已改为图片容器
|
||||
- ✅ 响应式设计已适配
|
||||
- ✅ 占位内容显示中
|
||||
- ⏳ 等待提供横幅图片
|
||||
|
||||
## 📐 图片规格建议
|
||||
|
||||
### 推荐尺寸
|
||||
- **桌面端**: 1200px × 400px
|
||||
- **平板端**: 1024px × 350px
|
||||
- **移动端**: 768px × 300px
|
||||
- **小屏手机**: 480px × 250px
|
||||
|
||||
### 文件格式
|
||||
- **推荐**: JPG/JPEG (文件小,加载快)
|
||||
- **支持**: PNG (支持透明背景)
|
||||
- **支持**: WebP (现代浏览器,更小文件)
|
||||
|
||||
### 文件大小
|
||||
- **建议**: < 500KB
|
||||
- **最大**: < 1MB
|
||||
|
||||
## 🚀 添加图片的方法
|
||||
|
||||
### 方法一:直接替换(推荐)
|
||||
|
||||
1. **将图片文件放到项目中**:
|
||||
```
|
||||
public/images/faculty-banner.jpg
|
||||
```
|
||||
|
||||
2. **修改 Faculty.vue 文件**:
|
||||
```typescript
|
||||
// 在文件开头找到这一行
|
||||
const bannerImageSrc = ref('')
|
||||
|
||||
// 改为
|
||||
const bannerImageSrc = ref('/images/faculty-banner.jpg')
|
||||
```
|
||||
|
||||
### 方法二:使用设置方法
|
||||
|
||||
在 `src/views/Faculty.vue` 中添加初始化代码:
|
||||
```typescript
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
|
||||
// 在组件挂载时设置图片
|
||||
onMounted(() => {
|
||||
setBannerImage('/images/faculty-banner.jpg')
|
||||
})
|
||||
```
|
||||
|
||||
## 📁 推荐的文件结构
|
||||
|
||||
```
|
||||
public/
|
||||
├── images/
|
||||
│ ├── faculty-banner.jpg # 师资力量横幅图片
|
||||
│ ├── faculty-banner-tablet.jpg # 平板版本(可选)
|
||||
│ └── faculty-banner-mobile.jpg # 移动版本(可选)
|
||||
```
|
||||
|
||||
## 🎨 图片内容建议
|
||||
|
||||
根据师资力量页面的特点,横幅图片应该包含:
|
||||
- 专业的教育背景或学术氛围
|
||||
- "师资力量"相关的标题文字
|
||||
- 可能包含教师形象或教学场景
|
||||
- 体现专业性和权威性的设计元素
|
||||
- 与整体网站风格保持一致的色调
|
||||
|
||||
## 🔧 技术实现细节
|
||||
|
||||
### 当前代码结构
|
||||
```vue
|
||||
<template>
|
||||
<div class="page-header">
|
||||
<div class="banner-image-container">
|
||||
<!-- 实际图片 -->
|
||||
<img
|
||||
v-if="hasBannerImage"
|
||||
:src="bannerImageSrc"
|
||||
alt="师资力量横幅"
|
||||
class="banner-image"
|
||||
/>
|
||||
<!-- 占位区域 -->
|
||||
<div v-else class="banner-placeholder">
|
||||
<!-- 占位内容 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 响应式适配
|
||||
- **桌面端**: 400px 高度
|
||||
- **平板端**: 350px 高度
|
||||
- **移动端**: 300px 高度
|
||||
- **小屏手机**: 250px 高度
|
||||
|
||||
### CSS 样式特点
|
||||
```css
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover; /* 保持比例,裁剪多余部分 */
|
||||
object-position: center; /* 居中显示 */
|
||||
}
|
||||
|
||||
.banner-placeholder {
|
||||
background: linear-gradient(135deg, #4A90E2 0%, #357ABD 100%);
|
||||
/* 蓝色渐变背景作为占位 */
|
||||
}
|
||||
```
|
||||
|
||||
## ⚡ 性能优化建议
|
||||
|
||||
1. **图片压缩**: 使用工具压缩图片文件
|
||||
2. **适当尺寸**: 避免使用过大的图片
|
||||
3. **格式选择**: 优先使用JPG格式
|
||||
4. **懒加载**: 大图片可考虑懒加载
|
||||
|
||||
## 🔄 更新步骤
|
||||
|
||||
当您准备好师资力量横幅图片时:
|
||||
|
||||
1. **准备图片文件**
|
||||
- 确保图片符合推荐规格
|
||||
- 压缩图片文件大小
|
||||
- 检查图片内容是否符合师资力量主题
|
||||
|
||||
2. **上传图片**
|
||||
- 将图片放到 `public/images/` 目录
|
||||
- 确保文件名清晰易懂
|
||||
|
||||
3. **更新代码**
|
||||
- 按照上述方法设置图片路径
|
||||
- 确保路径正确无误
|
||||
|
||||
4. **测试效果**
|
||||
- 访问 `/faculty` 页面查看效果
|
||||
- 测试不同设备的显示效果
|
||||
- 检查图片加载速度
|
||||
|
||||
## 🎯 与活动页面的区别
|
||||
|
||||
师资力量页面与活动页面的横幅设置方法相同,但内容主题不同:
|
||||
- **活动页面**: 侧重课程活动和学习资源
|
||||
- **师资力量页面**: 侧重教师团队和专业实力
|
||||
|
||||
## 📞 需要帮助?
|
||||
|
||||
如果您在设置师资力量横幅图片时遇到任何问题,请:
|
||||
1. 检查图片路径是否正确
|
||||
2. 确认图片文件是否存在于 `public/images/` 目录
|
||||
3. 查看浏览器控制台是否有错误信息
|
||||
4. 确保图片格式被浏览器支持
|
||||
5. 联系开发人员获取技术支持
|
||||
|
||||
## 🔗 相关页面
|
||||
|
||||
- [活动页面横幅设置指南](./Banner-Image-Setup.md)
|
||||
- [师资力量页面功能说明](./Faculty-Page.md)
|
||||
|
||||
---
|
||||
|
||||
**注意**: 当前页面显示占位内容,一旦您提供师资力量横幅图片并按照上述步骤设置,占位内容将自动被实际图片替换。页面访问地址:`http://localhost:3000/faculty`
|
@ -195,16 +195,13 @@ const handleMenuSelect = (key: string) => {
|
||||
router.push('/')
|
||||
break
|
||||
case 'faculty':
|
||||
// 暂时跳转到首页
|
||||
router.push('/')
|
||||
router.push('/faculty')
|
||||
break
|
||||
case 'resources':
|
||||
// 暂时跳转到首页
|
||||
router.push('/')
|
||||
router.push('/resources')
|
||||
break
|
||||
case 'activities':
|
||||
// 暂时跳转到首页
|
||||
router.push('/')
|
||||
router.push('/activities')
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,9 @@ import Profile from '@/views/Profile.vue'
|
||||
import Login from '@/views/Login.vue'
|
||||
import Register from '@/views/Register.vue'
|
||||
import LearningPaths from '@/views/LearningPaths.vue'
|
||||
import Faculty from '@/views/Faculty.vue'
|
||||
import Resources from '@/views/Resources.vue'
|
||||
import Activities from '@/views/Activities.vue'
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
@ -78,6 +81,30 @@ const routes: RouteRecordRaw[] = [
|
||||
title: '学习路径'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/faculty',
|
||||
name: 'Faculty',
|
||||
component: Faculty,
|
||||
meta: {
|
||||
title: '师资力量'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/resources',
|
||||
name: 'Resources',
|
||||
component: Resources,
|
||||
meta: {
|
||||
title: '精选资源'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/activities',
|
||||
name: 'Activities',
|
||||
component: Activities,
|
||||
meta: {
|
||||
title: '全部活动'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'NotFound',
|
||||
|
630
src/views/Activities.vue
Normal file
630
src/views/Activities.vue
Normal file
@ -0,0 +1,630 @@
|
||||
<template>
|
||||
<div class="activities-page">
|
||||
<!-- 横幅图片区域 -->
|
||||
<div class="hero-banner">
|
||||
<div class="banner-image-container">
|
||||
<!-- 实际图片 -->
|
||||
<img
|
||||
v-if="hasBannerImage"
|
||||
:src="bannerImageSrc"
|
||||
alt="活动横幅"
|
||||
class="banner-image"
|
||||
/>
|
||||
<!-- 图片占位区域 -->
|
||||
<div v-else class="banner-placeholder">
|
||||
<div class="placeholder-content">
|
||||
<div class="placeholder-icon">🖼️</div>
|
||||
<div class="placeholder-text">横幅图片占位</div>
|
||||
<div class="placeholder-desc">请提供横幅图片</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主要内容区域 -->
|
||||
<div class="main-content">
|
||||
<div class="container">
|
||||
<!-- 全部活动区域 -->
|
||||
<section class="all-activities">
|
||||
<h2 class="section-title">全部活动</h2>
|
||||
|
||||
<!-- 活动网格 -->
|
||||
<div v-if="loading" class="loading-grid">
|
||||
<div v-for="i in 6" :key="i" class="loading-card">
|
||||
<div class="loading-shimmer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="activities-grid">
|
||||
<div
|
||||
v-for="activity in activities"
|
||||
:key="activity.id"
|
||||
class="activity-card"
|
||||
>
|
||||
<div class="card-header">
|
||||
<div class="card-background">
|
||||
<div class="year-badge">2025</div>
|
||||
<div class="course-title">{{ activity.title }}</div>
|
||||
<div class="course-subtitle">{{ activity.subtitle }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<!-- 特色标签 -->
|
||||
<div class="feature-tags">
|
||||
<span
|
||||
v-for="tag in activity.tags"
|
||||
:key="tag"
|
||||
class="feature-tag"
|
||||
>
|
||||
<i class="tag-icon">✓</i>
|
||||
{{ tag }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 课程信息 -->
|
||||
<div class="course-info">
|
||||
<div class="info-row">
|
||||
<span class="info-label">{{ activity.courseTitle }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-text">{{ activity.schedule }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-text">{{ activity.duration }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-text">{{ activity.students }}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="price">{{ activity.price }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 查看详情按钮 -->
|
||||
<div class="card-footer">
|
||||
<button class="detail-btn" @click="viewDetail(activity.id)">
|
||||
查看详情
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(true)
|
||||
|
||||
// 横幅图片路径 - 您可以在这里设置图片路径
|
||||
const bannerImageSrc = ref('')
|
||||
|
||||
// 检查是否有横幅图片
|
||||
const hasBannerImage = computed(() => bannerImageSrc.value.trim() !== '')
|
||||
|
||||
// 活动数据
|
||||
const activities = ref([
|
||||
{
|
||||
id: 1,
|
||||
title: '计算机二级',
|
||||
subtitle: 'C语言讲练综合班',
|
||||
tags: ['系统备考', '考点详解', '题考刷题'],
|
||||
courseTitle: '计算机二级C语言程序设计证书',
|
||||
schedule: '开课时间:2025.07.26-2025.09.28',
|
||||
duration: '适合年级:高校本科生',
|
||||
students: '已报名:1468/2000',
|
||||
price: '免费'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '计算机二级',
|
||||
subtitle: 'C语言讲练综合班',
|
||||
tags: ['系统备考', '考点详解', '题考刷题'],
|
||||
courseTitle: '计算机二级C语言程序设计证书',
|
||||
schedule: '开课时间:2025.07.26-2025.09.28',
|
||||
duration: '适合年级:高校本科生',
|
||||
students: '已报名:1468/2000',
|
||||
price: '免费'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '计算机二级',
|
||||
subtitle: 'C语言讲练综合班',
|
||||
tags: ['系统备考', '考点详解', '题考刷题'],
|
||||
courseTitle: '计算机二级C语言程序设计证书',
|
||||
schedule: '开课时间:2025.07.26-2025.09.28',
|
||||
duration: '适合年级:高校本科生',
|
||||
students: '已报名:1468/2000',
|
||||
price: '免费'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: '计算机二级',
|
||||
subtitle: 'C语言讲练综合班',
|
||||
tags: ['系统备考', '考点详解', '题考刷题'],
|
||||
courseTitle: '计算机二级C语言程序设计证书',
|
||||
schedule: '开课时间:2025.07.26-2025.09.28',
|
||||
duration: '适合年级:高校本科生',
|
||||
students: '已报名:1468/2000',
|
||||
price: '免费'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: '计算机二级',
|
||||
subtitle: 'C语言讲练综合班',
|
||||
tags: ['系统备考', '考点详解', '题考刷题'],
|
||||
courseTitle: '计算机二级C语言程序设计证书',
|
||||
schedule: '开课时间:2025.07.26-2025.09.28',
|
||||
duration: '适合年级:高校本科生',
|
||||
students: '已报名:1468/2000',
|
||||
price: '免费'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: '计算机二级',
|
||||
subtitle: 'C语言讲练综合班',
|
||||
tags: ['系统备考', '考点详解', '题考刷题'],
|
||||
courseTitle: '计算机二级C语言程序设计证书',
|
||||
schedule: '开课时间:2025.07.26-2025.09.28',
|
||||
duration: '适合年级:高校本科生',
|
||||
students: '已报名:1468/2000',
|
||||
price: '免费'
|
||||
}
|
||||
])
|
||||
|
||||
// 查看详情
|
||||
const viewDetail = (id: number) => {
|
||||
console.log('查看活动详情:', id)
|
||||
// 这里可以跳转到活动详情页面
|
||||
// router.push(`/activity/${id}`)
|
||||
}
|
||||
|
||||
// 设置横幅图片的方法(供后续使用)
|
||||
const setBannerImage = (imagePath: string) => {
|
||||
bannerImageSrc.value = imagePath
|
||||
}
|
||||
|
||||
// 模拟数据加载
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 800)
|
||||
|
||||
// 示例:如果您有图片路径,可以在这里设置
|
||||
// setBannerImage('/images/activities-banner.jpg')
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.activities-page {
|
||||
min-height: 100vh;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
/* 横幅图片区域 */
|
||||
.hero-banner {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.banner-image-container {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
.banner-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #4A90E2 0%, #357ABD 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.banner-placeholder::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.placeholder-content {
|
||||
text-align: center;
|
||||
color: white;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.placeholder-desc {
|
||||
font-size: 16px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
/* 主要内容区域 */
|
||||
.main-content {
|
||||
padding: 80px 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
margin: 0 0 50px 0;
|
||||
}
|
||||
|
||||
/* 活动网格 */
|
||||
.activities-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.activity-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.activity-card:hover {
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
/* 卡片头部 */
|
||||
.card-header {
|
||||
position: relative;
|
||||
height: 120px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-background {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #4ECDC4 0%, #44A08D 100%);
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-background::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
transform: translate(30px, -30px);
|
||||
}
|
||||
|
||||
.card-background::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 50%;
|
||||
transform: translate(-20px, 20px);
|
||||
}
|
||||
|
||||
.year-badge {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 20px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
color: #44A08D;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.course-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.course-subtitle {
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 卡片主体 */
|
||||
.card-body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.feature-tags {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.feature-tag {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
background: #FFF2E6;
|
||||
color: #FF6B35;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tag-icon {
|
||||
font-size: 10px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.course-info {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
margin-bottom: 8px;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.info-row:first-child {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: #FF6B35;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 卡片底部 */
|
||||
.card-footer {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.detail-btn {
|
||||
width: 100%;
|
||||
padding: 10px 20px;
|
||||
background: #4A90E2;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.detail-btn:hover {
|
||||
background: #357ABD;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.loading-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
.loading-shimmer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
#f0f0f0 25%,
|
||||
#e0e0e0 50%,
|
||||
#f0f0f0 75%
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-50px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInRight {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(50px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.banner-image-container {
|
||||
animation: fadeInUp 0.8s ease-out;
|
||||
}
|
||||
|
||||
.activity-card {
|
||||
animation: fadeInUp 0.6s ease-out;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.activity-card:nth-child(1) { animation-delay: 0.1s; }
|
||||
.activity-card:nth-child(2) { animation-delay: 0.2s; }
|
||||
.activity-card:nth-child(3) { animation-delay: 0.3s; }
|
||||
.activity-card:nth-child(4) { animation-delay: 0.4s; }
|
||||
.activity-card:nth-child(5) { animation-delay: 0.5s; }
|
||||
.activity-card:nth-child(6) { animation-delay: 0.6s; }
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 1024px) {
|
||||
.activities-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.banner-image-container {
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.activities-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.banner-image-container {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.placeholder-desc {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 40px 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.banner-image-container {
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.placeholder-desc {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.feature-tags {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
File diff suppressed because it is too large
Load Diff
606
src/views/Faculty.vue
Normal file
606
src/views/Faculty.vue
Normal file
@ -0,0 +1,606 @@
|
||||
<template>
|
||||
<div class="faculty-page">
|
||||
<!-- 横幅图片区域 -->
|
||||
<div class="page-header">
|
||||
<div class="banner-image-container">
|
||||
<!-- 实际图片 -->
|
||||
<img
|
||||
v-if="hasBannerImage"
|
||||
:src="bannerImageSrc"
|
||||
alt="师资力量横幅"
|
||||
class="banner-image"
|
||||
/>
|
||||
<!-- 图片占位区域 -->
|
||||
<div v-else class="banner-placeholder">
|
||||
<div class="placeholder-content">
|
||||
<div class="placeholder-icon">🖼️</div>
|
||||
<div class="placeholder-text">师资力量横幅图片占位</div>
|
||||
<div class="placeholder-desc">请提供横幅图片</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主要内容区域 -->
|
||||
<div class="main-content">
|
||||
<div class="container">
|
||||
<!-- 筛选标签栏 -->
|
||||
<div class="filter-tabs">
|
||||
<button
|
||||
v-for="tab in filterTabs"
|
||||
:key="tab.id"
|
||||
:class="['filter-tab', { active: activeTab === tab.id }]"
|
||||
@click="activeTab = tab.id"
|
||||
>
|
||||
{{ tab.name }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 师资卡片网格 -->
|
||||
<div class="faculty-grid">
|
||||
<div
|
||||
v-for="teacher in paginatedTeachers"
|
||||
:key="teacher.id"
|
||||
class="faculty-card"
|
||||
>
|
||||
<div class="card-header">
|
||||
<div class="avatar-container">
|
||||
<!-- 头像占位 -->
|
||||
<div class="avatar-placeholder"></div>
|
||||
<div v-if="teacher.featured" class="featured-badge">金牌讲师</div>
|
||||
</div>
|
||||
<div class="card-arrow">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M6 4L10 8L6 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<h3 class="teacher-name">{{ teacher.name }}</h3>
|
||||
<p class="teacher-title">{{ teacher.title }}</p>
|
||||
<p class="teacher-description">{{ teacher.description }}</p>
|
||||
<div class="teacher-tags">
|
||||
<span v-for="tag in teacher.tags" :key="tag" class="tag">{{ tag }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页组件 -->
|
||||
<div class="pagination">
|
||||
<button class="page-btn" :disabled="currentPage === 1" @click="goToPage(currentPage - 1)">
|
||||
上一页
|
||||
</button>
|
||||
<button
|
||||
v-for="page in visiblePages"
|
||||
:key="page"
|
||||
:class="['page-btn', { active: currentPage === page }]"
|
||||
@click="typeof page === 'number' ? goToPage(page) : null"
|
||||
:disabled="typeof page !== 'number'"
|
||||
>
|
||||
{{ page }}
|
||||
</button>
|
||||
<button class="page-btn" :disabled="currentPage === totalPages" @click="goToPage(currentPage + 1)">
|
||||
下一页
|
||||
</button>
|
||||
<span class="page-info">共{{ totalPages }}页</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
// 横幅图片相关
|
||||
const bannerImageSrc = ref('')
|
||||
const hasBannerImage = computed(() => bannerImageSrc.value.trim() !== '')
|
||||
|
||||
// 设置横幅图片的方法(供后续使用)
|
||||
const setBannerImage = (imagePath: string) => {
|
||||
bannerImageSrc.value = imagePath
|
||||
}
|
||||
|
||||
// 筛选标签数据
|
||||
const filterTabs = ref([
|
||||
{ id: 'all', name: '全部讲师' },
|
||||
{ id: 'main', name: '主讲' },
|
||||
{ id: 'international', name: '注册国际讲师' },
|
||||
{ id: 'consultant', name: '咨询师' },
|
||||
{ id: 'expert', name: '专家顾问' },
|
||||
{ id: 'senior', name: '资深讲师' },
|
||||
{ id: 'featured', name: '金牌讲师' },
|
||||
{ id: 'enterprise', name: '企业导师' }
|
||||
])
|
||||
|
||||
const activeTab = ref('all')
|
||||
|
||||
// 师资数据
|
||||
const teachers = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '黄天羽',
|
||||
title: '注册国际人才测评师资格认证',
|
||||
description: '注册国际企业学习设计师 认证',
|
||||
tags: ['主讲', '资深人才测评师'],
|
||||
featured: true
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '蓝天',
|
||||
title: '北京理工大学MBA企业文化专家顾问',
|
||||
description: '多家知名上市企业高管',
|
||||
tags: ['主讲', 'MBA企业文化专家']
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '万精云',
|
||||
title: '中国人事科学',
|
||||
description: '中国科学院博士',
|
||||
tags: ['主讲', '人事专家']
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '张庆勋',
|
||||
title: '北京大学博士',
|
||||
description: '内蒙古财经大学',
|
||||
tags: ['主讲', '金牌讲师']
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '程毅',
|
||||
title: '中国科技大学博士研究生',
|
||||
description: '',
|
||||
tags: ['主讲', '科技专家']
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: '王德华',
|
||||
title: '数字经济与金融研究中心专家',
|
||||
description: '多家知名上市企业高级管理顾问',
|
||||
tags: ['主讲', '数字经济专家']
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: '马前程',
|
||||
title: '清华大学管理学院',
|
||||
description: '多家一线互联网企业高级管理顾问',
|
||||
tags: ['主讲', '清华大学管理专家']
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: '陈宇',
|
||||
title: '知名上市企业高级管理顾问专家',
|
||||
description: '多家一线互联网企业高级管理顾问',
|
||||
tags: ['主讲', '企业管理专家']
|
||||
}
|
||||
])
|
||||
|
||||
// 分页相关
|
||||
const currentPage = ref(1)
|
||||
const pageSize = 8
|
||||
const totalPages = computed(() => Math.ceil(teachers.value.length / pageSize))
|
||||
|
||||
const paginatedTeachers = computed(() => {
|
||||
const start = (currentPage.value - 1) * pageSize
|
||||
const end = start + pageSize
|
||||
return teachers.value.slice(start, end)
|
||||
})
|
||||
|
||||
const visiblePages = computed(() => {
|
||||
const pages = []
|
||||
const total = totalPages.value
|
||||
const current = currentPage.value
|
||||
|
||||
if (total <= 7) {
|
||||
for (let i = 1; i <= total; i++) {
|
||||
pages.push(i)
|
||||
}
|
||||
} else {
|
||||
if (current <= 4) {
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
pages.push(i)
|
||||
}
|
||||
pages.push('...')
|
||||
pages.push(total)
|
||||
} else if (current >= total - 3) {
|
||||
pages.push(1)
|
||||
pages.push('...')
|
||||
for (let i = total - 4; i <= total; i++) {
|
||||
pages.push(i)
|
||||
}
|
||||
} else {
|
||||
pages.push(1)
|
||||
pages.push('...')
|
||||
for (let i = current - 1; i <= current + 1; i++) {
|
||||
pages.push(i)
|
||||
}
|
||||
pages.push('...')
|
||||
pages.push(total)
|
||||
}
|
||||
}
|
||||
|
||||
return pages
|
||||
})
|
||||
|
||||
const goToPage = (page: number) => {
|
||||
if (page >= 1 && page <= totalPages.value) {
|
||||
currentPage.value = page
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.faculty-page {
|
||||
min-height: 100vh;
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
/* 横幅图片区域 */
|
||||
.page-header {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.banner-image-container {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
.banner-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #4A90E2 0%, #357ABD 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.banner-placeholder::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.placeholder-content {
|
||||
text-align: center;
|
||||
color: white;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.placeholder-desc {
|
||||
font-size: 16px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
/* 主要内容区域 */
|
||||
.main-content {
|
||||
padding: 40px 0 80px;
|
||||
}
|
||||
|
||||
/* 筛选标签栏 */
|
||||
.filter-tabs {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
margin-bottom: 40px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.filter-tab {
|
||||
padding: 12px 24px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: all 0.3s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-tab:hover {
|
||||
background: #f8f9fa;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.filter-tab.active {
|
||||
background: #4A90E2;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 师资卡片网格 */
|
||||
.faculty-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 24px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.faculty-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.faculty-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
position: relative;
|
||||
height: 200px;
|
||||
background: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #e0e0e0 0%, #f0f0f0 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.avatar-placeholder::after {
|
||||
content: '头像占位';
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.featured-badge {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
background: #FF6B35;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.card-arrow {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 16px;
|
||||
transform: translateY(-50%);
|
||||
color: #4A90E2;
|
||||
background: white;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.teacher-name {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0 0 8px 0;
|
||||
}
|
||||
|
||||
.teacher-title {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin: 0 0 8px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.teacher-description {
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
margin: 0 0 12px 0;
|
||||
line-height: 1.4;
|
||||
min-height: 18px;
|
||||
}
|
||||
|
||||
.teacher-tags {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
background: #f0f8ff;
|
||||
color: #4A90E2;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
border: 1px solid #e6f3ff;
|
||||
}
|
||||
|
||||
/* 分页组件 */
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.page-btn {
|
||||
padding: 8px 16px;
|
||||
border: 1px solid #ddd;
|
||||
background: white;
|
||||
color: #666;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s;
|
||||
min-width: 40px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.page-btn:hover:not(:disabled) {
|
||||
background: #f8f9fa;
|
||||
border-color: #4A90E2;
|
||||
color: #4A90E2;
|
||||
}
|
||||
|
||||
.page-btn.active {
|
||||
background: #4A90E2;
|
||||
border-color: #4A90E2;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.page-btn:disabled {
|
||||
background: #f5f5f5;
|
||||
color: #ccc;
|
||||
cursor: not-allowed;
|
||||
border-color: #eee;
|
||||
}
|
||||
|
||||
.page-info {
|
||||
margin-left: 16px;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 1200px) {
|
||||
.faculty-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.banner-image-container {
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.faculty-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.filter-tabs {
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.filter-tab {
|
||||
padding: 8px 16px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.banner-image-container {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.placeholder-desc {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.faculty-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 20px 0 40px;
|
||||
}
|
||||
|
||||
.banner-image-container {
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.placeholder-icon {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.placeholder-desc {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
610
src/views/Resources.vue
Normal file
610
src/views/Resources.vue
Normal file
@ -0,0 +1,610 @@
|
||||
<template>
|
||||
<div class="resources-page">
|
||||
<!-- 轮播图区域 -->
|
||||
<div class="banner-section">
|
||||
<div class="banner-container">
|
||||
<div class="banner-slide active">
|
||||
<div class="banner-image">
|
||||
<!-- 轮播图占位 -->
|
||||
<div class="banner-placeholder"></div>
|
||||
</div>
|
||||
<div class="banner-content">
|
||||
<h2 class="banner-title">海量资源聚合,您的一站式数字资源库</h2>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 轮播指示器 -->
|
||||
<div class="banner-indicators">
|
||||
<span class="indicator active"></span>
|
||||
<span class="indicator"></span>
|
||||
<span class="indicator"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主要内容区域 -->
|
||||
<div class="main-content">
|
||||
<div class="container">
|
||||
<!-- 精选视频区域 -->
|
||||
<section class="featured-videos">
|
||||
<h2 class="section-title">精选视频</h2>
|
||||
<div class="featured-grid">
|
||||
<div
|
||||
v-for="video in featuredVideos"
|
||||
:key="video.id"
|
||||
class="featured-card"
|
||||
>
|
||||
<div class="card-image">
|
||||
<div class="image-placeholder"></div>
|
||||
<div class="play-button">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M8 5V19L19 12L8 5Z" fill="white"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<h3 class="card-title">{{ video.title }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 全部视频区域 -->
|
||||
<section class="all-videos">
|
||||
<h2 class="section-title">全部视频</h2>
|
||||
<!-- 筛选标签 -->
|
||||
<div class="filter-tabs">
|
||||
<button
|
||||
v-for="tab in videoTabs"
|
||||
:key="tab.id"
|
||||
:class="['filter-tab', { active: activeVideoTab === tab.id }]"
|
||||
@click="activeVideoTab = tab.id"
|
||||
>
|
||||
{{ tab.name }}
|
||||
</button>
|
||||
</div>
|
||||
<!-- 视频网格 -->
|
||||
<div class="video-grid">
|
||||
<div
|
||||
v-for="video in allVideos"
|
||||
:key="video.id"
|
||||
class="video-card"
|
||||
>
|
||||
<div class="card-image">
|
||||
<div class="image-placeholder"></div>
|
||||
<div class="play-button">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M8 5V19L19 12L8 5Z" fill="white"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<h3 class="card-title">{{ video.title }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="load-more">
|
||||
<button class="load-more-btn">查看更多</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 全部图片区域 -->
|
||||
<section class="all-images">
|
||||
<h2 class="section-title">全部图片</h2>
|
||||
<!-- 筛选标签 -->
|
||||
<div class="filter-tabs">
|
||||
<button
|
||||
v-for="tab in imageTabs"
|
||||
:key="tab.id"
|
||||
:class="['filter-tab', { active: activeImageTab === tab.id }]"
|
||||
@click="activeImageTab = tab.id"
|
||||
>
|
||||
{{ tab.name }}
|
||||
</button>
|
||||
</div>
|
||||
<!-- 图片网格 -->
|
||||
<div class="image-grid">
|
||||
<div
|
||||
v-for="image in allImages"
|
||||
:key="image.id"
|
||||
class="image-card"
|
||||
>
|
||||
<div class="card-image">
|
||||
<div class="image-placeholder"></div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<h3 class="card-title">{{ image.title }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="load-more">
|
||||
<button class="load-more-btn">查看更多</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 精选视频数据
|
||||
const featuredVideos = ref([
|
||||
{ id: 1, title: '西安工业大学内部资源之一' },
|
||||
{ id: 2, title: '华南工业大学内部资源之一' },
|
||||
{ id: 3, title: '西安工业大学内部资源之一' }
|
||||
])
|
||||
|
||||
// 视频筛选标签
|
||||
const videoTabs = ref([
|
||||
{ id: 'all', name: '全部' },
|
||||
{ id: 'educational', name: '中小学教育资源' },
|
||||
{ id: 'training', name: '师资培训' },
|
||||
{ id: 'technology', name: '技术资源' },
|
||||
{ id: 'management', name: '管理资源' }
|
||||
])
|
||||
|
||||
const activeVideoTab = ref('all')
|
||||
|
||||
// 全部视频数据
|
||||
const allVideos = ref([
|
||||
{ id: 1, title: '北京工业大学内部资源之一' },
|
||||
{ id: 2, title: '北京工业大学内部资源之一' },
|
||||
{ id: 3, title: '西安工业大学内部资源之一' },
|
||||
{ id: 4, title: '北京工业大学内部资源之一' },
|
||||
{ id: 5, title: '中国工业大学内部资源之一' },
|
||||
{ id: 6, title: '西安工业大学内部资源之一' },
|
||||
{ id: 7, title: '西安工业大学内部资源之一' },
|
||||
{ id: 8, title: '内蒙古工业大学内部资源之一' }
|
||||
])
|
||||
|
||||
// 图片筛选标签
|
||||
const imageTabs = ref([
|
||||
{ id: 'all', name: '全部' },
|
||||
{ id: 'educational', name: '中小学教育资源' },
|
||||
{ id: 'training', name: '师资培训' },
|
||||
{ id: 'technology', name: '技术资源' },
|
||||
{ id: 'management', name: '管理资源' }
|
||||
])
|
||||
|
||||
const activeImageTab = ref('all')
|
||||
|
||||
// 全部图片数据
|
||||
const allImages = ref([
|
||||
{ id: 1, title: '中国工业大学内部资源之一' },
|
||||
{ id: 2, title: '西安工业大学内部资源之一' },
|
||||
{ id: 3, title: '西安工业大学内部资源之一' },
|
||||
{ id: 4, title: '内蒙古工业大学内部资源之一' },
|
||||
{ id: 5, title: '北京工业大学内部资源之一' },
|
||||
{ id: 6, title: '北京工业大学内部资源之一' },
|
||||
{ id: 7, title: '西安工业大学内部资源之一' },
|
||||
{ id: 8, title: '内蒙古工业大学内部资源之一' }
|
||||
])
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.resources-page {
|
||||
min-height: 100vh;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
/* 轮播图区域 */
|
||||
.banner-section {
|
||||
position: relative;
|
||||
height: 400px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.banner-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.banner-slide {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.banner-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.banner-placeholder::after {
|
||||
content: '轮播图占位';
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.banner-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
text-align: center;
|
||||
color: white;
|
||||
max-width: 800px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.banner-indicators {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.indicator.active {
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* 主要内容区域 */
|
||||
.main-content {
|
||||
padding: 60px 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0 0 30px 0;
|
||||
}
|
||||
|
||||
/* 精选视频区域 */
|
||||
.featured-videos {
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
.featured-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.featured-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.featured-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.card-image {
|
||||
position: relative;
|
||||
height: 180px;
|
||||
background: #f5f5f5;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.image-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #e0e0e0 0%, #f0f0f0 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.image-placeholder::after {
|
||||
content: '图片占位';
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.play-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.play-button:hover {
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
transform: translate(-50%, -50%) scale(1.1);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 筛选标签 */
|
||||
.filter-tabs {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
margin-bottom: 30px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 4px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.filter-tab {
|
||||
padding: 8px 20px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: all 0.3s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-tab:hover {
|
||||
background: #f8f9fa;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.filter-tab.active {
|
||||
background: #4A90E2;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 全部视频区域 */
|
||||
.all-videos {
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
.video-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.video-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.video-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.video-card .card-image {
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
.video-card .play-button {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
/* 全部图片区域 */
|
||||
.all-images {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.image-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.image-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.image-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.image-card .card-image {
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
/* 查看更多按钮 */
|
||||
.load-more {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.load-more-btn {
|
||||
padding: 12px 32px;
|
||||
background: white;
|
||||
border: 1px solid #ddd;
|
||||
color: #666;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.load-more-btn:hover {
|
||||
background: #f8f9fa;
|
||||
border-color: #4A90E2;
|
||||
color: #4A90E2;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 1024px) {
|
||||
.container {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.featured-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.video-grid,
|
||||
.image-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.banner-section {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 40px 0;
|
||||
}
|
||||
|
||||
.featured-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.video-grid,
|
||||
.image-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.filter-tabs {
|
||||
overflow-x: auto;
|
||||
padding: 4px;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.filter-tab {
|
||||
padding: 6px 16px;
|
||||
font-size: 13px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.featured-videos,
|
||||
.all-videos {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.banner-section {
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
font-size: 20px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.video-grid,
|
||||
.image-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.card-image {
|
||||
height: 160px;
|
||||
}
|
||||
|
||||
.video-card .card-image,
|
||||
.image-card .card-image {
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.filter-tabs {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.filter-tab {
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user