This commit is contained in:
zly
2025-11-23 17:45:04 +08:00
parent 929b96feeb
commit 9bdc52b2dd
4 changed files with 474 additions and 0 deletions

202
web/group-site/README.md Normal file
View File

@@ -0,0 +1,202 @@
# 科研课题组展示网站
## 📍 访问地址
```
https://amiap.hzau.edu.cn/group/
```
## 🎨 Vue 项目配置(重要!)
### 1. Vue Router 配置
```javascript
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
// ⚠️ 重要base 设置为 /group/
history: createWebHistory('/group/'),
routes: [
{
path: '/', // 实际访问: https://amiap.hzau.edu.cn/group/
name: 'Home',
component: () => import('@/views/Home.vue')
},
{
path: '/members', // 实际访问: https://amiap.hzau.edu.cn/group/members
name: 'Members',
component: () => import('@/views/Members.vue')
}
]
})
export default router
```
### 2. Vite 配置
```javascript
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
// ⚠️ 重要base 设置为 /group/
base: '/group/',
build: {
outDir: 'dist',
assetsDir: 'assets'
}
})
```
### 3. Vue CLI 配置(如果使用 Vue CLI
```javascript
// vue.config.js
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/group/' : '/',
outputDir: 'dist'
}
```
## 🚀 部署步骤
### 1. 构建 Vue 项目
```bash
# 在你的 Vue 项目根目录
cd your-vue-project
# 确保已配置 base: '/group/'
# 然后构建
npm run build
# 或
pnpm build
```
### 2. 复制构建产物
```bash
# 复制 dist 目录到部署位置
cp -r dist /vol1/1000/docker_server/traefik/web/group-site/
```
### 3. 启动服务
```bash
cd /vol1/1000/docker_server/traefik/web/group-site
# 启动
docker compose up -d
# 查看日志
docker compose logs -f
```
### 4. 访问网站
```
https://amiap.hzau.edu.cn/group/
```
## 📊 完整路由规划
```
https://amiap.hzau.edu.cn/
├── / → MinIO S3 API + 控制台(根路径)
│ ├── /stub/ → S3 bucket 访问
│ ├── /api/v1/ → MinIO Console API
│ └── /static/ → MinIO Console 静态资源
├── /group/ → 科研课题组网站(你的 Vue 项目)
│ ├── /group/ → 首页
│ ├── /group/members → 成员介绍
│ ├── /group/research → 研究方向
│ └── /group/... → 其他页面
├── /supa/ → Supabase API
└── /ABM/ → ABM 数据库
```
## 🔧 开发调试
### 本地开发
```bash
# 在 Vue 项目中本地运行
npm run dev
# Vite 会自动处理 /group/ base path
# 访问: http://localhost:5173/group/
```
### 生产环境测试
```bash
# 构建生产版本
npm run build
# 预览
npm run preview
# 访问: http://localhost:4173/group/
```
## <20><> 示例项目结构
```javascript
// App.vue
<template>
<div id="app">
<nav>
<\!-- 路由链接会自动加上 /group/ 前缀 -->
<router-link to="/">首页</router-link>
<router-link to="/members">团队成员</router-link>
<router-link to="/research">研究方向</router-link>
</nav>
<router-view />
</div>
</template>
// 图片引用示例
<template>
<img src="@/assets/logo.png" alt="Logo">
<\!-- Vite 会自动处理为: /group/assets/logo-xxx.png -->
</template>
```
## ⚠️ 常见问题
### Q: 刷新页面出现 404
A: 已在 nginx.conf 中配置 `try_files`,支持 Vue Router History 模式
### Q: 静态资源加载失败
A: 确保 Vite/Vue CLI 配置了正确的 `base: '/group/'`
### Q: 路由跳转到根路径
A: 检查 Vue Router 的 `history: createWebHistory('/group/')`
### Q: API 请求路径错误
A: 使用绝对路径或相对路径,例如:
```javascript
// 调用 Supabase API
fetch('https://amiap.hzau.edu.cn/supa/rest/v1/...')
// 或使用环境变量
const API_BASE = import.meta.env.VITE_API_URL
```
## 🔗 相关资源
- [Vue Router Base 配置](https://router.vuejs.org/guide/essentials/history-mode.html#html5-mode)
- [Vite Base 配置](https://vitejs.dev/config/shared-options.html#base)
- [主项目文档](../../README.md)
---
**部署路径**: `/group/`
**优先级**: 80高于 MinIO S3 的 50
**维护者**: Lab Admin

203
web/group-site/dist/index.html vendored Executable file
View File

@@ -0,0 +1,203 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>实验室服务导航 - HZAU Lab</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
}
.container {
background: rgba(255, 255, 255, 0.95);
border-radius: 24px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
padding: 3rem;
max-width: 800px;
width: 100%;
}
.header {
text-align: center;
margin-bottom: 3rem;
}
.header h1 {
font-size: 2.5rem;
color: #2d3748;
margin-bottom: 0.5rem;
}
.header p {
color: #718096;
font-size: 1.1rem;
}
.services {
display: grid;
gap: 1.5rem;
margin-bottom: 2rem;
}
.service-card {
display: flex;
align-items: center;
padding: 1.5rem;
background: white;
border-radius: 16px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.07);
transition: all 0.3s ease;
text-decoration: none;
border: 2px solid transparent;
}
.service-card:hover {
transform: translateY(-4px);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
border-color: #667eea;
}
.service-icon {
width: 60px;
height: 60px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
margin-right: 1.5rem;
flex-shrink: 0;
}
.icon-minio { background: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%); }
.icon-supabase { background: linear-gradient(135deg, #3ecf8e 0%, #2eb77a 100%); }
.icon-abm { background: linear-gradient(135deg, #4facfe 0%, #00a8ff 100%); }
.service-info {
flex: 1;
}
.service-info h3 {
font-size: 1.3rem;
color: #2d3748;
margin-bottom: 0.3rem;
}
.service-info p {
color: #718096;
font-size: 0.95rem;
}
.service-badge {
padding: 0.25rem 0.75rem;
border-radius: 12px;
font-size: 0.75rem;
font-weight: 600;
margin-left: 1rem;
}
.badge-internal {
background: #fef5e7;
color: #d68910;
}
.badge-public {
background: #eaf7f0;
color: #27ae60;
}
.footer {
text-align: center;
padding-top: 2rem;
border-top: 1px solid #e2e8f0;
color: #a0aec0;
font-size: 0.9rem;
}
.footer strong {
color: #667eea;
}
@media (max-width: 600px) {
.container {
padding: 2rem;
}
.header h1 {
font-size: 2rem;
}
.service-card {
padding: 1.25rem;
}
.service-icon {
width: 50px;
height: 50px;
font-size: 1.5rem;
margin-right: 1rem;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🔬 实验室服务导航</h1>
<p>华中农业大学 · Lab Services Portal</p>
</div>
<div class="services">
<!-- MinIO 对象存储 -->
<a href="http://100.64.0.2:9001" class="service-card" target="_blank">
<div class="service-icon icon-minio">📦</div>
<div class="service-info">
<h3>MinIO 对象存储</h3>
<p>S3 兼容对象存储管理控制台</p>
</div>
<span class="service-badge badge-internal">内网访问</span>
</a>
<!-- Supabase Dashboard -->
<a href="http://100.64.0.2:18000" class="service-card" target="_blank">
<div class="service-icon icon-supabase">🗄️</div>
<div class="service-info">
<h3>Supabase Dashboard</h3>
<p>数据库管理和 API 配置面板</p>
</div>
<span class="service-badge badge-internal">内网访问</span>
</a>
<!-- ABM 数据库 -->
<a href="https://amiap.hzau.edu.cn/ABM/" class="service-card" target="_blank">
<div class="service-icon icon-abm">🌐</div>
<div class="service-info">
<h3>ABM 数据库</h3>
<p>WebSocket 实时数据服务</p>
</div>
<span class="service-badge badge-public">公网访问</span>
</a>
</div>
<div class="footer">
<p>⚠️ 这是临时导航页面</p>
<p style="margin-top: 0.5rem;">
后续将替换为 <strong>Vue 课题组网站</strong>
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,39 @@
# Vue 科研课题组展示网站
# 部署路径https://amiap.hzau.edu.cn/group/
services:
group-site:
image: nginx:alpine
container_name: group-site
volumes:
# Vue 构建产物
- ./dist:/usr/share/nginx/html:ro
# Nginx 配置
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- frontend
labels:
- "traefik.enable=true"
# ======================================
# 课题组网站路由 - /group/ 子路径
# ======================================
- "traefik.http.routers.group-site.rule=Host(`amiap.hzau.edu.cn`) && PathPrefix(`/group`)"
- "traefik.http.routers.group-site.priority=80" # 高于 MinIO S3 (50)
- "traefik.http.routers.group-site.entrypoints=websecure"
- "traefik.http.routers.group-site.tls.certresolver=myresolver"
# StripPrefix 中间件 - 去除 /group 前缀
- "traefik.http.middlewares.group-stripprefix.stripprefix.prefixes=/group"
# 压缩中间件
- "traefik.http.middlewares.group-compress.compress=true"
# 应用中间件
- "traefik.http.routers.group-site.middlewares=group-stripprefix,group-compress"
- "traefik.http.services.group-site-svc.loadbalancer.server.port=80"
networks:
frontend:
external: true

30
web/group-site/nginx.conf Normal file
View File

@@ -0,0 +1,30 @@
# Nginx 配置 - Vue Router History 模式 + 子路径
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
gzip_min_length 1000;
# Vue Router history 模式支持
# 重要:因为 Traefik 已经去除了 /group 前缀,这里直接处理根路径
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}