Files
webend/README.md
T

260 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 唱作网 (ichangzuo)
基于 Vue3 + Vite6 + TypeScript5 + Element-Plus + Pinia 等主流技术栈构建的中后台管理前端应用。
## 技术栈
| 层级 | 技术 | 版本 |
|---|---|---|
| 框架 | Vue | ^3.5.13 |
| 构建 | Vite | ^6.0.2 |
| 语言 | TypeScript | ^5.7.2 |
| UI | Element Plus | ^2.9.0 |
| 状态管理 | Pinia | ^2.2.8 |
| 路由 | Vue Router | ^4.5.0 |
| 国际化 | Vue I18n | 10.0.5 |
| CSS | UnoCSS + SCSS | ^0.65.0 / sass ^1.82.0 |
| HTTP | Axios | ^1.7.8 |
| 富文本 | WangEditor | ^5.1.23 |
## 环境准备
| 环境 | 要求 |
|---|---|
| 运行环境 | Node.js ≥18(注意:20.6.0 版本不可用) |
| 包管理器 | pnpm(项目强制,npm/yarn 无法安装) |
| 开发工具 | VSCode(推荐) |
## 开发指南
### 安装与启动
```bash
# 安装依赖
pnpm install
# 启动开发服务器(默认端口 3000)
pnpm dev
```
### 常用命令
| 命令 | 说明 |
|---|---|
| `pnpm dev` | 启动开发服务器 |
| `pnpm build` | 类型检查 + 生产构建 |
| `pnpm build-only` | 仅生产构建(不做类型检查) |
| `pnpm type-check` | TypeScript 类型检查 |
| `pnpm lint:eslint` | ESLint 检查并自动修复 |
| `pnpm lint:prettier` | Prettier 格式化 |
| `pnpm lint:stylelint` | Stylelint 检查并自动修复 |
| `pnpm commit` | 交互式 Git 提交(必须使用,不要直接 `git commit` |
### 环境变量
环境变量定义在 `.env.development``.env.production` 中:
| 变量 | 开发环境 | 生产环境 | 说明 |
|---|---|---|---|
| `VITE_APP_PORT` | 3000 | — | 开发服务器端口 |
| `VITE_APP_BASE_API` | `/dev-api` | `/prod-api` | API 代理前缀 |
| `VITE_APP_API_URL` | `http://localhost:8989` | — | 后端接口地址 |
| `VITE_MOCK_DEV_SERVER` | false | — | 是否启用 Mock 服务 |
> 注意:`VITE_APP_BASE_API` 是代理前缀,不是后端的真实路径。Vite 开发服务器会自动将 `/dev-api` 前缀剥离后再转发请求到 `VITE_APP_API_URL`。例如请求 `/dev-api/api/v1/auth/login`,实际转发到 `http://localhost:8989/api/v1/auth/login`。
## 项目结构
```
src/
├── api/ # API 模块(每个文件对应一个业务域,导出静态类和类型)
├── assets/icons/ # SVG 图标(通过 vite-plugin-svg-icons 加载)
├── components/ # 通用组件(自动注册,无需手动导入)
├── directive/ # 自定义指令(v-permission 按钮权限)
├── enums/ # 常量枚举(ResultEnum, CacheEnum, LayoutEnum, ThemeEnum 等)
├── lang/ # 国际化资源(zh-CN + en
├── layout/ # 应用布局框架(侧边栏、顶栏、标签导航)
├── plugins/ # 应用插件注册(图标、路由守卫)
├── router/ # Vue Router 配置(静态路由 + 动态路由)
├── store/modules/ # Pinia 状态模块(app, permission, settings, tagsView, user
├── styles/ # 全局样式(SCSS 变量、重置、登录样式)
├── types/ # 全局类型声明(env, auto-imports, components, router
├── utils/ # 工具函数(request.ts = axios 封装, i18n, format, nprogress
└── views/ # 页面组件
├── software/ # 软件产品页(默认首页)
├── helper/ # 帮助/助手页
├── dashboard/ # 账号信息
├── account/ # 用户账户(笔记、消息、VIP、安全、修改密码)
├── system/ # 系统管理(用户、角色、菜单、字典、配置、日志)
├── website/ # 网站管理
├── autoLogin/ # 自动登录
├── resetPassword/ # 重置密码
└── error-page/ # 错误页面(401、404
```
## 核心功能
### 权限系统
- **路由权限**:基于角色的动态路由,登录后从后端获取菜单并动态注入路由
- **按钮权限**:通过 `v-permission` 指令和 `hasAuth()` 函数控制按钮级权限
- **白名单路由**`/software``/helper``/autoLogin``/resetPassword` 无需登录即可访问
- **ROOT 角色**:超级管理员拥有所有按钮权限,自动放行
### 认证流程
1. 用户登录 → 后端返回 Token → 存储到 `localStorage`key: `accessToken`
2. 路由守卫检测 Token → 获取用户信息(角色、权限) → 生成动态路由
3. Token 过期(后端返回 `A0230`) → 自动清除 Token → 重定向到登录页
### API 层
API 模块位于 `src/api/`,每个文件导出一个静态类和对应的请求/响应类型:
- `auth.ts` — 登录、注册、验证码
- `user.ts` — 用户信息、账户信息
- `role.ts` — 角色管理
- `menu.ts` — 菜单管理
- `dict.ts` — 字典管理
- `software.ts` — 软件产品
- `helper.ts` — 帮助内容
- `order.ts` — 订单管理
- `integral.ts` — 积分系统
- `message.ts` — 消息通知
- `notice.ts` — 公告管理
- `bank.ts` — 银行信息
- `file.ts` — 文件上传
- `config.ts` — 系统配置
- `log.ts` — 日志管理
- `statistics.ts` — 数据统计
- `style.ts` — 样式管理
- `codegen.ts` — 代码生成
### 状态管理
Pinia Store 采用 Composition API 风格(`defineStore("name", () => { ... })`):
| 模块 | 文件 | 职责 |
|---|---|---|
| app | `store/modules/app.ts` | 应用全局状态(侧边栏、设备类型等) |
| permission | `store/modules/permission.ts` | 动态路由生成 |
| settings | `store/modules/settings.ts` | 应用设置(主题、布局、语言等) |
| tagsView | `store/modules/tagsView.ts` | 标签导航管理 |
| user | `store/modules/user.ts` | 用户认证与信息 |
> 在组件外(如路由守卫、拦截器)使用 Store 时,用 `useUserStoreHook()`、`useAppStoreHook()` 等包装函数。
## 开发约定
### 路径别名
`@` 映射到 `src/`,跨模块引用统一使用 `@/` 前缀:
```typescript
// 正确
import { useUserStore } from "@/store/modules/user";
import AuthAPI from "@/api/auth";
// 错误
import { useUserStore } from "../../store/modules/user";
```
### 自动导入
项目配置了 `unplugin-auto-import``unplugin-vue-components`,以下无需手动导入:
- **Vue API**`ref``reactive``computed``watch``onMounted`
- **Pinia**`defineStore`
- **Vue Router**`useRouter``useRoute`
- **Vue I18n**`createI18n`
- **@vueuse/core**:所有导出
- **Element Plus**`ElMessage``ElNotification``ElMessageBox` 及所有组件
```typescript
// 错误 — 不要添加这些导入
import { ref } from "vue";
import { ElMessage } from "element-plus";
// 正确 — 直接使用,编译时自动注入
const count = ref(0);
ElMessage.success("操作成功");
```
### 图标使用
- **Element Plus 图标**`<i-ep-xxx />`(如 `<i-ep-edit />``<i-ep-delete />`
- **自定义 SVG 图标**:将 SVG 文件放入 `src/assets/icons/`,使用 `<SvgIcon icon-class="name" />`
### UnoCSS 快捷类
| 快捷类 | 等效 |
|---|---|
| `flex-center` | `flex justify-center items-center` |
| `flex-x-center` | `flex justify-center` |
| `flex-y-center` | `flex items-center` |
| `wh-full` | `w-full h-full` |
| `flex-x-between` | `flex items-center justify-between` |
| `flex-x-end` | `flex items-center justify-end` |
主题色使用 UnoCSS 的 `primary`(等价于 `var(--el-color-primary)`),不要硬编码色值。
### SCSS 全局变量
`src/styles/variables.scss` 中的变量通过 Vite 全局注入,所有 `.vue``.scss` 文件可直接使用,无需 `@use`
### Git 提交规范
使用 `pnpm commit` 交互式提交,支持以下类型:
| 类型 | 说明 |
|---|---|
| `feat` | 新增功能 |
| `fix` | 修复缺陷 |
| `docs` | 文档变更 |
| `style` | 代码格式(不影响功能) |
| `refactor` | 代码重构 |
| `perf` | 性能优化 |
| `test` | 测试相关 |
| `build` | 构建流程、外部依赖变更 |
| `ci` | CI 配置变更 |
| `revert` | 回滚提交 |
| `chore` | 构建过程或辅助工具变更 |
| `wip` | 开发阶段临时提交 |
Pre-commit 钩子会自动对暂存文件执行 ESLint + Prettier + Stylelint 检查。
## 部署
```bash
# 生产构建
pnpm build
# 构建产物在 dist/ 目录,部署到服务器即可
```
Nginx 配置参考:
```nginx
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
# 后端 API 反向代理
location /prod-api/ {
proxy_pass http://localhost:8989/;
}
}
```
> 注意:`try_files` 配置确保 Vue Router 的 HTML5 History 模式正常工作,刷新页面不会 404。
## 注意事项
- **自动导入插件 DTS 生成已关闭**:组件类型声明已预生成。如需添加新组件,临时开启 `vite.config.ts` 中 AutoImport/Components 的 `dts` 选项,运行一次开发服务器后重新关闭。
- **Node 20.6.0 不可用**:该版本存在已知问题,请使用其他 18+ 版本。
- **IDE 爆红**:如遇组件、函数或引用标红,尝试重启 VSCode 或重新执行 `pnpm install`