前端项目结构
This commit is contained in:
563
docs/前端完整指南.md
Normal file
563
docs/前端完整指南.md
Normal file
@@ -0,0 +1,563 @@
|
||||
# 泰豪电源 AI 数智化平台 - 前端完整指南
|
||||
|
||||
## 📖 目录
|
||||
|
||||
1. [技术架构](#1-技术架构)
|
||||
2. [共享组件方案](#2-共享组件方案)
|
||||
3. [快速开始](#3-快速开始)
|
||||
4. [开发指南](#4-开发指南)
|
||||
5. [构建部署](#5-构建部署)
|
||||
6. [常见问题](#6-常见问题)
|
||||
|
||||
---
|
||||
|
||||
## 1. 技术架构
|
||||
|
||||
### 1.1 技术栈
|
||||
|
||||
**前端框架**
|
||||
- Vue 3.5+ (`<script setup>`)
|
||||
- TypeScript 5.7+
|
||||
- Vite 6.0+
|
||||
- Pinia 2.2+
|
||||
- Element Plus 2.9+
|
||||
|
||||
**工程化**
|
||||
- pnpm 9.0+ Monorepo
|
||||
- Turborepo 2.0+ 构建加速
|
||||
- unplugin-auto-import 自动导入
|
||||
- ESLint 9 + Prettier
|
||||
|
||||
**通信层**
|
||||
- ofetch (替代 Axios)
|
||||
- @vueuse/core
|
||||
|
||||
### 1.2 项目结构
|
||||
|
||||
```
|
||||
urbanLifelineWeb/
|
||||
├── packages/
|
||||
│ ├── shared/ # 共享包 ⭐核心
|
||||
│ │ ├── components/ # UI组件
|
||||
│ │ ├── utils/ # 工具函数
|
||||
│ │ ├── api/ # API封装
|
||||
│ │ └── composables/ # 组合函数
|
||||
│ ├── portal/ # 主应用
|
||||
│ ├── app-bidding/ # 招投标应用
|
||||
│ ├── app-customer-service/ # 智能客服应用
|
||||
│ └── app-knowledge/ # 知识协同应用
|
||||
├── pnpm-workspace.yaml
|
||||
└── turbo.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 共享组件方案
|
||||
|
||||
### 2.1 核心理念
|
||||
|
||||
**业务应用只需关心 `@shared/*` 导入,无需关心底层依赖(Vue、Element Plus 等)**
|
||||
|
||||
```
|
||||
业务应用: import { UlTable } from '@shared/components'
|
||||
↓
|
||||
浏览器: GET /shared/components.js
|
||||
↓
|
||||
共享服务: 返回包含 Vue + Element Plus 的 ES Module
|
||||
↓
|
||||
✅ 所有应用共用,浏览器缓存
|
||||
```
|
||||
|
||||
### 2.2 配置方式
|
||||
|
||||
**业务应用配置(极简)**
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"@shared/components": "/shared/components.js",
|
||||
"@shared/utils": "/shared/utils.js",
|
||||
"@shared/api": "/shared/api.js"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
**Vue 组件使用**
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
// ✅ 直接从 HTTP URL 加载
|
||||
import { UlTable } from '@shared/components'
|
||||
import { http } from '@shared/utils'
|
||||
import { authApi } from '@shared/api'
|
||||
import { useTable } from '@shared/composables'
|
||||
|
||||
const { loading, tableData } = useTable({
|
||||
fetchData: authApi.getUserList
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UlTable :data="tableData" :loading="loading" />
|
||||
</template>
|
||||
```
|
||||
|
||||
### 2.3 优势
|
||||
|
||||
| 特性 | 传统方式 | Import Maps 方案 |
|
||||
|------|---------|-----------------|
|
||||
| 代码共享 | ❌ 每个应用打包一份 | ✅ 所有应用共用一份 |
|
||||
| 构建体积 | ❌ 重复打包 | ✅ 减少 30-50% |
|
||||
| 依赖管理 | ❌ 每个应用配置 | ✅ 共享服务统一管理 |
|
||||
| 版本升级 | ❌ 所有应用改 | ✅ 只改共享服务 |
|
||||
| 浏览器缓存 | ⚠️ 独立缓存 | ✅ 统一缓存 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 快速开始
|
||||
|
||||
### 3.1 Docker 环境(推荐)
|
||||
|
||||
```bash
|
||||
# 1. 启动所有服务
|
||||
make up
|
||||
|
||||
# 2. 查看状态
|
||||
make ps
|
||||
|
||||
# 3. 访问应用
|
||||
open http://localhost
|
||||
```
|
||||
|
||||
**访问地址**
|
||||
- 主应用: http://localhost/
|
||||
- 招投标: http://localhost/bidding
|
||||
- 智能客服: http://localhost/customer-service
|
||||
- 共享组件: http://localhost/shared/components.js
|
||||
- API网关: http://localhost/api
|
||||
- Nacos: http://localhost/nacos
|
||||
|
||||
### 3.2 本地开发
|
||||
|
||||
```bash
|
||||
# 1. 安装依赖
|
||||
pnpm install
|
||||
|
||||
# 2. 启动所有应用
|
||||
pnpm dev
|
||||
|
||||
# 或启动单个应用
|
||||
pnpm --filter portal dev
|
||||
pnpm --filter app-bidding dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 开发指南
|
||||
|
||||
### 4.1 创建页面
|
||||
|
||||
```vue
|
||||
<!-- packages/portal/src/views/UserList.vue -->
|
||||
<script setup lang="ts">
|
||||
import { UlTable } from '@shared/components'
|
||||
import { authApi } from '@shared/api'
|
||||
import { useTable } from '@shared/composables'
|
||||
|
||||
interface User {
|
||||
id: string
|
||||
username: string
|
||||
email: string
|
||||
}
|
||||
|
||||
const { loading, tableData, pagination, handlePageChange } = useTable<User>({
|
||||
fetchData: authApi.getUserList
|
||||
})
|
||||
|
||||
const columns = [
|
||||
{ prop: 'username', label: '用户名', minWidth: 150 },
|
||||
{ prop: 'email', label: '邮箱', minWidth: 200 }
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="user-list">
|
||||
<UlTable
|
||||
:data="tableData"
|
||||
:columns="columns"
|
||||
:loading="loading"
|
||||
:pagination="pagination"
|
||||
@page-change="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 4.2 API 调用
|
||||
|
||||
```typescript
|
||||
// 使用封装的 API
|
||||
import { authApi, systemApi } from '@shared/api'
|
||||
|
||||
// GET 请求
|
||||
const users = await authApi.getUserList({ page: 1, size: 10 })
|
||||
|
||||
// POST 请求
|
||||
await authApi.createUser({ username: 'test', email: 'test@example.com' })
|
||||
|
||||
// 直接使用 http
|
||||
import { http } from '@shared/utils'
|
||||
const data = await http.get('/custom/endpoint')
|
||||
```
|
||||
|
||||
### 4.3 状态管理
|
||||
|
||||
```typescript
|
||||
// store/user.ts
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import { authApi } from '@shared/api'
|
||||
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
// State
|
||||
const userInfo = ref(null)
|
||||
const permissions = ref([])
|
||||
|
||||
// Getters
|
||||
const isLoggedIn = computed(() => !!userInfo.value)
|
||||
|
||||
// Actions
|
||||
const login = async (loginData) => {
|
||||
const res = await authApi.login(loginData)
|
||||
userInfo.value = res.userInfo
|
||||
permissions.value = res.permissions
|
||||
}
|
||||
|
||||
return { userInfo, permissions, isLoggedIn, login }
|
||||
})
|
||||
```
|
||||
|
||||
### 4.4 路由配置
|
||||
|
||||
```typescript
|
||||
// router/index.ts
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
component: () => import('@/layouts/MainLayout.vue'),
|
||||
children: [
|
||||
{
|
||||
path: 'home',
|
||||
component: () => import('@/views/home/index.vue'),
|
||||
meta: { title: '首页' }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
||||
```
|
||||
|
||||
### 4.5 常用命令
|
||||
|
||||
```bash
|
||||
# 查看日志
|
||||
make logs-portal # 主应用日志
|
||||
make logs-gateway # 网关日志
|
||||
make logs-shared # 共享包日志
|
||||
|
||||
# 重启服务
|
||||
make restart-portal # 重启主应用
|
||||
make restart # 重启所有服务
|
||||
|
||||
# 进入容器
|
||||
make shell-portal # 进入容器调试
|
||||
|
||||
# 数据库
|
||||
make db # 连接数据库
|
||||
make db-init # 初始化数据
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 构建部署
|
||||
|
||||
### 5.1 本地构建
|
||||
|
||||
```bash
|
||||
# 构建所有应用
|
||||
pnpm build
|
||||
|
||||
# 构建单个应用
|
||||
pnpm --filter portal build
|
||||
pnpm --filter shared build
|
||||
|
||||
# 预览
|
||||
pnpm preview
|
||||
```
|
||||
|
||||
### 5.2 部署到生产
|
||||
|
||||
**方式1: Docker 部署**
|
||||
|
||||
```bash
|
||||
# 构建生产镜像
|
||||
docker build -t urban-lifeline-web .
|
||||
|
||||
# 运行
|
||||
docker run -p 80:80 urban-lifeline-web
|
||||
```
|
||||
|
||||
**方式2: CDN 部署**
|
||||
|
||||
```bash
|
||||
# 部署共享包到 CDN
|
||||
cd packages/shared
|
||||
pnpm build
|
||||
ossutil cp -r dist/esm/ oss://cdn/shared/v1.0.0/
|
||||
|
||||
# 部署业务应用
|
||||
cd packages/portal
|
||||
pnpm build
|
||||
ossutil cp -r dist/ oss://cdn/portal/
|
||||
```
|
||||
|
||||
**方式3: Nginx 静态部署**
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name taihao.com;
|
||||
|
||||
# 主应用
|
||||
location / {
|
||||
root /var/www/portal/dist;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# 共享包
|
||||
location /shared/ {
|
||||
root /var/www/shared/dist;
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
expires 1y;
|
||||
}
|
||||
|
||||
# API 代理
|
||||
location /api/ {
|
||||
proxy_pass http://gateway:8080/;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 环境变量
|
||||
|
||||
```bash
|
||||
# .env.development
|
||||
VITE_API_BASE_URL=http://localhost/api
|
||||
VITE_SHARED_URL=http://localhost/shared
|
||||
|
||||
# .env.production
|
||||
VITE_API_BASE_URL=https://api.taihao.com/api
|
||||
VITE_SHARED_URL=https://cdn.taihao.com/shared/v1.0.0
|
||||
```
|
||||
|
||||
### 5.4 CI/CD
|
||||
|
||||
```yaml
|
||||
# .github/workflows/deploy.yml
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Build
|
||||
run: pnpm install && pnpm build
|
||||
|
||||
- name: Deploy
|
||||
run: ./scripts/deploy-production.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 常见问题
|
||||
|
||||
### 6.1 为什么使用 Import Maps?
|
||||
|
||||
**优势**:
|
||||
- ✅ 浏览器原生支持,无需额外库
|
||||
- ✅ 真正的运行时共享
|
||||
- ✅ 开发体验好(支持 HMR)
|
||||
- ✅ 减小构建体积
|
||||
|
||||
**对比 Module Federation**:
|
||||
- Import Maps 更简单,配置少
|
||||
- Module Federation 功能更强大,但复杂
|
||||
- 两者可以结合使用
|
||||
|
||||
### 6.2 如何处理 TypeScript 类型?
|
||||
|
||||
```typescript
|
||||
// packages/portal/src/types/shared.d.ts
|
||||
declare module '@shared/components' {
|
||||
export * from '../../../shared/src/components'
|
||||
}
|
||||
|
||||
declare module '@shared/utils' {
|
||||
export * from '../../../shared/src/utils'
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 如何更新共享组件?
|
||||
|
||||
```bash
|
||||
# 1. 修改共享组件代码
|
||||
vim packages/shared/src/components/UlTable/index.vue
|
||||
|
||||
# 2. 重启共享服务(HMR 自动生效)
|
||||
make restart-shared
|
||||
|
||||
# 3. 浏览器刷新,所有应用自动获得最新版本
|
||||
```
|
||||
|
||||
### 6.4 生产环境如何缓存?
|
||||
|
||||
```nginx
|
||||
# Nginx 配置
|
||||
location /shared/ {
|
||||
# 基于版本号的长期缓存
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# HTML 不缓存
|
||||
location ~* \.html$ {
|
||||
add_header Cache-Control "no-cache";
|
||||
}
|
||||
```
|
||||
|
||||
### 6.5 如何调试共享组件?
|
||||
|
||||
```bash
|
||||
# 方式1: 查看网络请求
|
||||
浏览器 F12 → Network → 筛选 JS → 查看 /shared/components.js
|
||||
|
||||
# 方式2: 查看日志
|
||||
make logs-shared
|
||||
|
||||
# 方式3: 进入容器
|
||||
make shell-shared
|
||||
```
|
||||
|
||||
### 6.6 为什么不用 Webpack?
|
||||
|
||||
Vite 优势:
|
||||
- ⚡ 开发启动快(秒级)
|
||||
- 🔥 HMR 更快
|
||||
- 📦 生产构建基于 Rollup(体积更小)
|
||||
- 🎯 原生 ES Module 支持
|
||||
|
||||
### 6.7 如何处理样式?
|
||||
|
||||
```vue
|
||||
<!-- 组件级样式 -->
|
||||
<style scoped>
|
||||
.ul-table {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- 全局样式 -->
|
||||
<style>
|
||||
@import '@shared/styles/variables.scss';
|
||||
</style>
|
||||
```
|
||||
|
||||
共享包会自动处理 CSS 提取和分割。
|
||||
|
||||
### 6.8 如何添加新的业务应用?
|
||||
|
||||
```bash
|
||||
# 1. 复制现有应用作为模板
|
||||
cp -r packages/portal packages/app-newapp
|
||||
|
||||
# 2. 修改 package.json
|
||||
{
|
||||
"name": "@apps/newapp",
|
||||
"scripts": {
|
||||
"dev": "vite --port 3003"
|
||||
}
|
||||
}
|
||||
|
||||
# 3. 添加到 pnpm-workspace.yaml(已自动包含)
|
||||
|
||||
# 4. 启动
|
||||
pnpm --filter app-newapp dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 附录
|
||||
|
||||
### A. 常用脚本
|
||||
|
||||
```bash
|
||||
# Makefile 命令
|
||||
make up # 启动
|
||||
make down # 停止
|
||||
make logs # 日志
|
||||
make ps # 状态
|
||||
make restart # 重启
|
||||
make clean # 清理
|
||||
|
||||
# pnpm 命令
|
||||
pnpm dev # 开发
|
||||
pnpm build # 构建
|
||||
pnpm preview # 预览
|
||||
pnpm lint # 检查
|
||||
pnpm format # 格式化
|
||||
```
|
||||
|
||||
### B. 目录说明
|
||||
|
||||
```
|
||||
urbanLifeline/
|
||||
├── urbanLifelineServ/ # 后端(Java Spring Boot)
|
||||
├── urbanLifelineWeb/ # 前端(Vue 3 Monorepo)
|
||||
├── docker-compose.dev.yml # Docker 开发环境
|
||||
├── Makefile # 快捷命令
|
||||
└── docs/ # 文档
|
||||
└── 前端完整指南.md # 📖 本文档
|
||||
```
|
||||
|
||||
### C. 技术支持
|
||||
|
||||
- 项目文档:`/docs`
|
||||
- 问题反馈:GitHub Issues
|
||||
- 开发规范:ESLint + Prettier
|
||||
- 提交规范:Conventional Commits
|
||||
|
||||
---
|
||||
|
||||
**Happy Coding! 🚀**
|
||||
|
||||
*最后更新:2025-12-02*
|
||||
Reference in New Issue
Block a user