技术栈、目录结构、数据库设计、接口约定、部署方式、排错手册——接手一个项目先读这页, 面试被问「介绍一下你的项目」也照这个讲。
| 层 | 技术 | 为什么 |
|---|---|---|
| 前端框架 | Vue 3(组合式 API)+ Vite | 组合式 API 逻辑聚在一处好教学;Vite 冷启动秒开 |
| UI 组件 | Element Plus | 表单 / 表格 / 弹窗开箱即用,把时间留给业务 |
| 状态 / 路由 | Pinia + Vue Router(history 模式) | 登录态全局共享 + localStorage 持久化 |
| HTTP | axios(统一封装 request.js) | 拦截器统一带 token、统一处理 code |
| 后端 | Flask 3 + 蓝图 | 轻、显式,适合理解 Web 原理;蓝图按业务分五模块 |
| ORM | Flask-SQLAlchemy + Flask-Migrate | 模型即表结构;换数据库不改业务代码 |
| 鉴权 | Flask-JWT-Extended(Bearer token) | 无状态鉴权,前后端分离的事实标准 |
| 数据库 | MySQL 8(课程)/ SQLite(线上演示) | 本机学标准 SQL;小服务器上 SQLite 零运维 |
| 部署 | gunicorn + nginx + systemd + HTTPS | 经典三件套,全部在本站真实运行 |
hiflask/
├── app.py # 工厂 create_app + JWT 异常统一 + 全局错误兜底 + Swagger 文档挂载
├── config.py # dev / prod / testing 三套配置(.env 驱动)
├── extensions.py # db / jwt / cors / migrate(防循环导入)
├── seed_demo.py # 演示数据种子(SQLite / MySQL 通用)
├── models/ # user / article / comment 三个文件导出 7 个模型
├── views/ # home / user / article / comment / favorite 五蓝图
├── utils/ # response.py(统一响应)· auth.py(登录装饰器)
├── static/
│ ├── openapi.yaml # Swagger 接口契约(/apidocs 页面渲染的就是它)
│ └── upload/ # 头像等上传文件(nginx 反代 /static/)
├── requirements.txt
└── .env.example # 环境变量模板(真实 .env 不进版本库)hivue/
├── index.html
├── vite.config.js # @ 别名 + 开发代理(/api → 127.0.0.1:5000)
├── .env.development / .env.production # VITE_API_BASE=/api(不写死 IP)
└── src/
├── main.js # Pinia / Router / Element Plus 装配
├── router/ # 5 条路由 + 登录守卫
├── stores/ # user.js:token + 用户信息(localStorage 持久化)
├── utils/ # request.js:全站唯一请求出口(拦截器)
├── api/ # home / user / article / comment / favorite 五个模块
├── layouts/ # BasicLayout:顶栏导航 + 内容出口
├── components/ # ArticleCard 作品卡片(七 computed 兼容字段)
└── views/ # Home / ArticleList / ArticleDetail / Login / UserCenter| 表 | 职责 | 关键字段 |
|---|---|---|
| user | 注册用户 | username(唯一)、password(哈希)、avatar、status(1 正常 / 0 禁用) |
| category | 文学分类 | name(唯一)、sort(排序值)、status |
| article | 文学作品 | title、author、dynasty、category_id↗、summary、content、views、likes、is_recommend、status |
| banner | 首页轮播 | title、image、link、sort、status |
| comment | 书评(两级) | user_id↗、article_id↗、parent_id(回复)、content、likes、status |
| favorite | 收藏 | (user_id, article_id) 联合唯一、created_at |
| user_like | 点赞(通用) | user_id↗、target_type(article/comment)、target_id —— 一张表服务两种对象 |
http://127.0.0.1:5000/api(Vite 代理)· 线上 https://m369d.cn/api(nginx 反代){"code":200,"msg":"success","data":{}} —— HTTP 恒 200,业务看 code;分页 data = {list,total,page,page_size}Authorization: Bearer <token>;token 过期统一返回 code 401,前端拦截器自动跳登录页systemctl status hiwen-api # 看服务状态
systemctl restart hiwen-api # 改完代码 / 配置后重启
journalctl -u hiwen-api -n 50 # 最近 50 行日志(排错第一步)
curl 127.0.0.1:5099/api/health # 绕过 nginx 直接探后端
ls /var/lib/hiwen-api/ # SQLite 数据文件在这里(备份它=备份全部数据)install-hiwen-api.sh 幂等重装(数据不丢,.env 与库文件被排除保护)npm run dev 联调通过后按「开发十步 · 第 10 步」自行构建上线| 现象 | 原因与处理 |
|---|---|
| 前端一直「网络异常」 | 后端没起:curl 127.0.0.1:5000/api/health 自证;起了就是代理没配好(检查 vite.config.js 是否重启) |
| 控制台 CORS 报错 | 绕过了代理直连 5000。开发走 Vite 代理;生产走 nginx 同域反代;实在要跨域用 Flask-CORS |
| 不停弹「登录已过期」 | token 没带上:Network 看请求头有没有 Authorization;或后端 JWT 密钥变了(重启后旧 token 全失效,重新登录即可) |
| 注册报「用户名已存在」但没注册过 | SQLite / MySQL 里已有同名演示账号——换一个用户名,或 seed_demo.py --reset |
| build 后白屏 | 部署在子目录却没加 --base=子路径,资源全 404 |
| 刷新子路由 404 | nginx 没配 SPA 回落:try_files $uri $uri/ /index.html; |
| 上传头像 500 | 上传目录没有写权限:chown -R www-data /opt/hiwen-api/app/static |
| 列表翻页重复 / 漏条 | 排序没带次关键字 id(后端已处理;自己实现时别忘) |