@@ -54,7 +54,7 @@ English | [Chinese](./README.md)
|
|||||||
|
|
||||||
## 📘 Project Introduction
|
## 📘 Project Introduction
|
||||||
|
|
||||||
**Fastapi-Vue3-Admin** is a **fully open-source, highly modular, and technologically advanced modern rapid development platform**, designed to help developers efficiently build high-quality enterprise-level middle and back-office systems. This project adopts a **front-end and back-end decoupled architecture**, integrating the Python backend framework `FastAPI` and the mainstream frontend framework `Vue3`, combined with `UniApp` to achieve unified multi-terminal development, providing an all-in-one, out-of-the-box development experience.
|
**Fastapi-Vue3-Admin** is a **fully open-source, highly modular, and technologically advanced modern rapid development platform**, designed to help developers efficiently build high-quality enterprise-level middle and back-office systems. This project adopts a **front-end and back-end decoupled architecture**, integrating the Python backend framework `FastAPI` and the mainstream frontend framework `Vue3` to achieve unified multi-terminal development, providing an all-in-one, out-of-the-box development experience.
|
||||||
|
|
||||||
> **Design Philosophy**: Centered around modularity and loose coupling, it aims to offer rich functional modules, simple and easy-to-use interfaces, comprehensive development documentation, and convenient maintenance methods. By leveraging a unified framework and components, it reduces technology selection costs, follows development specifications and design patterns, builds a robust code layering model, and is equipped with comprehensive localized Chinese support—specifically tailored for team and enterprise development scenarios.
|
> **Design Philosophy**: Centered around modularity and loose coupling, it aims to offer rich functional modules, simple and easy-to-use interfaces, comprehensive development documentation, and convenient maintenance methods. By leveraging a unified framework and components, it reduces technology selection costs, follows development specifications and design patterns, builds a robust code layering model, and is equipped with comprehensive localized Chinese support—specifically tailored for team and enterprise development scenarios.
|
||||||
|
|
||||||
@@ -63,7 +63,6 @@ fastapi_vue3_admin
|
|||||||
├─ backend # Backend project
|
├─ backend # Backend project
|
||||||
├─ frontend # Frontend project
|
├─ frontend # Frontend project
|
||||||
├─ devops # Deployment project
|
├─ devops # Deployment project
|
||||||
├─ uni-app # Mobile application project
|
|
||||||
├─ docker-compose.yaml # Deployment configuration file
|
├─ docker-compose.yaml # Deployment configuration file
|
||||||
├─ start.sh # One-click deployment script
|
├─ start.sh # One-click deployment script
|
||||||
├─ LICENSE # License agreement
|
├─ LICENSE # License agreement
|
||||||
@@ -78,15 +77,14 @@ fastapi_vue3_admin
|
|||||||
| Feature | Description |
|
| Feature | Description |
|
||||||
| ------ | ----------- |
|
| ------ | ----------- |
|
||||||
| 🔭 Rapid Development | A fully open-source modern rapid development platform designed to help developers efficiently build high-quality middle and back-office systems. |
|
| 🔭 Rapid Development | A fully open-source modern rapid development platform designed to help developers efficiently build high-quality middle and back-office systems. |
|
||||||
| 🌐 Full-Stack Integration | Frontend and backend decoupled architecture, integrating Python (FastAPI), Vue3, and UniApp for multi-terminal development. |
|
| 🌐 Full-Stack Integration | Frontend and backend decoupled architecture, integrating Python (FastAPI), and Vue3 for multi-terminal development. |
|
||||||
| 🧱 Modular Design | Highly decoupled system functions, easy to extend and maintain. |
|
| 🧱 Modular Design | Highly decoupled system functions, easy to extend and maintain. |
|
||||||
| ⚡ High-Performance Asynchronous | Optimized interface response speed using the FastAPI asynchronous framework and Redis caching. |
|
| ⚡ High-Performance Asynchronous | Optimized interface response speed using the FastAPI asynchronous framework and Redis caching. |
|
||||||
| 🔒 Secure Authentication | Supports JWT OAuth2 authentication mechanisms to ensure system security. |
|
| 🔒 Secure Authentication | Supports JWT OAuth2 authentication mechanisms to ensure system security. |
|
||||||
| 📊 Permission Management | Implements fine-grained permission control at the menu, button, and data levels using the RBAC model. |
|
| 📊 Permission Management | Implements fine-grained permission control at the menu, button, and data levels using the RBAC model. |
|
||||||
| 🚀 Quick Deployment | Supports one-click deployment with Docker, Docker Compose, and Nginx. |
|
| 🚀 Quick Deployment | Supports one-click deployment with Docker, Docker Compose, and Nginx. |
|
||||||
| 📄 Developer-Friendly | Provides comprehensive Chinese documentation, localized interface, and visual toolchains to reduce learning costs. |
|
| 📄 Developer-Friendly | Provides comprehensive Chinese documentation, localized interface, and visual toolchains to reduce learning costs. |
|
||||||
| 📫 Cross-Platform Support | Supports multi-terminal development via UniApp, including H5 and mini-programs. |
|
| 🚀 Easy Integration | Ready-to-use with mainstream frontend technology stacks such as Vue3, Vite5, Pinia, and Ant Design Vue |
|
||||||
| 🚀 Easy Integration | Ready-to-use with mainstream frontend technology stacks such as Vue3, Vite5, Pinia, UniApp, Ant Design Vue, and uView-plus. |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -99,8 +97,7 @@ fastapi_vue3_admin
|
|||||||
| Task Scheduling | APScheduler | Easily implement scheduled tasks. |
|
| Task Scheduling | APScheduler | Easily implement scheduled tasks. |
|
||||||
| Authentication | PyJWT | Implements JWT-based authentication. |
|
| Authentication | PyJWT | Implements JWT-based authentication. |
|
||||||
| Frontend Framework | Vue3 / Vite5 / Pinia / TypeScript | Rapid development of Vue3 applications. |
|
| Frontend Framework | Vue3 / Vite5 / Pinia / TypeScript | Rapid development of Vue3 applications. |
|
||||||
| UI Library | Ant Design Vue / uView-plus | Quickly build visually appealing UI components. |
|
| UI Library | Ant Design Vue | Quickly build visually appealing UI components. |
|
||||||
| Mobile Development | UniApp | Rapid mobile application development. |
|
|
||||||
| Database | MySQL / MongoDB | Powerful database systems. |
|
| Database | MySQL / MongoDB | Powerful database systems. |
|
||||||
| Caching | Redis | High-performance caching database. |
|
| Caching | Redis | High-performance caching database. |
|
||||||
| Documentation | Swagger / Redoc | Automatically generates API documentation. |
|
| Documentation | Swagger / Redoc | Automatically generates API documentation. |
|
||||||
@@ -115,7 +112,6 @@ fastapi_vue3_admin
|
|||||||
| System Management | Menus, Departments, Positions, Roles, Users, Logs, Configurations, Announcements, Dictionaries, Tasks | Core system functionality |
|
| System Management | Menus, Departments, Positions, Roles, Users, Logs, Configurations, Announcements, Dictionaries, Tasks | Core system functionality |
|
||||||
| Monitoring Management | Online Users, Server Monitoring, Cache Monitoring | System monitoring and management features |
|
| Monitoring Management | Online Users, Server Monitoring, Cache Monitoring | System monitoring and management features |
|
||||||
| Public Management | API Management, Documentation Management | Project API documentation management |
|
| Public Management | API Management, Documentation Management | Project API documentation management |
|
||||||
| App Module | Home Page, Workspace, Personal Center | Mobile application management |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -140,8 +136,6 @@ fastapi_vue3_admin
|
|||||||
| Frontend | Vue3 | 3.3 |
|
| Frontend | Vue3 | 3.3 |
|
||||||
| Database | MySQL | 8.0 (latest version recommended) |
|
| Database | MySQL | 8.0 (latest version recommended) |
|
||||||
| Middleware | Redis | 7.0 (latest version recommended) |
|
| Middleware | Redis | 7.0 (latest version recommended) |
|
||||||
| MiniApp | uni-app | 3.0.0 |
|
|
||||||
| MiniApp | uview-plus | ^3.3.74 |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -197,28 +191,9 @@ npm run build
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Local App Startup
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# Navigate to the frontend project directory
|
|
||||||
cd frontend
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
npm install
|
|
||||||
|
|
||||||
# Start the frontend service
|
|
||||||
npm run dev
|
|
||||||
|
|
||||||
# Build the frontend, generating the `frontend/dist` directory
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Local Access Addresses
|
### Local Access Addresses
|
||||||
|
|
||||||
- Frontend Address: <http://127.0.0.1:5180>
|
- Frontend Address: <http://127.0.0.1:5180>
|
||||||
- Mini Program Address: <http://127.0.0.1:5181>
|
|
||||||
- API Address: <http://127.0.0.1:8001/api/v1/docs>
|
- API Address: <http://127.0.0.1:8001/api/v1/docs>
|
||||||
- Admin Account: `admin` Password: `123456`
|
- Admin Account: `admin` Password: `123456`
|
||||||
- Demo Account: `demo` Password: `123456`
|
- Demo Account: `demo` Password: `123456`
|
||||||
@@ -234,11 +209,6 @@ chmod +x start.sh
|
|||||||
# Execute the script
|
# Execute the script
|
||||||
./start.sh
|
./start.sh
|
||||||
|
|
||||||
# Access addresses
|
|
||||||
# Frontend access: `http://Public IP address:80`,
|
|
||||||
# API access: `http://Public IP address:8001/api/v1/docs`,
|
|
||||||
# Log in with `admin/123456` or `demo/123456`
|
|
||||||
|
|
||||||
# View images:
|
# View images:
|
||||||
docker images -a
|
docker images -a
|
||||||
|
|
||||||
@@ -296,12 +266,6 @@ docker rm <Container name>
|
|||||||
<td><img src="./backend/docs/resources/help.png"/>Online Documentation</td>
|
<td><img src="./backend/docs/resources/help.png"/>Online Documentation</td>
|
||||||
<td><img src="./backend/docs/resources/dict.png"/>Dictionary Management</td>
|
<td><img src="./backend/docs/resources/dict.png"/>Dictionary Management</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td><img src="./backend/docs/resources/app-login.png"/>App Login</td>
|
|
||||||
<td><img src="./backend/docs/resources/app-home.png"/>App Home Page</td>
|
|
||||||
<td><img src="./backend/docs/resources/app-work.png"/>App Workspace</td>
|
|
||||||
<td><img src="./backend/docs/resources/app-me.png"/>App Personal Center</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -318,8 +282,6 @@ Thanks to the contributions and support of the following projects, which have en
|
|||||||
- [RuoYi-Vue3-FastAPI Project](https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI)
|
- [RuoYi-Vue3-FastAPI Project](https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI)
|
||||||
- [APScheduler Project](https://github.com/agronholm/apscheduler)
|
- [APScheduler Project](https://github.com/agronholm/apscheduler)
|
||||||
- [Vite Project](https://github.com/vitejs/vite)
|
- [Vite Project](https://github.com/vitejs/vite)
|
||||||
- [UniApp Project](https://github.com/dcloudio/uni-app)
|
|
||||||
- [uView-plus Project](https://uiadmin.net/uview-plus)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
## 📘 项目介绍
|
## 📘 项目介绍
|
||||||
|
|
||||||
**Fastapi-Vue3-Admin** 是一套 **完全开源、高度模块化、技术先进的现代化快速开发平台**,旨在帮助开发者高效搭建高质量的企业级中后台系统。该项目采用 **前后端分离架构**,融合 Python 后端框架 `FastAPI` 和前端主流框架 `Vue3`,结合 `UniApp` 实现多端统一开发,提供了一站式开箱即用的开发体验。
|
**Fastapi-Vue3-Admin** 是一套 **完全开源、高度模块化、技术先进的现代化快速开发平台**,旨在帮助开发者高效搭建高质量的企业级中后台系统。该项目采用 **前后端分离架构**,融合 Python 后端框架 `FastAPI` 和前端主流框架 `Vue3` 实现多端统一开发,提供了一站式开箱即用的开发体验。
|
||||||
|
|
||||||
> **设计初心**: 以模块化、松耦合为核心,追求丰富的功能模块、简洁易用的接口、详尽的开发文档和便捷的维护方式。通过统一框架和组件,降低技术选型成本,遵循开发规范和设计模式,构建强大的代码分层模型,搭配完善的本地中文化支持,专为团队和企业开发场景量身定制。
|
> **设计初心**: 以模块化、松耦合为核心,追求丰富的功能模块、简洁易用的接口、详尽的开发文档和便捷的维护方式。通过统一框架和组件,降低技术选型成本,遵循开发规范和设计模式,构建强大的代码分层模型,搭配完善的本地中文化支持,专为团队和企业开发场景量身定制。
|
||||||
|
|
||||||
@@ -63,7 +63,6 @@ fastapi_vue3_admin
|
|||||||
├─ backend # 后端工程
|
├─ backend # 后端工程
|
||||||
├─ frontend # 前端工程
|
├─ frontend # 前端工程
|
||||||
├─ devops # 部署工程
|
├─ devops # 部署工程
|
||||||
├─ uni-app # 移动端工程
|
|
||||||
├─ docker-compose.yaml # 部署文件
|
├─ docker-compose.yaml # 部署文件
|
||||||
├─ start.sh # 一键部署脚本
|
├─ start.sh # 一键部署脚本
|
||||||
├─ LICENSE # 许可协议
|
├─ LICENSE # 许可协议
|
||||||
@@ -78,15 +77,14 @@ fastapi_vue3_admin
|
|||||||
| 特性 | 描述 |
|
| 特性 | 描述 |
|
||||||
| ---- | ---- |
|
| ---- | ---- |
|
||||||
| 🔭 快速开发 |一套完全开源的现代化快速开发平台,旨在帮助开发者高效搭建高质量的中后台系统。|
|
| 🔭 快速开发 |一套完全开源的现代化快速开发平台,旨在帮助开发者高效搭建高质量的中后台系统。|
|
||||||
| 🌐 全栈整合 | 前后端分离,融合 Python (FastAPI) + Vue3 + UniApp 多端开发 |
|
| 🌐 全栈整合 | 前后端分离,融合 Python (FastAPI) + Vue3 多端开发 |
|
||||||
| 🧱 模块化设计 | 系统功能高度解耦,便于扩展和维护 |
|
| 🧱 模块化设计 | 系统功能高度解耦,便于扩展和维护 |
|
||||||
| ⚡️ 高性能异步 | 使用 FastAPI 异步框架 + Redis 缓存优化接口响应速度 |
|
| ⚡️ 高性能异步 | 使用 FastAPI 异步框架 + Redis 缓存优化接口响应速度 |
|
||||||
| 🔒 安全认证 | 支持 JWT OAuth2 认证机制,保障系统安全 |
|
| 🔒 安全认证 | 支持 JWT OAuth2 认证机制,保障系统安全 |
|
||||||
| 📊 权限管理 | RBAC 模型实现菜单、按钮、数据级别的细粒度权限控制 |
|
| 📊 权限管理 | RBAC 模型实现菜单、按钮、数据级别的细粒度权限控制 |
|
||||||
| 🚀 快速部署 | 支持 Docker/Docker Compose/Nginx 一键部署 |
|
| 🚀 快速部署 | 支持 Docker/Docker Compose/Nginx 一键部署 |
|
||||||
| 📄 开发友好 | 提供完善的中文文档 + 中文化界面 + 可视化工具链,降低学习成本 |
|
| 📄 开发友好 | 提供完善的中文文档 + 中文化界面 + 可视化工具链,降低学习成本 |
|
||||||
| 📫 跨平台支持 | 通过 UniApp 支持多端开发,包括 H5、小程序等。|
|
| 🚀 快速接入 |基于 Vue3、Vite5、Pinia、Ant Design Vue 等主流前端技术栈,开箱即用。|
|
||||||
| 🚀 快速接入 |基于 Vue3、Vite5、Pinia、UniApp、Ant Design Vue、uView-plus 等主流前端技术栈,开箱即用。|
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -99,8 +97,7 @@ fastapi_vue3_admin
|
|||||||
| 定时任务 | APScheduler | 轻松实现定时任务。 |
|
| 定时任务 | APScheduler | 轻松实现定时任务。 |
|
||||||
| 权限认证 | PyJWT | 实现 JWT 认证。 |
|
| 权限认证 | PyJWT | 实现 JWT 认证。 |
|
||||||
| 前端框架 | Vue3 / Vite5 / Pinia / TypeScript | 快速开发 Vue3 应用。 |
|
| 前端框架 | Vue3 / Vite5 / Pinia / TypeScript | 快速开发 Vue3 应用。 |
|
||||||
| UI 库 | Ant Design Vue / uView-plus | 快速开发美观的 UI 组件。 |
|
| UI 库 | Ant Design Vue | 快速开发美观的 UI 组件。 |
|
||||||
| 移动端 | UniApp | 快速开发移动端应用。 |
|
|
||||||
| 数据库 | MySQL / MongoDB | 强大的数据库。 |
|
| 数据库 | MySQL / MongoDB | 强大的数据库。 |
|
||||||
| 缓存 | Redis | 强大的缓存数据库。 |
|
| 缓存 | Redis | 强大的缓存数据库。 |
|
||||||
| 文档 | Swagger / Redoc | 自动生成 API 文档。 |
|
| 文档 | Swagger / Redoc | 自动生成 API 文档。 |
|
||||||
@@ -116,7 +113,6 @@ fastapi_vue3_admin
|
|||||||
| 系统管理 | 包含菜单、部门、岗位、角色、用户、日志、配置、公告、字典、任务等子模块|系统主功能 |
|
| 系统管理 | 包含菜单、部门、岗位、角色、用户、日志、配置、公告、字典、任务等子模块|系统主功能 |
|
||||||
| 监控管理 | 在线用户、服务器监控、缓存监控 |系统监控管理功能 |
|
| 监控管理 | 在线用户、服务器监控、缓存监控 |系统监控管理功能 |
|
||||||
| 公共管理 | 接口管理、文档管理|项目接口文档 |
|
| 公共管理 | 接口管理、文档管理|项目接口文档 |
|
||||||
| App 端 | 首页、工作台、个人中心|移动端应用管理 |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -141,8 +137,6 @@ fastapi_vue3_admin
|
|||||||
| 前端 | Vue3 | 3.3 |
|
| 前端 | Vue3 | 3.3 |
|
||||||
| 数据库 | MySQL | 8.0 (推荐使用最新版)|
|
| 数据库 | MySQL | 8.0 (推荐使用最新版)|
|
||||||
| 中间件 | Redis | 7.0 (推荐使用最新版)|
|
| 中间件 | Redis | 7.0 (推荐使用最新版)|
|
||||||
| 小程序 | uni-app | 3.0.0 |
|
|
||||||
| 小程序 | uview-plus | ^3.3.74 |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -191,25 +185,9 @@ npm run build
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 本地小程序启动
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# 进入移动工程目录
|
|
||||||
cd uni-app
|
|
||||||
# 安装依赖
|
|
||||||
npm install
|
|
||||||
# 启动小程序
|
|
||||||
npm run dev:h5
|
|
||||||
# 构建, 生成 `uni-app/dist` 目录
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 本地访问地址
|
### 本地访问地址
|
||||||
|
|
||||||
- 前端地址: <http://127.0.0.1:5180>
|
- 前端地址: <http://127.0.0.1:5180>
|
||||||
- 小程序地址: <http://127.0.0.1:5181>
|
|
||||||
- 接口地址: <http://127.0.0.1:8001/api/v1/docs>
|
- 接口地址: <http://127.0.0.1:8001/api/v1/docs>
|
||||||
- 管理员账号:`admin` 密码:`123456`
|
- 管理员账号:`admin` 密码:`123456`
|
||||||
- 演示账号:`demo` 密码:`123456`
|
- 演示账号:`demo` 密码:`123456`
|
||||||
@@ -223,10 +201,6 @@ npm run build
|
|||||||
chmod +x start.sh
|
chmod +x start.sh
|
||||||
# 执行脚本
|
# 执行脚本
|
||||||
./start.sh
|
./start.sh
|
||||||
# 访问地址
|
|
||||||
# 前端访问: `http://公网地址:80`,
|
|
||||||
# 接口访问: `http://公网地址:8001/api/v1/docs`,
|
|
||||||
# 登录 `admin/123456` 或 `demo/123456`
|
|
||||||
# 查看镜像:
|
# 查看镜像:
|
||||||
docsker images -a
|
docsker images -a
|
||||||
# 查看容器:
|
# 查看容器:
|
||||||
@@ -279,12 +253,6 @@ docker rm <容器名>
|
|||||||
<td><img src="./backend/docs/resources/help.png"/>在线文档</td>
|
<td><img src="./backend/docs/resources/help.png"/>在线文档</td>
|
||||||
<td><img src="./backend/docs/resources/dict.png"/>字典管理</td>
|
<td><img src="./backend/docs/resources/dict.png"/>字典管理</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td><img src="./backend/docs/resources/app-login.png"/>app登陆</td>
|
|
||||||
<td><img src="./backend/docs/resources/app-home.png"/>app首页</td>
|
|
||||||
<td><img src="./backend/docs/resources/app-work.png"/>app工作台</td>
|
|
||||||
<td><img src="./backend/docs/resources/app-me.png"/>app个人中心</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -301,8 +269,6 @@ docker rm <容器名>
|
|||||||
- [RuoYi-Vue3-FastAPI 项目](https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI)
|
- [RuoYi-Vue3-FastAPI 项目](https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI)
|
||||||
- [APScheduler 项目](https://github.com/agronholm/apscheduler)
|
- [APScheduler 项目](https://github.com/agronholm/apscheduler)
|
||||||
- [Vite 项目](https://github.com/vitejs/vite)
|
- [Vite 项目](https://github.com/vitejs/vite)
|
||||||
- [UniApp 项目](https://github.com/dcloudio/uni-app)
|
|
||||||
- [uView-plus 项目](https://uiadmin.net/uview-plus)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
## 📘 项目介绍
|
## 📘 项目介绍
|
||||||
|
|
||||||
**Fastapi-Vue3-Admin** 是一套 **完全开源、高度模块化、技术先进的现代化快速开发平台**,旨在帮助开发者高效搭建高质量的企业级中后台系统。该项目采用 **前后端分离架构**,融合 Python 后端框架 `FastAPI` 和前端主流框架 `Vue3`,结合 `UniApp` 实现多端统一开发,提供了一站式开箱即用的开发体验。
|
**Fastapi-Vue3-Admin** 是一套 **完全开源、高度模块化、技术先进的现代化快速开发平台**,旨在帮助开发者高效搭建高质量的企业级中后台系统。该项目采用 **前后端分离架构**,融合 Python 后端框架 `FastAPI` 和前端主流框架 `Vue3`,实现多端统一开发,提供了一站式开箱即用的开发体验。
|
||||||
|
|
||||||
> **设计初心**: 以模块化、松耦合为核心,追求丰富的功能模块、简洁易用的接口、详尽的开发文档和便捷的维护方式。通过统一框架和组件,降低技术选型成本,遵循开发规范和设计模式,构建强大的代码分层模型,搭配完善的本地中文化支持,专为团队和企业开发场景量身定制。
|
> **设计初心**: 以模块化、松耦合为核心,追求丰富的功能模块、简洁易用的接口、详尽的开发文档和便捷的维护方式。通过统一框架和组件,降低技术选型成本,遵循开发规范和设计模式,构建强大的代码分层模型,搭配完善的本地中文化支持,专为团队和企业开发场景量身定制。
|
||||||
|
|
||||||
@@ -59,8 +59,6 @@ fastapi_vue3_admin
|
|||||||
├─ backend # 后端工程
|
├─ backend # 后端工程
|
||||||
├─ frontend # 前端工程
|
├─ frontend # 前端工程
|
||||||
├─ devops # 部署工程
|
├─ devops # 部署工程
|
||||||
├─ mkdocs # 文档工程
|
|
||||||
├─ uni-app # 移动端工程
|
|
||||||
├─ docker-compose.yaml # 部署文件
|
├─ docker-compose.yaml # 部署文件
|
||||||
├─ start.sh # 一键部署脚本
|
├─ start.sh # 一键部署脚本
|
||||||
├─ LICENSE # 许可协议
|
├─ LICENSE # 许可协议
|
||||||
@@ -75,15 +73,14 @@ fastapi_vue3_admin
|
|||||||
| 特性 | 描述 |
|
| 特性 | 描述 |
|
||||||
| ---- | ---- |
|
| ---- | ---- |
|
||||||
| 🔭 快速开发 |一套完全开源的现代化快速开发平台,旨在帮助开发者高效搭建高质量的中后台系统。|
|
| 🔭 快速开发 |一套完全开源的现代化快速开发平台,旨在帮助开发者高效搭建高质量的中后台系统。|
|
||||||
| 🌐 全栈整合 | 前后端分离,融合 Python (FastAPI) + Vue3 + UniApp 多端开发 |
|
| 🌐 全栈整合 | 前后端分离,融合 Python (FastAPI) + Vue3 |
|
||||||
| 🧱 模块化设计 | 系统功能高度解耦,便于扩展和维护 |
|
| 🧱 模块化设计 | 系统功能高度解耦,便于扩展和维护 |
|
||||||
| ⚡️ 高性能异步 | 使用 FastAPI 异步框架 + Redis 缓存优化接口响应速度 |
|
| ⚡️ 高性能异步 | 使用 FastAPI 异步框架 + Redis 缓存优化接口响应速度 |
|
||||||
| 🔒 安全认证 | 支持 JWT OAuth2 认证机制,保障系统安全 |
|
| 🔒 安全认证 | 支持 JWT OAuth2 认证机制,保障系统安全 |
|
||||||
| 📊 权限管理 | RBAC 模型实现菜单、按钮、数据级别的细粒度权限控制 |
|
| 📊 权限管理 | RBAC 模型实现菜单、按钮、数据级别的细粒度权限控制 |
|
||||||
| 🚀 快速部署 | 支持 Docker/Docker Compose/Nginx 一键部署 |
|
| 🚀 快速部署 | 支持 Docker/Docker Compose/Nginx 一键部署 |
|
||||||
| 📄 开发友好 | 提供完善的中文文档 + 中文化界面 + 可视化工具链,降低学习成本 |
|
| 📄 开发友好 | 提供完善的中文文档 + 中文化界面 + 可视化工具链,降低学习成本 |
|
||||||
| 📫 跨平台支持 | 通过 UniApp 支持多端开发,包括 H5、小程序等。|
|
| 🚀 快速接入 |基于 Vue3、Vite5、Pinia、Ant Design Vue 等主流前端技术栈,开箱即用。|
|
||||||
| 🚀 快速接入 |基于 Vue3、Vite5、Pinia、UniApp、Ant Design Vue、uView-plus 等主流前端技术栈,开箱即用。|
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -96,8 +93,7 @@ fastapi_vue3_admin
|
|||||||
| 定时任务 | APScheduler | 轻松实现定时任务。 |
|
| 定时任务 | APScheduler | 轻松实现定时任务。 |
|
||||||
| 权限认证 | PyJWT | 实现 JWT 认证。 |
|
| 权限认证 | PyJWT | 实现 JWT 认证。 |
|
||||||
| 前端框架 | Vue3 / Vite5 / Pinia / TypeScript | 快速开发 Vue3 应用。 |
|
| 前端框架 | Vue3 / Vite5 / Pinia / TypeScript | 快速开发 Vue3 应用。 |
|
||||||
| UI 库 | Ant Design Vue / uView-plus | 快速开发美观的 UI 组件。 |
|
| UI 库 | Ant Design Vue | 快速开发美观的 UI 组件。 |
|
||||||
| 移动端 | UniApp | 快速开发移动端应用。 |
|
|
||||||
| 数据库 | MySQL / MongoDB | 强大的数据库。 |
|
| 数据库 | MySQL / MongoDB | 强大的数据库。 |
|
||||||
| 缓存 | Redis | 强大的缓存数据库。 |
|
| 缓存 | Redis | 强大的缓存数据库。 |
|
||||||
| 文档 | Swagger / Redoc | 自动生成 API 文档。 |
|
| 文档 | Swagger / Redoc | 自动生成 API 文档。 |
|
||||||
@@ -138,8 +134,6 @@ fastapi_vue3_admin
|
|||||||
| 前端 | Vue3 | 3.3 |
|
| 前端 | Vue3 | 3.3 |
|
||||||
| 数据库 | MySQL | 8.0 (推荐使用最新版)|
|
| 数据库 | MySQL | 8.0 (推荐使用最新版)|
|
||||||
| 中间件 | Redis | 7.0 (推荐使用最新版)|
|
| 中间件 | Redis | 7.0 (推荐使用最新版)|
|
||||||
| 小程序 | uni-app | 3.0.0 |
|
|
||||||
| 小程序 | uview-plus | ^3.3.74 |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -188,21 +182,6 @@ npm run build
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 本地小程序启动
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# 进入移动工程目录
|
|
||||||
cd uni-app
|
|
||||||
# 安装依赖
|
|
||||||
npm install
|
|
||||||
# 启动小程序
|
|
||||||
npm run dev:h5
|
|
||||||
# 构建, 生成 `uni-app/dist` 目录
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 本地访问地址
|
### 本地访问地址
|
||||||
|
|
||||||
- 前端地址: <http://127.0.0.1:5180>
|
- 前端地址: <http://127.0.0.1:5180>
|
||||||
@@ -298,8 +277,6 @@ docker rm <容器名>
|
|||||||
- [RuoYi-Vue3-FastAPI 项目](https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI)
|
- [RuoYi-Vue3-FastAPI 项目](https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI)
|
||||||
- [APScheduler 项目](https://github.com/agronholm/apscheduler)
|
- [APScheduler 项目](https://github.com/agronholm/apscheduler)
|
||||||
- [Vite 项目](https://github.com/vitejs/vite)
|
- [Vite 项目](https://github.com/vitejs/vite)
|
||||||
- [UniApp 项目](https://github.com/dcloudio/uni-app)
|
|
||||||
- [uView-plus 项目](https://uiadmin.net/uview-plus)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 707 KiB |
|
Before Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 409 KiB |
@@ -389,15 +389,6 @@
|
|||||||
|
|
||||||
<li class="md-nav__item">
|
<li class="md-nav__item">
|
||||||
<a href="#_11" class="md-nav__link">
|
<a href="#_11" class="md-nav__link">
|
||||||
<span class="md-ellipsis">
|
|
||||||
本地小程序启动
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="md-nav__item">
|
|
||||||
<a href="#_12" class="md-nav__link">
|
|
||||||
<span class="md-ellipsis">
|
<span class="md-ellipsis">
|
||||||
本地访问地址
|
本地访问地址
|
||||||
</span>
|
</span>
|
||||||
@@ -420,7 +411,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="md-nav__item">
|
<li class="md-nav__item">
|
||||||
<a href="#_13" class="md-nav__link">
|
<a href="#_12" class="md-nav__link">
|
||||||
<span class="md-ellipsis">
|
<span class="md-ellipsis">
|
||||||
🔧 模块展示
|
🔧 模块展示
|
||||||
</span>
|
</span>
|
||||||
@@ -429,7 +420,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="md-nav__item">
|
<li class="md-nav__item">
|
||||||
<a href="#_14" class="md-nav__link">
|
<a href="#_13" class="md-nav__link">
|
||||||
<span class="md-ellipsis">
|
<span class="md-ellipsis">
|
||||||
🙏 特别鸣谢
|
🙏 特别鸣谢
|
||||||
</span>
|
</span>
|
||||||
@@ -438,7 +429,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="md-nav__item">
|
<li class="md-nav__item">
|
||||||
<a href="#_15" class="md-nav__link">
|
<a href="#_14" class="md-nav__link">
|
||||||
<span class="md-ellipsis">
|
<span class="md-ellipsis">
|
||||||
🎨 社区
|
🎨 社区
|
||||||
</span>
|
</span>
|
||||||
@@ -456,7 +447,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="md-nav__item">
|
<li class="md-nav__item">
|
||||||
<a href="#_16" class="md-nav__link">
|
<a href="#_15" class="md-nav__link">
|
||||||
<span class="md-ellipsis">
|
<span class="md-ellipsis">
|
||||||
👀 访问统计
|
👀 访问统计
|
||||||
</span>
|
</span>
|
||||||
@@ -540,7 +531,7 @@
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<h2 id="_1">📘 项目介绍</h2>
|
<h2 id="_1">📘 项目介绍</h2>
|
||||||
<p><strong>Fastapi-Vue3-Admin</strong> 是一套 <strong>完全开源、高度模块化、技术先进的现代化快速开发平台</strong>,旨在帮助开发者高效搭建高质量的企业级中后台系统。该项目采用 <strong>前后端分离架构</strong>,融合 Python 后端框架 <code>FastAPI</code> 和前端主流框架 <code>Vue3</code>,结合 <code>UniApp</code> 实现多端统一开发,提供了一站式开箱即用的开发体验。</p>
|
<p><strong>Fastapi-Vue3-Admin</strong> 是一套 <strong>完全开源、高度模块化、技术先进的现代化快速开发平台</strong>,旨在帮助开发者高效搭建高质量的企业级中后台系统。该项目采用 <strong>前后端分离架构</strong>,融合 Python 后端框架 <code>FastAPI</code> 和前端主流框架 <code>Vue3</code>,实现多端统一开发,提供了一站式开箱即用的开发体验。</p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><strong>设计初心</strong>: 以模块化、松耦合为核心,追求丰富的功能模块、简洁易用的接口、详尽的开发文档和便捷的维护方式。通过统一框架和组件,降低技术选型成本,遵循开发规范和设计模式,构建强大的代码分层模型,搭配完善的本地中文化支持,专为团队和企业开发场景量身定制。</p>
|
<p><strong>设计初心</strong>: 以模块化、松耦合为核心,追求丰富的功能模块、简洁易用的接口、详尽的开发文档和便捷的维护方式。通过统一框架和组件,降低技术选型成本,遵循开发规范和设计模式,构建强大的代码分层模型,搭配完善的本地中文化支持,专为团队和企业开发场景量身定制。</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@@ -548,8 +539,6 @@
|
|||||||
├─ backend # 后端工程
|
├─ backend # 后端工程
|
||||||
├─ frontend # 前端工程
|
├─ frontend # 前端工程
|
||||||
├─ devops # 部署工程
|
├─ devops # 部署工程
|
||||||
├─ mkdocs # 文档工程
|
|
||||||
├─ uni-app # 移动端工程
|
|
||||||
├─ docker-compose.yaml # 部署文件
|
├─ docker-compose.yaml # 部署文件
|
||||||
├─ start.sh # 一键部署脚本
|
├─ start.sh # 一键部署脚本
|
||||||
├─ LICENSE # 许可协议
|
├─ LICENSE # 许可协议
|
||||||
@@ -572,7 +561,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>🌐 全栈整合</td>
|
<td>🌐 全栈整合</td>
|
||||||
<td>前后端分离,融合 Python (FastAPI) + Vue3 + UniApp 多端开发</td>
|
<td>前后端分离,融合 Python (FastAPI) + Vue3</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>🧱 模块化设计</td>
|
<td>🧱 模块化设计</td>
|
||||||
@@ -599,12 +588,8 @@
|
|||||||
<td>提供完善的中文文档 + 中文化界面 + 可视化工具链,降低学习成本</td>
|
<td>提供完善的中文文档 + 中文化界面 + 可视化工具链,降低学习成本</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>📫 跨平台支持</td>
|
|
||||||
<td>通过 UniApp 支持多端开发,包括 H5、小程序等。</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>🚀 快速接入</td>
|
<td>🚀 快速接入</td>
|
||||||
<td>基于 Vue3、Vite5、Pinia、UniApp、Ant Design Vue、uView-plus 等主流前端技术栈,开箱即用。</td>
|
<td>基于 Vue3、Vite5、Pinia、Ant Design Vue 等主流前端技术栈,开箱即用。</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -646,15 +631,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>UI 库</td>
|
<td>UI 库</td>
|
||||||
<td>Ant Design Vue / uView-plus</td>
|
<td>Ant Design Vue</td>
|
||||||
<td>快速开发美观的 UI 组件。</td>
|
<td>快速开发美观的 UI 组件。</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>移动端</td>
|
|
||||||
<td>UniApp</td>
|
|
||||||
<td>快速开发移动端应用。</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>数据库</td>
|
<td>数据库</td>
|
||||||
<td>MySQL / MongoDB</td>
|
<td>MySQL / MongoDB</td>
|
||||||
<td>强大的数据库。</td>
|
<td>强大的数据库。</td>
|
||||||
@@ -768,16 +748,6 @@
|
|||||||
<td>Redis</td>
|
<td>Redis</td>
|
||||||
<td>7.0 (推荐使用最新版)</td>
|
<td>7.0 (推荐使用最新版)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>小程序</td>
|
|
||||||
<td>uni-app</td>
|
|
||||||
<td>3.0.0</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>小程序</td>
|
|
||||||
<td>uview-plus</td>
|
|
||||||
<td>^3.3.74</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<hr />
|
<hr />
|
||||||
@@ -814,18 +784,7 @@ npm run dev
|
|||||||
npm run build
|
npm run build
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<hr />
|
<hr />
|
||||||
<h3 id="_11">本地小程序启动</h3>
|
<h3 id="_11">本地访问地址</h3>
|
||||||
<pre><code class="language-sh"># 进入移动工程目录
|
|
||||||
cd uni-app
|
|
||||||
# 安装依赖
|
|
||||||
npm install
|
|
||||||
# 启动小程序
|
|
||||||
npm run dev:h5
|
|
||||||
# 构建, 生成 `uni-app/dist` 目录
|
|
||||||
npm run build
|
|
||||||
</code></pre>
|
|
||||||
<hr />
|
|
||||||
<h3 id="_12">本地访问地址</h3>
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>前端地址: <a href="http://127.0.0.1:5180">http://127.0.0.1:5180</a></li>
|
<li>前端地址: <a href="http://127.0.0.1:5180">http://127.0.0.1:5180</a></li>
|
||||||
<li>小程序地址: <a href="http://127.0.0.1:5181">http://127.0.0.1:5181</a></li>
|
<li>小程序地址: <a href="http://127.0.0.1:5181">http://127.0.0.1:5181</a></li>
|
||||||
@@ -863,7 +822,7 @@ docker rm <容器名>
|
|||||||
<li>部署文件 <code>fastapi_vue3_amdin/docker-compose.yaml</code> 和 <code>fastapi_vue3_amdin/devops/devops/nginx/nginx.conf</code></li>
|
<li>部署文件 <code>fastapi_vue3_amdin/docker-compose.yaml</code> 和 <code>fastapi_vue3_amdin/devops/devops/nginx/nginx.conf</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
<hr />
|
<hr />
|
||||||
<h2 id="_13">🔧 模块展示</h2>
|
<h2 id="_12">🔧 模块展示</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://gitee.com/tao__tao/fastapi_vue3_admin/raw/master/backend/docs/resources/login.png"/>登陆</td>
|
<td><img src="https://gitee.com/tao__tao/fastapi_vue3_admin/raw/master/backend/docs/resources/login.png"/>登陆</td>
|
||||||
@@ -902,7 +861,7 @@ docker rm <容器名>
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<h2 id="_14">🙏 特别鸣谢</h2>
|
<h2 id="_13">🙏 特别鸣谢</h2>
|
||||||
<p>感谢以下项目的贡献和支持,使本项目得以顺利完成:</p>
|
<p>感谢以下项目的贡献和支持,使本项目得以顺利完成:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://fastapi.tiangolo.com/">FastAPI 项目</a></li>
|
<li><a href="https://fastapi.tiangolo.com/">FastAPI 项目</a></li>
|
||||||
@@ -913,11 +872,9 @@ docker rm <容器名>
|
|||||||
<li><a href="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI">RuoYi-Vue3-FastAPI 项目</a></li>
|
<li><a href="https://gitee.com/insistence2022/RuoYi-Vue3-FastAPI">RuoYi-Vue3-FastAPI 项目</a></li>
|
||||||
<li><a href="https://github.com/agronholm/apscheduler">APScheduler 项目</a></li>
|
<li><a href="https://github.com/agronholm/apscheduler">APScheduler 项目</a></li>
|
||||||
<li><a href="https://github.com/vitejs/vite">Vite 项目</a></li>
|
<li><a href="https://github.com/vitejs/vite">Vite 项目</a></li>
|
||||||
<li><a href="https://github.com/dcloudio/uni-app">UniApp 项目</a></li>
|
|
||||||
<li><a href="https://uiadmin.net/uview-plus">uView-plus 项目</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<hr />
|
<hr />
|
||||||
<h2 id="_15">🎨 社区</h2>
|
<h2 id="_14">🎨 社区</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="https://gitee.com/tao__tao/fastapi_vue3_admin/raw/master/backend/docs/resources/wechat.jpg"/></td>
|
<td><img src="https://gitee.com/tao__tao/fastapi_vue3_admin/raw/master/backend/docs/resources/wechat.jpg"/></td>
|
||||||
@@ -929,7 +886,7 @@ docker rm <容器名>
|
|||||||
<h2 id="star">❤️ Star 支持我</h2>
|
<h2 id="star">❤️ Star 支持我</h2>
|
||||||
<p>如果你喜欢这个项目,请给我一个 ⭐️ Star 支持一下吧!非常感谢!</p>
|
<p>如果你喜欢这个项目,请给我一个 ⭐️ Star 支持一下吧!非常感谢!</p>
|
||||||
<hr />
|
<hr />
|
||||||
<h2 id="_16">👀 访问统计</h2>
|
<h2 id="_15">👀 访问统计</h2>
|
||||||
<p><img alt="Visitor Count" src="https://profile-counter.glitch.me/1014TaoTao/count.svg" /></p>
|
<p><img alt="Visitor Count" src="https://profile-counter.glitch.me/1014TaoTao/count.svg" /></p>
|
||||||
<hr />
|
<hr />
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 707 KiB |
|
Before Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 409 KiB |
@@ -1,11 +0,0 @@
|
|||||||
# 环境变量
|
|
||||||
VITE_ENV = development
|
|
||||||
|
|
||||||
# 后端地址
|
|
||||||
VITE_API_BASE_URL = "http://192.168.0.101:8001"
|
|
||||||
|
|
||||||
# 后端接口基础路径
|
|
||||||
VITE_API_BASE_NAME = "/api"
|
|
||||||
|
|
||||||
# 请求超时时间
|
|
||||||
VITE_TIMEOUT = "10000"
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
# uni-app
|
|
||||||
|
|
||||||
## 目录结构
|
|
||||||
|
|
||||||
```sh
|
|
||||||
uni-app/
|
|
||||||
├─ src # 前端源码目录
|
|
||||||
│ ├─ api # API目录
|
|
||||||
│ ├─ components # 组件目录
|
|
||||||
│ ├─ pages # 页面目录
|
|
||||||
│ ├─ static # 静态资源目录
|
|
||||||
│ ├─ stores # 状态管理目录
|
|
||||||
│ ├─ utils # 工具目录
|
|
||||||
│ ├─ App.vue # 主组件
|
|
||||||
│ ├─ main.ts # 入口文件
|
|
||||||
│ ├─ manifest.json # 应用配置文件
|
|
||||||
│ ├─ pages.json # 页面配置文件
|
|
||||||
│ ├─ shims-uni.d.ts # 类型声明文件
|
|
||||||
│ └─ uni.scss # 全局样式文件
|
|
||||||
├─ .env # 前端目录
|
|
||||||
├─ .gitignore # git忽略文件
|
|
||||||
├─ .env # 环境变量
|
|
||||||
├─ index.html # 首页
|
|
||||||
├─ package.json # 项目依赖
|
|
||||||
├─ shims-uni.d.ts # 类型声明文件
|
|
||||||
├─ vite.config.js # vite配置文件
|
|
||||||
└─ README.md # 文档说明
|
|
||||||
```
|
|
||||||
|
|
||||||
## 快速开始
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# 进入移动工程目录
|
|
||||||
cd uni-app
|
|
||||||
# 安装依赖
|
|
||||||
npm install
|
|
||||||
# 启动小程序
|
|
||||||
npm run dev:h5
|
|
||||||
# 构建, 生成 `uni-app/dist` 目录
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## 注意
|
|
||||||
|
|
||||||
在sass1.8.0以上版本报错Deprecation Warning: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0. 因为新版本Sass的@use语法较为激进,如果升级为@use将会是破坏式更新,所以推荐将sass固定在以下版本结局报警。
|
|
||||||
"uview-plus": "^3.3.74", 版本不要升级
|
|
||||||
"unocss": "^0.58.9", 版本不要升级
|
|
||||||
"sass": "1.63.2", //sass版本不要升级
|
|
||||||
"sass-loader": "10.4.1", //sass-loader版本不要升级
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<link rel="icon" type="image/png" href="/static/favicon.ico" />
|
|
||||||
<script>
|
|
||||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
|
||||||
CSS.supports('top: constant(a)'))
|
|
||||||
document.write(
|
|
||||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
|
||||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
|
||||||
</script>
|
|
||||||
<title></title>
|
|
||||||
<!--preload-links-->
|
|
||||||
<!--app-context-->
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"><!--app-html--></div>
|
|
||||||
<script type="module" src="/src/main.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "uni-preset-vue",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"scripts": {
|
|
||||||
"dev:custom": "uni -p",
|
|
||||||
"dev:h5": "uni",
|
|
||||||
"dev:h5:ssr": "uni --ssr",
|
|
||||||
"dev:mp-alipay": "uni -p mp-alipay",
|
|
||||||
"dev:mp-baidu": "uni -p mp-baidu",
|
|
||||||
"dev:mp-jd": "uni -p mp-jd",
|
|
||||||
"dev:mp-kuaishou": "uni -p mp-kuaishou",
|
|
||||||
"dev:mp-lark": "uni -p mp-lark",
|
|
||||||
"dev:mp-qq": "uni -p mp-qq",
|
|
||||||
"dev:mp-toutiao": "uni -p mp-toutiao",
|
|
||||||
"dev:mp-weixin": "uni -p mp-weixin",
|
|
||||||
"dev:mp-xhs": "uni -p mp-xhs",
|
|
||||||
"dev:quickapp-webview": "uni -p quickapp-webview",
|
|
||||||
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
|
|
||||||
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
|
|
||||||
"build:custom": "uni build -p",
|
|
||||||
"build:h5": "uni build",
|
|
||||||
"build:h5:ssr": "uni build --ssr",
|
|
||||||
"build:mp-alipay": "uni build -p mp-alipay",
|
|
||||||
"build:mp-baidu": "uni build -p mp-baidu",
|
|
||||||
"build:mp-jd": "uni build -p mp-jd",
|
|
||||||
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
|
||||||
"build:mp-lark": "uni build -p mp-lark",
|
|
||||||
"build:mp-qq": "uni build -p mp-qq",
|
|
||||||
"build:mp-toutiao": "uni build -p mp-toutiao",
|
|
||||||
"build:mp-weixin": "uni build -p mp-weixin",
|
|
||||||
"build:mp-xhs": "uni build -p mp-xhs",
|
|
||||||
"build:quickapp-webview": "uni build -p quickapp-webview",
|
|
||||||
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
|
|
||||||
"build:quickapp-webview-union": "uni build -p quickapp-webview-union"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@dcloudio/uni-app": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-app-harmony": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-app-plus": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-components": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-h5": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-mp-alipay": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-mp-baidu": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-mp-jd": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-mp-kuaishou": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-mp-lark": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-mp-qq": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-mp-toutiao": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-mp-weixin": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-mp-xhs": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-quickapp-webview": "3.0.0-4050720250324001",
|
|
||||||
"unplugin-auto-import": "^19.1.2",
|
|
||||||
"uview-plus": "^3.3.74",
|
|
||||||
"vue": "3.5.13",
|
|
||||||
"vue-i18n": "9.14.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@dcloudio/types": "3.4.14",
|
|
||||||
"@dcloudio/uni-automator": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-cli-shared": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/uni-stacktracey": "3.0.0-4050720250324001",
|
|
||||||
"@dcloudio/vite-plugin-uni": "3.0.0-4050720250324001",
|
|
||||||
"@vue/runtime-core": "3.5.13",
|
|
||||||
"pinia": "^2.3.0",
|
|
||||||
"sass": "1.63.2",
|
|
||||||
"sass-loader": "10.4.1",
|
|
||||||
"unocss": "^0.58.9",
|
|
||||||
"vite": "5.2.8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/// <reference types='@dcloudio/types' />
|
|
||||||
import 'vue'
|
|
||||||
|
|
||||||
declare module '@vue/runtime-core' {
|
|
||||||
type Hooks = App.AppInstance & Page.PageInstance;
|
|
||||||
|
|
||||||
interface ComponentCustomOptions extends Hooks {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
|
|
||||||
|
|
||||||
onLaunch(() => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
onHide(() => {
|
|
||||||
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import "uview-plus/index.scss";
|
|
||||||
</style>
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import { request } from "../utils/request";
|
|
||||||
|
|
||||||
const contentTypes = {
|
|
||||||
form: "application/x-www-form-urlencoded",
|
|
||||||
json: "application/json",
|
|
||||||
multipart: "multipart/form-data"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export function login(data) {
|
|
||||||
return request({
|
|
||||||
url: "/api/v1/system/auth/login",
|
|
||||||
method: "post",
|
|
||||||
data: data,
|
|
||||||
header: { "Content-Type": contentTypes.form }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function get_captcha() {
|
|
||||||
return request({
|
|
||||||
url: "/api/v1/system/auth/captcha/get",
|
|
||||||
method: "post",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function forgot_password(data) {
|
|
||||||
return request({
|
|
||||||
url: "/api/v1/system/user/forget/password",
|
|
||||||
method: "post",
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function register(data) {
|
|
||||||
return request({
|
|
||||||
url: "/api/v1/system/user/register",
|
|
||||||
method: "post",
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function logout(data) {
|
|
||||||
return request({
|
|
||||||
url: "/api/v1/system/auth/logout",
|
|
||||||
method: "post",
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getCurrentUserInfo() {
|
|
||||||
return request({
|
|
||||||
url: "/api/v1/system/user/current/info",
|
|
||||||
method: "get",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="layout">
|
|
||||||
<slot name="main"></slot>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.layout {
|
|
||||||
min-height: (100vh - var(--status-bar-height));
|
|
||||||
|
|
||||||
.main {
|
|
||||||
padding: 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import { createSSRApp } from "vue";
|
|
||||||
import App from "./App.vue";
|
|
||||||
import uviewPlus, { setConfig } from 'uview-plus';
|
|
||||||
import * as Pinia from 'pinia';
|
|
||||||
import 'uno.css';
|
|
||||||
|
|
||||||
export function createApp() {
|
|
||||||
const app = createSSRApp(App);
|
|
||||||
app.use(uviewPlus)
|
|
||||||
app.use(Pinia.createPinia());
|
|
||||||
return {
|
|
||||||
app,
|
|
||||||
Pinia
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
{
|
|
||||||
"name" : "",
|
|
||||||
"appid" : "",
|
|
||||||
"description" : "",
|
|
||||||
"versionName" : "1.0.0",
|
|
||||||
"versionCode" : "100",
|
|
||||||
"transformPx" : false,
|
|
||||||
/* 5+App特有相关 */
|
|
||||||
"app-plus" : {
|
|
||||||
"usingComponents" : true,
|
|
||||||
"nvueStyleCompiler" : "uni-app",
|
|
||||||
"compilerVersion" : 3,
|
|
||||||
"splashscreen" : {
|
|
||||||
"alwaysShowBeforeRender" : true,
|
|
||||||
"waiting" : true,
|
|
||||||
"autoclose" : true,
|
|
||||||
"delay" : 0
|
|
||||||
},
|
|
||||||
/* 模块配置 */
|
|
||||||
"modules" : {},
|
|
||||||
/* 应用发布信息 */
|
|
||||||
"distribute" : {
|
|
||||||
/* android打包配置 */
|
|
||||||
"android" : {
|
|
||||||
"permissions" : [
|
|
||||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
|
||||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
|
||||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
/* ios打包配置 */
|
|
||||||
"ios" : {},
|
|
||||||
/* SDK配置 */
|
|
||||||
"sdkConfigs" : {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/* 快应用特有相关 */
|
|
||||||
"quickapp" : {},
|
|
||||||
/* 小程序特有相关 */
|
|
||||||
"mp-weixin" : {
|
|
||||||
"appid" : "",
|
|
||||||
"setting" : {
|
|
||||||
"urlCheck" : false
|
|
||||||
},
|
|
||||||
"usingComponents" : true
|
|
||||||
},
|
|
||||||
"mp-alipay" : {
|
|
||||||
"usingComponents" : true
|
|
||||||
},
|
|
||||||
"mp-baidu" : {
|
|
||||||
"usingComponents" : true
|
|
||||||
},
|
|
||||||
"mp-toutiao" : {
|
|
||||||
"usingComponents" : true
|
|
||||||
},
|
|
||||||
"uniStatistics": {
|
|
||||||
"enable": false
|
|
||||||
},
|
|
||||||
"vueVersion" : "3"
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
{
|
|
||||||
"easycom": {
|
|
||||||
"autoscan": true,
|
|
||||||
"custom": {
|
|
||||||
// uni-ui 规则如下配置
|
|
||||||
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
|
|
||||||
|
|
||||||
// uView-plus 规则如下配置
|
|
||||||
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
|
||||||
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
|
|
||||||
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
|
||||||
{
|
|
||||||
"path": "pages/login/login",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "登录"
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/me/me",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "个人中心"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/me/profile",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "个人主页"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path" : "pages/home/home",
|
|
||||||
"style" :
|
|
||||||
{
|
|
||||||
"navigationBarTitleText" : "首页",
|
|
||||||
"enablePullDownRefresh": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path" : "pages/work/work",
|
|
||||||
"style" :
|
|
||||||
{
|
|
||||||
"navigationBarTitleText" : "工作台",
|
|
||||||
"enablePullDownRefresh": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"globalStyle": {
|
|
||||||
"navigationBarTextStyle": "white",
|
|
||||||
"navigationBarTitleText": "用户信息管理系统",// 导航蓝字体内容
|
|
||||||
"navigationBarBackgroundColor": "#3c9cff",//导航蓝背景颜色
|
|
||||||
"backgroundColor": "#F8F8F8"// 下拉刷新区背景颜色
|
|
||||||
},
|
|
||||||
"tabBar": {
|
|
||||||
"color": "#999",
|
|
||||||
"selectedColor": "#3c9cff",
|
|
||||||
"list": [
|
|
||||||
{
|
|
||||||
"pagePath": "pages/home/home",
|
|
||||||
"text": "首页",
|
|
||||||
"iconPath": "/static/tabbar/home.png",
|
|
||||||
"selectedIconPath": "/static/tabbar/home_.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pagePath": "pages/work/work",
|
|
||||||
"text": "工作台",
|
|
||||||
"iconPath": "/static/tabbar/work.png",
|
|
||||||
"selectedIconPath": "/static/tabbar/work_.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pagePath": "pages/me/me",
|
|
||||||
"text": "我的",
|
|
||||||
"iconPath": "/static/tabbar/mine.png",
|
|
||||||
"selectedIconPath": "/static/tabbar/mine_.png"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"uniIdRouter": {}
|
|
||||||
}
|
|
||||||
@@ -1,226 +0,0 @@
|
|||||||
<template>
|
|
||||||
<app-layout>
|
|
||||||
<template #main>
|
|
||||||
<view class="home-container">
|
|
||||||
<up-search :placeholder="'搜索书名/作者/分类'" @search="handleSearch" clear="handleClearSearch" />
|
|
||||||
|
|
||||||
<view class="scroll-content">
|
|
||||||
<!-- 紧凑轮播图 -->
|
|
||||||
<view class="swiper-section">
|
|
||||||
<up-swiper :list="swiperList" indicator>
|
|
||||||
<template v-slot:item="{ item }">
|
|
||||||
<up-image :src="item.image" width="100%" height="160rpx" mode="aspectFill"
|
|
||||||
radius="12" />
|
|
||||||
</template>
|
|
||||||
</up-swiper>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 分类导航 -->
|
|
||||||
<view class="category-nav">
|
|
||||||
<scroll-view scroll-x class="nav-scroll">
|
|
||||||
<view v-for="(item, index) in categories" :key="index" class="nav-item"
|
|
||||||
:class="{ active: currentCategory === index }" @click="switchCategory(index)">
|
|
||||||
{{ item }}
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 热门小说推荐 -->
|
|
||||||
<view class="novel-section">
|
|
||||||
<view class="section-header">
|
|
||||||
<text class="title">热门小说</text>
|
|
||||||
<text class="more">更多 ></text>
|
|
||||||
</view>
|
|
||||||
<scroll-view scroll-x class="novel-scroll">
|
|
||||||
<view v-for="(item, index) in hotNovels" :key="index" class="novel-card">
|
|
||||||
<up-image :src="item.cover" width="200rpx" height="280rpx" radius="12" />
|
|
||||||
<text class="novel-title">{{ item.title }}</text>
|
|
||||||
<text class="novel-author">{{ item.author }}</text>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 排行榜 -->
|
|
||||||
<view class="ranking-section">
|
|
||||||
<view class="section-header">
|
|
||||||
<text class="title">本周热榜</text>
|
|
||||||
</view>
|
|
||||||
<view class="ranking-list">
|
|
||||||
<view v-for="(item, index) in rankingList" :key="index" class="ranking-item">
|
|
||||||
<text class="rank-num" :class="{ 'top3': index < 3 }">{{ index + 1 }}</text>
|
|
||||||
<up-image :src="item.cover" width="120rpx" height="160rpx" radius="8" />
|
|
||||||
<view class="rank-info">
|
|
||||||
<text class="book-title">{{ item.title }}</text>
|
|
||||||
<text class="book-author">{{ item.author }}</text>
|
|
||||||
<text class="book-hot">{{ item.hot }}人在读</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</app-layout>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
const swiperList = ref([
|
|
||||||
'/static/banner/banner01.jpg',
|
|
||||||
'/static/banner/banner02.jpg',
|
|
||||||
'/static/banner/banner03.jpg'
|
|
||||||
])
|
|
||||||
|
|
||||||
const currentCategory = ref(0)
|
|
||||||
const categories = ref(['推荐', '小说', '文学', '青春', '励志', '生活', '经管', '科技'])
|
|
||||||
|
|
||||||
const hotNovels = ref([
|
|
||||||
{ cover: 'https://bookcover.yuewen.com/qdbimg/349573/1001535109/150.webp', title: '三体', author: '刘慈欣' },
|
|
||||||
{ cover: 'https://bookcover.yuewen.com/qdbimg/349573/1042581400/150.webp', title: '活着', author: '余华' },
|
|
||||||
{ cover: 'https://bookcover.yuewen.com/qdbimg/349573/1039864976/150.webp', title: '白夜行', author: '东野圭吾' },
|
|
||||||
// ...更多小说
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
const rankingList = ref([
|
|
||||||
{ cover: 'https://bookcover.yuewen.com/qdbimg/349573/1015190643/90.webp', title: '云边有个小卖部', author: '张嘉佳', hot: '12.5万' },
|
|
||||||
{ cover: 'https://bookcover.yuewen.com/qdbimg/349573/1030657157/90.webp', title: '克拉克公园', author: '史蒂夫', hot: '10.2万' },
|
|
||||||
{ cover: 'https://bookcover.yuewen.com/qdbimg/349573/1005053098/90.webp', title: '平原上的摩西', author: '双雪涛', hot: '8.9万' },
|
|
||||||
])
|
|
||||||
|
|
||||||
const switchCategory = (index) => {
|
|
||||||
currentCategory.value = index
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSearch = (value) => {
|
|
||||||
console.log('搜索:', value)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.home-container {
|
|
||||||
padding: 60rpx 20rpx;
|
|
||||||
|
|
||||||
.scroll-content {
|
|
||||||
padding: 20rpx 24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 轮播图优化 */
|
|
||||||
.swiper-section {
|
|
||||||
margin: 20rpx 0;
|
|
||||||
|
|
||||||
:deep(.up-swiper) {
|
|
||||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 分类导航 */
|
|
||||||
.category-nav {
|
|
||||||
margin: 20rpx 0;
|
|
||||||
|
|
||||||
.nav-scroll {
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
.nav-item {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 16rpx 30rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #666;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: #2979ff;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 热门小说推荐 */
|
|
||||||
.novel-section {
|
|
||||||
margin: 30rpx 0;
|
|
||||||
|
|
||||||
.novel-scroll {
|
|
||||||
white-space: nowrap;
|
|
||||||
padding: 20rpx 0;
|
|
||||||
|
|
||||||
.novel-card {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 24rpx;
|
|
||||||
width: 200rpx;
|
|
||||||
|
|
||||||
.novel-title {
|
|
||||||
font-size: 26rpx;
|
|
||||||
color: #333;
|
|
||||||
margin-top: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.novel-author {
|
|
||||||
font-size: 22rpx;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 排行榜 */
|
|
||||||
.ranking-section {
|
|
||||||
margin: 30rpx 0;
|
|
||||||
|
|
||||||
.ranking-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20rpx 0;
|
|
||||||
border-bottom: 1rpx solid #eee;
|
|
||||||
|
|
||||||
.rank-num {
|
|
||||||
width: 40rpx;
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #999;
|
|
||||||
|
|
||||||
&.top3 {
|
|
||||||
color: #ff6b6b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.rank-info {
|
|
||||||
margin-left: 20rpx;
|
|
||||||
|
|
||||||
.book-title {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.book-author {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.book-hot {
|
|
||||||
font-size: 22rpx;
|
|
||||||
color: #ff6b6b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.more {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="login-container" :style="{ backgroundImage: BACKGROUND_IMAGE }">
|
|
||||||
<!-- 登录表单 -->
|
|
||||||
<up-image class="logo" :src="LOGO_PATH" shape="circle" width="100" height="100" mode="aspectFit" />
|
|
||||||
<up-text class="logo-text" :bold="true" align="center" size="24" lineHeight="40" text="用户管理系统" />
|
|
||||||
<up-form ref="loginForm" class="auth-form" :model="formData" :rules="rules">
|
|
||||||
<!-- 用户名 -->
|
|
||||||
<up-form-item prop="username">
|
|
||||||
<up-input v-model="formData.username" placeholder="请输入账号" prefix-icon="account" clearable />
|
|
||||||
</up-form-item>
|
|
||||||
|
|
||||||
<!-- 密码 -->
|
|
||||||
<up-form-item prop="password">
|
|
||||||
<up-input v-model="formData.password" type="password" placeholder="请输入密码" prefix-icon="lock" clearable />
|
|
||||||
</up-form-item>
|
|
||||||
|
|
||||||
<!-- 验证码 -->
|
|
||||||
<up-form-item prop="captcha">
|
|
||||||
<up-input v-model="formData.captcha" placeholder="请输入验证码" prefix-icon="fingerprint" clearable >
|
|
||||||
<template #suffix>
|
|
||||||
<up-image :src="captchaState.img_base" @click="requestCaptcha" :preview="false" width="100" height="30" />
|
|
||||||
</template>
|
|
||||||
</up-input>
|
|
||||||
</up-form-item>
|
|
||||||
|
|
||||||
<!-- 登录按钮 -->
|
|
||||||
<up-button class="login-btn" type="primary" text="登录" :loading="loading" @click="handleSubmit" />
|
|
||||||
</up-form>
|
|
||||||
|
|
||||||
<!-- 底部链接 - 左右分开 -->
|
|
||||||
<view class="footer-links">
|
|
||||||
<up-text type="primary" @click="navigateTo('register')" text="用户注册" align="left"></up-text>
|
|
||||||
<up-text type="primary" @click="navigateTo('forget')" text="忘记密码" align="right"></up-text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { onReady, onShow } from '@dcloudio/uni-app'
|
|
||||||
import { useUserStore } from '../../stores/index'
|
|
||||||
import { login, get_captcha } from '@/api/apis'
|
|
||||||
|
|
||||||
onReady(() => {
|
|
||||||
requestCaptcha();
|
|
||||||
})
|
|
||||||
|
|
||||||
const LOGO_PATH = '/static/logo.png'
|
|
||||||
const BACKGROUND_IMAGE = '/static/background.png'
|
|
||||||
const loading = ref(false)
|
|
||||||
const loginForm = ref(null)
|
|
||||||
|
|
||||||
const formData = ref({
|
|
||||||
username: '',
|
|
||||||
password: '',
|
|
||||||
captcha: '',
|
|
||||||
captcha_key: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
const captchaState = ref({
|
|
||||||
key: '',
|
|
||||||
img_base: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
const rules = {
|
|
||||||
username: { required: true, message: '请输入账号',trigger: ['change','blur'] },
|
|
||||||
password: { required: true, message: '请输入密码',trigger: ['change','blur'] },
|
|
||||||
captcha: { required: true, message: '请输入验证码',trigger: ['change','blur'] },
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
await loginForm.value.validate()
|
|
||||||
loading.value = true
|
|
||||||
|
|
||||||
formData.value.captcha_key = captchaState.value.key;
|
|
||||||
login(formData.value).then(response => {
|
|
||||||
const data = response.data;
|
|
||||||
useUserStore().setToken(data.access_token, data.refresh_token)
|
|
||||||
console.log('登录成功', response)
|
|
||||||
uni.switchTab({ url: '/pages/home/home' })
|
|
||||||
}).catch(error => {
|
|
||||||
console.error('登录失败', error)
|
|
||||||
requestCaptcha();
|
|
||||||
})
|
|
||||||
.finally(() => loading.value = false);
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestCaptcha = async () => {
|
|
||||||
const response = await get_captcha()
|
|
||||||
console.log('获取验证码', response);
|
|
||||||
const data = response.data;
|
|
||||||
captchaState.value = data;
|
|
||||||
};
|
|
||||||
const navigateTo = (page) => {
|
|
||||||
uni.showToast({
|
|
||||||
title: page+'功能开发中',
|
|
||||||
icon: "none",
|
|
||||||
mask: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.login-container {
|
|
||||||
padding: 60rpx;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.auth-form {
|
|
||||||
margin-top: 40rpx;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.login-btn {
|
|
||||||
margin-top: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-links {
|
|
||||||
margin-top: 40rpx;
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
<template>
|
|
||||||
<app-layout>
|
|
||||||
<template #main>
|
|
||||||
<view class="me-container">
|
|
||||||
<!-- 个人信息卡片 -->
|
|
||||||
<up-card padding="40rpx" margin="0 0 30rpx 0" :shadow="3" :borderRadius="20" :show-head="false">
|
|
||||||
<template #body>
|
|
||||||
<view class="user-info-container">
|
|
||||||
<up-avatar :src="formData.avatar || '/static/logo.png'" shape="circle"
|
|
||||||
size="80" class="user-avatar"></up-avatar>
|
|
||||||
<view class="user-details">
|
|
||||||
<up-text :text="formData.name" bold size="20"></up-text>
|
|
||||||
<up-text :text="formData.username" type="info" margin="10rpx 0 0 0"
|
|
||||||
prefix-icon="account"></up-text>
|
|
||||||
<up-text :text="formData.mobile" type="info" margin="10rpx 0 0 0"
|
|
||||||
prefix-icon="phone"></up-text>
|
|
||||||
</view>
|
|
||||||
<up-button type="primary" size="small" text="个人主页" @click="handleToProfile(formData.id)" class="profile-button"></up-button>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</up-card>
|
|
||||||
|
|
||||||
<!-- 数据统计 -->
|
|
||||||
<up-grid :border="false" col="4" align="center" class="stats-grid">
|
|
||||||
<up-grid-item v-for="item in dataItems" :key="item.title" :border="true" class="stats-item">
|
|
||||||
<view class="stats-content">
|
|
||||||
<view class="stats-value">
|
|
||||||
<up-text :text="item.value" size="22" bold></up-text>
|
|
||||||
</view>
|
|
||||||
<view class="stats-title">
|
|
||||||
<up-text :text="item.title" type="info" ></up-text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</up-grid-item>
|
|
||||||
</up-grid>
|
|
||||||
|
|
||||||
<!-- 功能菜单 -->
|
|
||||||
<view class="menu-section">
|
|
||||||
<up-cell-group>
|
|
||||||
<up-cell title="个人资料" icon="account" isLink @click="handleToDetail(formData.id)"></up-cell>
|
|
||||||
<up-cell title="系统设置" icon="setting" isLink @click="handleToUpdate(formData.id)"></up-cell>
|
|
||||||
<up-cell title="安全中心" icon="lock" isLink @click="handletoPassword()"></up-cell>
|
|
||||||
<up-cell title="消息中心" icon="bell" isLink @click="showContact = true"></up-cell>
|
|
||||||
</up-cell-group>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 退出登录按钮 -->
|
|
||||||
<view class="logout-btn">
|
|
||||||
<up-button type="error" text="退出登录" :loading="loading" @click="handleLogout"></up-button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</app-layout>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, computed, reactive } from 'vue';
|
|
||||||
import { onLoad, onReady, onShow } from '@dcloudio/uni-app';
|
|
||||||
import { logout } from "@/api/apis";
|
|
||||||
import { useUserStore } from '../../stores/index';
|
|
||||||
|
|
||||||
const userStore = useUserStore();
|
|
||||||
const loading = ref(false);
|
|
||||||
|
|
||||||
const formData = ref({
|
|
||||||
id: null,
|
|
||||||
name: "",
|
|
||||||
username: "",
|
|
||||||
available: null,
|
|
||||||
is_superuser: null,
|
|
||||||
avatar: "",
|
|
||||||
dept_name: "",
|
|
||||||
email: "",
|
|
||||||
mobile: "",
|
|
||||||
gender: null, // 0男 1女 2未知
|
|
||||||
description: "",
|
|
||||||
created_at: "",
|
|
||||||
updated_at: "",
|
|
||||||
last_login: "",
|
|
||||||
});
|
|
||||||
// 数据统计
|
|
||||||
const dataItems = ref([
|
|
||||||
{ title: '待办事项', value: '5' },
|
|
||||||
{ title: '消息通知', value: '3' },
|
|
||||||
{ title: '收藏项目', value: '8' },
|
|
||||||
{ title: '已完成', value: '12' }
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
onReady(async () => {
|
|
||||||
loading.value = true;
|
|
||||||
await userStore.getUserInfo();
|
|
||||||
formData.value = userStore.basic_info;
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 添加onShow生命周期钩子
|
|
||||||
onShow(() => {
|
|
||||||
formData.value = userStore.basic_info;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// 弹窗控制
|
|
||||||
const showContact = ref(false)
|
|
||||||
|
|
||||||
// 退出登录
|
|
||||||
const handleLogout = async () => {
|
|
||||||
loading.value = true;
|
|
||||||
logout({ token: userStore.access_token }).then(response => {
|
|
||||||
if (response.status_code == 200) {
|
|
||||||
useUserStore().clear();
|
|
||||||
uni.reLaunch({ url: '/pages/login/login' });
|
|
||||||
}
|
|
||||||
}).catch(error => {
|
|
||||||
console.error('退出登录失败', error)
|
|
||||||
})
|
|
||||||
.finally(() => loading.value = false);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 个人主页按钮点击事件
|
|
||||||
const handleToProfile = () => {
|
|
||||||
uni.navigateTo({ url: `/pages/me/profile` });
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.me-container {
|
|
||||||
padding: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-info-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-avatar {
|
|
||||||
margin-right: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-details {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-button {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
border-radius: 40rpx 0 0 40rpx;
|
|
||||||
width: 160rpx;
|
|
||||||
padding-right: 20rpx;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-item {
|
|
||||||
position: relative;
|
|
||||||
padding: 20rpx;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 20%;
|
|
||||||
width: 1px;
|
|
||||||
height: 60%;
|
|
||||||
background: #ebedf0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-value {
|
|
||||||
margin: 8rpx 0;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-title {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-section {
|
|
||||||
margin: 40rpx 0;
|
|
||||||
background: #ffffff;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logout-btn {
|
|
||||||
padding: 20rpx 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-popup {
|
|
||||||
width: 600rpx;
|
|
||||||
padding: 40rpx;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
position: relative;
|
|
||||||
z-index: 100;
|
|
||||||
|
|
||||||
.popup-header {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.popup-footer {
|
|
||||||
text-align: center;
|
|
||||||
padding: 20rpx 0 0;
|
|
||||||
border-top: 1px solid #eee;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="detail-container">
|
|
||||||
<up-cell-group>
|
|
||||||
<up-cell title="头像" :border="true">
|
|
||||||
<template #right-icon>
|
|
||||||
<up-avatar :src="formData.avatar" shape="circle" size="40" mode="scaleToFill"
|
|
||||||
bgColor="#c0c4cc" color="#ffffff" fontSize="35px" name="level">
|
|
||||||
</up-avatar>
|
|
||||||
</template>
|
|
||||||
</up-cell>
|
|
||||||
<up-cell title="编号" :value="formData.id" :border="true"></up-cell>
|
|
||||||
<up-cell title="用户名" :value="formData.name" :border="true"></up-cell>
|
|
||||||
<up-cell title="账号" :value="formData.username" :border="true"></up-cell>
|
|
||||||
<up-cell title="状态">
|
|
||||||
<template #value>
|
|
||||||
<up-tag :text="formData.available ? '启用' : '禁用'" :type="formData.available ? 'success' : 'warning'" plain plainFill></up-tag>
|
|
||||||
</template>
|
|
||||||
</up-cell>
|
|
||||||
<up-cell title="类型">
|
|
||||||
<template #value>
|
|
||||||
<up-tag :text="formData.is_superuser ? '管理员' : '普通用户'" :type="formData.is_superuser ? 'error' : 'primary'" plain plainFill ></up-tag>
|
|
||||||
</template>
|
|
||||||
</up-cell>
|
|
||||||
<up-cell title="部门" :value="formData.dept_name" :border="true"></up-cell>
|
|
||||||
<up-cell title="邮箱" :value="formData.email" :border="true"></up-cell>
|
|
||||||
<up-cell title="手机号" :value="formData.mobile" :border="true"></up-cell>
|
|
||||||
<up-cell title="性别">
|
|
||||||
<template #value>
|
|
||||||
<up-tag :text="formData.gender==0? '男' : formData.gender==1? '女' : '未知'" :type="formData.gender==0? 'success' : formData.gender==1? 'warning' : 'info'" plain plainFill></up-tag>
|
|
||||||
</template>
|
|
||||||
</up-cell>
|
|
||||||
<up-cell title="描述" :value="formData.description || '暂无描述'" :border="true"></up-cell>
|
|
||||||
<up-cell title="创建时间" :value="formData.created_at" :border="true"></up-cell>
|
|
||||||
<up-cell title="更新时间" :value="formData.updated_at" :border="true"></up-cell>
|
|
||||||
</up-cell-group>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
|
||||||
import { useUserStore } from '../../stores/index';
|
|
||||||
|
|
||||||
const userStore = useUserStore();
|
|
||||||
const loading = ref(false);
|
|
||||||
const formData = ref({
|
|
||||||
id: null,
|
|
||||||
name: "",
|
|
||||||
username: "",
|
|
||||||
available: null,
|
|
||||||
is_superuser: null,
|
|
||||||
avatar: "",
|
|
||||||
dept_name: "",
|
|
||||||
email: "",
|
|
||||||
mobile: "",
|
|
||||||
gender: null, // 0男 1女 2未知
|
|
||||||
description: "",
|
|
||||||
created_at: "",
|
|
||||||
updated_at: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
onLoad(async () => {
|
|
||||||
loading.value = true;
|
|
||||||
await userStore.getUserInfo();
|
|
||||||
formData.value = userStore.basic_info;
|
|
||||||
loading.value = false;
|
|
||||||
})
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.detail-container {
|
|
||||||
padding: 60rpx 60rpx;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
<template>
|
|
||||||
<app-layout>
|
|
||||||
<template #main>
|
|
||||||
<view class="work-container">
|
|
||||||
<!-- 通知栏 -->
|
|
||||||
<up-notice-bar :text="noticeText" bg-color="#f0f7ff" color="#2979ff"></up-notice-bar>
|
|
||||||
|
|
||||||
<!-- 轮播图 -->
|
|
||||||
<view class="swiper-box">
|
|
||||||
<up-swiper :list="swiperList" indicator indicator-pos="bottomCenter" radius="8" />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 常用功能 -->
|
|
||||||
<view class="section-card">
|
|
||||||
<view class="section-header">
|
|
||||||
<up-row customStyle="margin-bottom: 10px">
|
|
||||||
<up-col span="6">
|
|
||||||
<up-text text="常用功能" bold align="left"></up-text>
|
|
||||||
</up-col>
|
|
||||||
<up-col span="6">
|
|
||||||
<up-text type="primary" text="更多" class="more" @click="navigateToMore" align="right" />
|
|
||||||
</up-col>
|
|
||||||
</up-row>
|
|
||||||
</view>
|
|
||||||
<up-grid :col="4" :border="false" align="center">
|
|
||||||
<up-grid-item v-for="(item, index) in commonFunctions" :key="index"
|
|
||||||
@click="handleFunctionClick(item)">
|
|
||||||
<view class="function-item">
|
|
||||||
<up-icon :name="item.icon" :size="22" :color="item.color || '#2979ff'" />
|
|
||||||
<text class="grid-text" margin-top="8" >{{ item.name }}</text>
|
|
||||||
</view>
|
|
||||||
</up-grid-item>
|
|
||||||
</up-grid>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 应用分类 -->
|
|
||||||
<view class="section-card">
|
|
||||||
<up-text text="全部功能" bold></up-text>
|
|
||||||
<view class="section-header">
|
|
||||||
<up-tabs :list="appTabs" @click="handleTabChange" active-color="#2979ff"></up-tabs>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 对应分类内容 -->
|
|
||||||
<up-grid :col="4" :border="false" align="center">
|
|
||||||
<up-grid-item v-for="(app, index) in currentApps" :key="index" @click="handleAppClick(app)">
|
|
||||||
<view class="app-item">
|
|
||||||
<up-icon :name="app.icon" :size="22" :color="app.color || '#2979ff'"/>
|
|
||||||
<text class="grid-text" margin-top="8" >{{ app.name }}</text>
|
|
||||||
</view>
|
|
||||||
</up-grid-item>
|
|
||||||
</up-grid>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</app-layout>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, computed } from 'vue';
|
|
||||||
|
|
||||||
// 常量数据
|
|
||||||
const noticeText = ref('体验公司全系产品 畅谈你的想法');
|
|
||||||
const swiperList = ref([
|
|
||||||
'/static/banner/banner01.jpg',
|
|
||||||
'/static/banner/banner02.jpg',
|
|
||||||
'/static/banner/banner03.jpg'
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 常用功能
|
|
||||||
const commonFunctions = ref([
|
|
||||||
{ name: '审批', icon: 'file-text', color: '#52c41a' },
|
|
||||||
{ name: '公告', icon: 'bell', color: '#faad14' },
|
|
||||||
{ name: '日报', icon: 'edit-pen', color: '#13c2c2' },
|
|
||||||
{ name: '周报', icon: 'calendar', color: '#2f54eb' },
|
|
||||||
{ name: '工资单', icon: 'rmb', color: '#f5222d' },
|
|
||||||
{ name: '待办', icon: 'list-dot', color: '#722ed1' },
|
|
||||||
{ name: '打卡', icon: 'checkmark-circle', color: '#eb2f96' },
|
|
||||||
{ name: '添加', icon: 'plus-circle', color: '#1890ff' }
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 应用分类数据
|
|
||||||
const appTabs = ref([
|
|
||||||
{ name: '关注' },
|
|
||||||
{ name: '推荐' },
|
|
||||||
{ name: '电影' },
|
|
||||||
{ name: '科技' },
|
|
||||||
{ name: '音乐' },
|
|
||||||
{ name: '美食' },
|
|
||||||
{ name: '文化' },
|
|
||||||
{ name: '财经' },
|
|
||||||
{ name: '手工' }
|
|
||||||
]);
|
|
||||||
|
|
||||||
const allApps = ref({
|
|
||||||
office: [
|
|
||||||
{ name: '审批', icon: 'checkmark-circle', color: '#52c41a' },
|
|
||||||
{ name: '日报', icon: 'edit-pen' , color: '#faad14'},
|
|
||||||
{ name: '周报', icon: 'list-dot' , color: '#13c2c2' },
|
|
||||||
{ name: '云文档', icon: 'file-text' , color: '#2f54eb'},
|
|
||||||
{ name: '项目管理', icon: 'grid' , color: '#f5222d'},
|
|
||||||
{ name: '设计工具', icon: 'photo' , color: '#722ed1'},
|
|
||||||
{ name: '分贝通', icon: 'coupon' , color: '#eb2f96'},
|
|
||||||
{ name: '飞书提醒', icon: 'bell', color: '#1890ff' }
|
|
||||||
],
|
|
||||||
collab: [
|
|
||||||
{ name: '项目管理', icon: 'grid', color: '#52c41a' },
|
|
||||||
{ name: '设计工具', icon: 'photo' , color: '#52c41a'},
|
|
||||||
{ name: '分贝通', icon: 'coupon' , color: '#52c41a'},
|
|
||||||
{ name: '飞书提醒', icon: 'bell' , color: '#52c41a'}
|
|
||||||
],
|
|
||||||
finance: [
|
|
||||||
{ name: '工资单', icon: 'rmb' , color: '#2f54eb'},
|
|
||||||
{ name: '报销', icon: 'wallet' , color: '#2f54eb'},
|
|
||||||
{ name: '预算', icon: 'pie-chart' , color: '#2f54eb'}
|
|
||||||
],
|
|
||||||
other: [
|
|
||||||
{ name: '通讯录', icon: 'account' , color: '#eb2f96'},
|
|
||||||
{ name: '设置', icon: 'settings', color: '#eb2f96' }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// 当前选中标签
|
|
||||||
const currentTab = ref(0);
|
|
||||||
const currentApps = computed(() => {
|
|
||||||
// 假设 appTabs 里有 type 属性对应 allApps 的键
|
|
||||||
const type = appTabs.value[currentTab.value].type || 'office';
|
|
||||||
return allApps.value[type] || [];
|
|
||||||
});
|
|
||||||
|
|
||||||
// 事件处理
|
|
||||||
const handleTabChange = (index) => {
|
|
||||||
currentTab.value = index;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFunctionClick = (item) => {
|
|
||||||
console.log('点击功能:', item.name);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAppClick = (app) => {
|
|
||||||
console.log('点击应用:', app.name);
|
|
||||||
};
|
|
||||||
|
|
||||||
const navigateToMore = () => {
|
|
||||||
console.log('跳转到更多页面');
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.work-container {
|
|
||||||
padding: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box {
|
|
||||||
padding: 20rpx;
|
|
||||||
background: #fff;
|
|
||||||
margin: 20rpx;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper-box {
|
|
||||||
margin: 20rpx;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-card {
|
|
||||||
background: #fff;
|
|
||||||
margin: 20rpx;
|
|
||||||
border-radius: 12rpx;
|
|
||||||
padding: 24rpx;
|
|
||||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
|
||||||
|
|
||||||
.section-header {
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.function-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 20rpx 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 16rpx 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-text {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #909399;
|
|
||||||
padding: 10rpx 0 20rpx 0rpx;
|
|
||||||
/* #ifndef APP-PLUS */
|
|
||||||
box-sizing: border-box;
|
|
||||||
/* #endif */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 调整tabs样式 */
|
|
||||||
::v-deep .up-tabs__wrapper {
|
|
||||||
padding: 0 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .up-tabs__item {
|
|
||||||
font-size: 28rpx !important;
|
|
||||||
padding: 20rpx 0 !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
export {};
|
|
||||||
|
|
||||||
declare module "vue" {
|
|
||||||
type Hooks = App.AppInstance & Page.PageInstance;
|
|
||||||
interface ComponentCustomOptions extends Hooks {}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
@@ -1,55 +0,0 @@
|
|||||||
import { defineStore } from "pinia";
|
|
||||||
import { getCurrentUserInfo } from "../api/apis";
|
|
||||||
|
|
||||||
|
|
||||||
export const useUserStore = defineStore('user', {
|
|
||||||
state: () => ({
|
|
||||||
basic_info: {},
|
|
||||||
access_token: uni.getStorageSync('access_token') || '',
|
|
||||||
refresh_token: uni.getStorageSync('refresh_token') || null
|
|
||||||
}),
|
|
||||||
|
|
||||||
getters: {
|
|
||||||
baseInfo: (state) => state.basic_info,
|
|
||||||
accessToken: (state) => state.access_token,
|
|
||||||
refreshToken: (state) => state.refresh_token
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
async getUserInfo() {
|
|
||||||
try {
|
|
||||||
const response = await getCurrentUserInfo();
|
|
||||||
console.log("获取当前用户", response);
|
|
||||||
const result = response.data;
|
|
||||||
this.basic_info = { ...this.basic_info, ...result };
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setToken(new_access_token, new_refresh_token) {
|
|
||||||
if (!new_access_token || !new_refresh_token) return false;
|
|
||||||
try {
|
|
||||||
this.access_token = new_access_token;
|
|
||||||
uni.setStorageSync('access_token', new_access_token);
|
|
||||||
uni.setStorageSync('refresh_token', new_refresh_token);
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('存储token失败:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.basicInfo = {};
|
|
||||||
this.access_token = null;
|
|
||||||
this.refresh_token = null;
|
|
||||||
try {
|
|
||||||
uni.removeStorageSync('access_token');
|
|
||||||
uni.removeStorageSync('refresh_token');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('清除存储信息失败:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* 这里是uni-app内置的常用样式变量
|
|
||||||
*
|
|
||||||
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
|
||||||
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
|
||||||
*
|
|
||||||
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 颜色变量 */
|
|
||||||
|
|
||||||
/* 行为相关颜色 */
|
|
||||||
$uni-color-primary: #007aff;
|
|
||||||
$uni-color-success: #4cd964;
|
|
||||||
$uni-color-warning: #f0ad4e;
|
|
||||||
$uni-color-error: #dd524d;
|
|
||||||
|
|
||||||
/* 文字基本颜色 */
|
|
||||||
$uni-text-color: #333; // 基本色
|
|
||||||
$uni-text-color-inverse: #fff; // 反色
|
|
||||||
$uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息
|
|
||||||
$uni-text-color-placeholder: #808080;
|
|
||||||
$uni-text-color-disable: #c0c0c0;
|
|
||||||
|
|
||||||
/* 背景颜色 */
|
|
||||||
$uni-bg-color: #fff;
|
|
||||||
$uni-bg-color-grey: #f8f8f8;
|
|
||||||
$uni-bg-color-hover: #f1f1f1; // 点击状态颜色
|
|
||||||
$uni-bg-color-mask: rgba(0, 0, 0, 0.4); // 遮罩颜色
|
|
||||||
|
|
||||||
/* 边框颜色 */
|
|
||||||
$uni-border-color: #c8c7cc;
|
|
||||||
|
|
||||||
/* 尺寸变量 */
|
|
||||||
|
|
||||||
/* 文字尺寸 */
|
|
||||||
$uni-font-size-sm: 12px;
|
|
||||||
$uni-font-size-base: 14px;
|
|
||||||
$uni-font-size-lg: 16;
|
|
||||||
|
|
||||||
/* 图片尺寸 */
|
|
||||||
$uni-img-size-sm: 20px;
|
|
||||||
$uni-img-size-base: 26px;
|
|
||||||
$uni-img-size-lg: 40px;
|
|
||||||
|
|
||||||
/* Border Radius */
|
|
||||||
$uni-border-radius-sm: 2px;
|
|
||||||
$uni-border-radius-base: 3px;
|
|
||||||
$uni-border-radius-lg: 6px;
|
|
||||||
$uni-border-radius-circle: 50%;
|
|
||||||
|
|
||||||
/* 水平间距 */
|
|
||||||
$uni-spacing-row-sm: 5px;
|
|
||||||
$uni-spacing-row-base: 10px;
|
|
||||||
$uni-spacing-row-lg: 15px;
|
|
||||||
|
|
||||||
/* 垂直间距 */
|
|
||||||
$uni-spacing-col-sm: 4px;
|
|
||||||
$uni-spacing-col-base: 8px;
|
|
||||||
$uni-spacing-col-lg: 12px;
|
|
||||||
|
|
||||||
/* 透明度 */
|
|
||||||
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
|
||||||
|
|
||||||
/* 文章场景相关 */
|
|
||||||
$uni-color-title: #2c405a; // 文章标题颜色
|
|
||||||
$uni-font-size-title: 20px;
|
|
||||||
$uni-color-subtitle: #555; // 二级标题颜色
|
|
||||||
$uni-font-size-subtitle: 18px;
|
|
||||||
$uni-color-paragraph: #3f536e; // 文章段落颜色
|
|
||||||
$uni-font-size-paragraph: 15px;
|
|
||||||
|
|
||||||
@import 'uview-plus/theme.scss'; // 引入uview-plus的scss变量
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
import { useUserStore } from "../stores/index";
|
|
||||||
|
|
||||||
export function request(options) {
|
|
||||||
const userStore = useUserStore();
|
|
||||||
uni.showToast({
|
|
||||||
title: "加载中...",
|
|
||||||
icon: "loading",
|
|
||||||
mask: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
// 普通请求处理
|
|
||||||
uni.request({
|
|
||||||
url: import.meta.env.VITE_API_BASE_URL + options.url,
|
|
||||||
method: options.method || "GET",
|
|
||||||
data: options.data || "",
|
|
||||||
header: {
|
|
||||||
Authorization: userStore.access_token ? `Bearer ${userStore.access_token}` : "",
|
|
||||||
...(options.header || {}),
|
|
||||||
},
|
|
||||||
timeout: import.meta.env.VITE_TIMEOUT,
|
|
||||||
success: (res) => {
|
|
||||||
if (res.data.status_code === 200) {
|
|
||||||
uni.showToast({
|
|
||||||
title: res.data.msg,
|
|
||||||
icon: "success",
|
|
||||||
mask: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
resolve(res.data);
|
|
||||||
} else if (res.data.status_code === 401) {
|
|
||||||
uni.showToast({
|
|
||||||
title: res.data.msg || "未登录",
|
|
||||||
icon: "none",
|
|
||||||
mask: true,
|
|
||||||
});
|
|
||||||
userStore.clear();
|
|
||||||
uni.reLaunch({ url: "/pages/login/login" });
|
|
||||||
reject(res.data);
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: res.data.msg || "请求发生异常",
|
|
||||||
icon: "none",
|
|
||||||
mask: true,
|
|
||||||
});
|
|
||||||
reject(res.data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fail: (error) => {
|
|
||||||
uni.showToast({
|
|
||||||
title: "请求异常",
|
|
||||||
icon: "none",
|
|
||||||
mask: true,
|
|
||||||
});
|
|
||||||
reject(error);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import { fileURLToPath, URL } from 'node:url'
|
|
||||||
import { defineConfig } from "vite";
|
|
||||||
import uni from "@dcloudio/vite-plugin-uni";
|
|
||||||
import UnoCSS from 'unocss/vite'
|
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [
|
|
||||||
uni(),
|
|
||||||
UnoCSS(),
|
|
||||||
],
|
|
||||||
server: {
|
|
||||||
host: "0.0.0.0",
|
|
||||||
port: 5181,
|
|
||||||
proxy: {
|
|
||||||
[process.env.VITE_API_BASE_NAME]: {
|
|
||||||
target: process.env.VITE_API_BASE_URL,
|
|
||||||
secure: false, // 请求是否为https
|
|
||||||
changeOrigin: true, // 是否跨域
|
|
||||||
rewrite: (path) => path.replace(/^\/api/, ""),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||