# easy_mg
**Repository Path**: jiu--qi/easy_mg
## Basic Information
- **Project Name**: easy_mg
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: devops
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-03-18
- **Last Updated**: 2026-03-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Easy 资产台账管理系统
**基于 FastAPI 的轻量级企业资产管理解决方案**
[](https://www.python.org/)
[](https://fastapi.tiangolo.com/)
[](https://sqlmodel.tiangolo.com/)
[](LICENSE)
---
## 📋 目录
- [产品简介](#-产品简介)
- [核心功能](#-核心功能)
- [技术架构](#-技术架构)
- [快速开始](#-快速开始)
- [API 文档](#-api-文档)
- [使用指南](#-使用指南)
- [部署说明](#-部署说明)
- [常见问题](#-常见问题)
---
## 🎯 产品简介
**Easy 资产台账管理系统**(easy_mg)是一款专为企业设计的现代化资产管理工具,提供高效、安全、易用的资产全生命周期管理功能。
### 适用场景
- ✅ 企业固定资产管理
- ✅ IT 设备追踪与管理
- ✅ 办公设施登记与维护
- ✅ 资产状态变更历史记录
### 目标用户
- 企业资产管理员
- IT 设备管理人员
- 行政后勤管理人员
- 系统管理员
### 核心价值
- **简洁高效**:RESTful API 设计,前后端分离架构
- **安全可靠**:JWT 认证 + bcrypt 密码加密,多重安全保障
- **可追溯性**:完整的资产变更日志,支持状态流转追踪
- **易于部署**:Docker 容器化支持,一键快速部署
---
## ✨ 核心功能
### 1. 资产管理
#### 基础信息
- 资产名称、类别、价格、购买日期、备注
- 支持资产的增删改查(CRUD)操作
- 关键字模糊搜索(名称/类别)
#### 状态管理
系统内置四种资产状态,严格的状态机流转控制:
| 状态代码 | 中文含义 | 描述 |
|---------|---------|------|
| `IDLE` | 闲置 | 未分配,可用状态 |
| `IN_USE` | 使用中 | 已分配给人员使用 |
| `REPAIR` | 维修中 | 故障维修状态 |
| `SCRAPPED` | 已报废 | 终态,不可恢复 |
**状态流转规则**:
```
闲置 (IDLE) → 使用中/维修中/已报废
使用中 (IN_USE) → 闲置/维修中/已报废
维修中 (REPAIR) → 闲置/已报废
已报废 (SCRAPPED) → 无(终态)
```
### 2. 日志追踪
- 自动记录每次资产状态变更
- 记录操作人、变更时间、变更原因
- 支持查看单个资产的完整历史轨迹
### 3. 用户认证
- OAuth2 Password Bearer Token 认证
- JWT 令牌机制(默认 30 分钟有效期)
- bcrypt 密码哈希加密存储
- 启动时自动创建 admin 管理员账户
---
## 🏗️ 技术架构
### 系统架构图
```
┌─────────────┐
│ 客户端 │
│ (浏览器/APP) │
└──────┬──────┘
│ HTTP/HTTPS
▼
┌─────────────────────────────────────┐
│ FastAPI Application │
│ ┌───────────────────────────────┐ │
│ │ API Routes (v1) │ │
│ │ • /api/v1/login/access-token │ │
│ │ • /api/v1/assets/* │ │
│ └──────────────┬────────────────┘ │
│ │ │
│ ┌──────────────▼────────────────┐ │
│ │ Services (Business) │ │
│ │ • AssetService │ │
│ │ • 状态机验证 │ │
│ └──────────────┬────────────────┘ │
│ │ │
│ ┌──────────────▼────────────────┐ │
│ │ Models & Schemas (Data) │ │
│ │ • SQLModel ORM │ │
│ │ • Pydantic Validation │ │
│ └──────────────┬────────────────┘ │
└─────────────────┼─────────────────┘
│
▼
┌─────────────────┐
│ MySQL 数据库 │
│ • asset 表 │
│ • assetlog 表 │
│ • user 表 │
└─────────────────┘
```
### 技术栈详情
#### 后端技术
| 组件 | 版本 | 用途 |
|------|------|------|
| **框架** | FastAPI 0.110.0+ | Web 框架 |
| **ASGI 服务器** | Uvicorn (standard) | 应用服务器 |
| **ORM** | SQLModel 0.0.14+ | 数据库模型与 ORM |
| **数据验证** | Pydantic 2.6.0+ | 请求/响应校验 |
| **数据库驱动** | PyMySQL 1.1.0+ | MySQL 连接 |
| **安全认证** | python-jose | JWT 生成解析 |
| **密码加密** | passlib[bcrypt] | 密码哈希 |
| **配置管理** | python-dotenv | 环境变量加载 |
#### 前端技术(可选 UI)
| 组件 | 版本 | 用途 |
|------|------|------|
| **框架** | Vue 3 | 前端框架 |
| **构建工具** | Vite | 快速开发构建 |
| **语言** | TypeScript | 类型安全 |
| **UI 组件** | 自定义组件 | 业务组件 |
### 项目结构
```
easy_mg/
├── app/ # 后端应用主目录
│ ├── api/v1/ # API 路由层
│ │ ├── assets.py # 资产管理接口
│ │ └── login.py # 认证登录接口
│ ├── core/ # 核心配置与安全
│ │ ├── config.py # 系统配置
│ │ └── security.py # 安全认证工具
│ ├── db/ # 数据库相关
│ │ └── session.py # 会话管理
│ ├── models/ # 数据模型
│ │ ├── asset.py # 资产模型
│ │ ├── asset_log.py # 日志模型
│ │ └── user.py # 用户模型
│ ├── schemas/ # Pydantic 模式
│ │ ├── asset.py # 资产 Schema
│ │ └── user.py # 用户 Schema
│ ├── services/ # 业务逻辑层
│ │ └── asset_service.py # 资产服务
│ ├── __init__.py
│ └── main.py # 应用入口
├── easy_mg_ui/ # 前端 UI 项目
│ └── src/ # 源代码
├── Dockerfile # Docker 构建文件
├── init_db.sql # 数据库初始化脚本
└── README.md # 本文档
```
---
## 🚀 快速开始
### 环境要求
- **Python**: 3.11+
- **MySQL**: 5.7+ 或 8.0+
- **Node.js**: 18+(可选,仅开发前端 UI)
- **Docker**: 20+(可选,用于容器化部署)
### 方式一:本地开发环境
#### 1. 克隆项目
```bash
git clone
cd easy_mg
```
#### 2. 安装 Python 依赖
```bash
# 创建虚拟环境
python -m venv venv
# 激活虚拟环境
# Windows:
venv\Scripts\activate
# Linux/Mac:
source venv/bin/activate
# 安装依赖
pip install -r requirements.txt
```
#### 3. 配置环境变量
在项目根目录创建 `.env` 文件:
```bash
# MySQL 数据库配置
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=your_password
MYSQL_DB=easy_assets
# JWT 配置
JWT_SECRET=your-secret-key-change-me
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
# CORS 跨域配置(多个用逗号分隔)
CORS_ORIGINS=http://localhost:3000,http://localhost:5173
```
> ⚠️ **重要**:生产环境务必修改默认 `JWT_SECRET`!
#### 4. 初始化数据库
```bash
# 登录 MySQL 并执行初始化脚本
mysql -u root -p < init_db.sql
```
或者手动执行 SQL:
```sql
CREATE DATABASE IF NOT EXISTS `easy_assets` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
#### 5. 启动服务
```bash
# 开发模式(支持热重载)
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
# 生产模式
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
```
访问 `http://localhost:8000/docs` 查看 API 文档。
### 方式二:Docker 部署
#### 1. 构建镜像
```bash
docker build -t easy_mg .
```
#### 2. 运行容器
```bash
docker run -d \
--name easy_mg \
-p 8000:8000 \
-e MYSQL_HOST=127.0.0.1 \
-e MYSQL_PORT=3306 \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=your_password \
-e JWT_SECRET=your-secret-key \
easy_mg
```
#### 3. 查看日志
```bash
docker logs -f easy_mg
```
### 方式三:前端 UI 开发(可选)
```bash
cd easy_mg_ui
# 安装依赖
npm install
# 开发模式
npm run dev
# 构建生产版本
npm run build
```
---
## 📖 API 文档
### 在线文档
启动服务后访问:
- **Swagger UI**: http://localhost:8000/docs
- **ReDoc**: http://localhost:8000/redoc
### 认证接口
#### 获取访问令牌
```http
POST /api/v1/login/access-token
Content-Type: application/json
{
"username": "admin",
"password": "123456"
}
```
**响应示例**:
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}
```
### 资产管理接口
所有资产接口需要在 Header 中添加认证:
```
Authorization: Bearer
```
#### 1. 获取资产列表
```http
GET /api/v1/assets?skip=0&limit=20&keyword=电脑
```
**查询参数**:
- `skip`: 跳过记录数(默认 0)
- `limit`: 返回数量(1-200,默认 20)
- `keyword`: 搜索关键词(可选)
**响应示例**:
```json
[
{
"id": 1,
"name": "联想笔记本 T14",
"category": "电脑",
"price": 8200.00,
"buy_date": "2025-04-15",
"remark": "研发部备用",
"status": "IDLE",
"created_at": "2025-01-15T10:30:00",
"updated_at": "2025-01-15T10:30:00"
}
]
```
#### 2. 创建资产
```http
POST /api/v1/assets
Content-Type: application/json
{
"name": "HP 打印机",
"category": "办公设备",
"price": 2800.00,
"buy_date": "2024-08-10",
"remark": "耗材充足",
"status": "IDLE"
}
```
#### 3. 获取资产详情
```http
GET /api/v1/assets/{asset_id}
```
#### 4. 更新资产
```http
PUT /api/v1/assets/{asset_id}
Content-Type: application/json
{
"name": "HP 打印机 M404",
"status": "IN_USE",
"reason": "分配给财务部使用"
}
```
> ⚠️ **注意**:状态变更时必须提供 `reason` 字段说明变更原因。
#### 5. 删除资产
```http
DELETE /api/v1/assets/{asset_id}
```
> ⚠️ **警告**:删除资产会同时删除其所有关联的日志记录!
#### 6. 获取资产日志
```http
GET /api/v1/assets/{asset_id}/logs
```
**响应示例**:
```json
[
{
"id": 1,
"asset_id": 1,
"operator_username": "admin",
"old_status": "IDLE",
"new_status": "IN_USE",
"reason": "分配给设计师使用",
"created_at": "2025-01-15T14:30:00"
}
]
```
### 状态码说明
| 状态码 | 含义 | 说明 |
|-------|------|------|
| 200 | OK | 请求成功 |
| 201 | Created | 资源创建成功 |
| 204 | No Content | 删除成功 |
| 400 | Bad Request | 请求参数错误(如非法状态流转) |
| 401 | Unauthorized | 未授权,需要登录 |
| 404 | Not Found | 资源不存在 |
---
## 💡 使用指南
### 典型工作流程
#### 场景 1:新员工入职配发电脑
```
1. 采购新电脑 → 状态:IDLE(闲置)
2. 分配给员工 → 变更为:IN_USE(使用中)
原因:分配给张三使用
3. 日常使用中 → 保持:IN_USE
4. 出现故障 → 变更为:REPAIR(维修中)
原因:屏幕闪烁送修
5. 维修完成 → 变更为:IDLE 或 IN_USE
原因:维修完成归还
```
#### 场景 2:资产报废流程
```
1. 资产损坏评估 → 从任意状态变更为:SCRAPPED
原因:严重损坏无法修复
2. 进入终态 → 不可再变更
```
### 最佳实践
#### ✅ 推荐做法
1. **规范命名**:资产名称应包含品牌、型号、关键特征
- 好:`联想 ThinkPad T14 16G/512G`
- 差:`笔记本电脑`
2. **详细记录**:状态变更时填写具体原因
- 好:`分配给财务部李四使用`
- 差:`使用`
3. **定期盘点**:利用搜索功能按类别筛选资产
4. **及时更新**:资产状态变化后立即更新系统
#### ❌ 避免行为
1. 不要跳过状态直接变更(如 IDLE → SCRAPPED 需合理理由)
2. 不要删除仍有使用价值的资产记录
3. 不要共享 admin 账号,建议为不同管理员创建独立账号
### 高级技巧
#### 批量导入资产
通过循环调用创建接口实现批量导入:
```python
import requests
assets = [
{"name": "资产 1", "category": "电脑", "price": 5000, ...},
{"name": "资产 2", "category": "设备", "price": 3000, ...},
# ...
]
token = "your_access_token"
headers = {"Authorization": f"Bearer {token}"}
for asset in assets:
response = requests.post(
"http://localhost:8000/api/v1/assets",
json=asset,
headers=headers
)
print(f"创建 {asset['name']}: {response.status_code}")
```
#### 导出资产数据
```python
response = requests.get(
"http://localhost:8000/api/v1/assets?limit=200",
headers=headers
)
assets = response.json()
# 导出为 CSV
import csv
with open('assets.csv', 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=assets[0].keys())
writer.writeheader()
writer.writerows(assets)
```
---
## 🛠️ 部署说明
### 生产环境配置
#### 1. 环境变量优化
```bash
# .env.production
MYSQL_HOST=production-db.example.com
MYSQL_PORT=3306
MYSQL_USER=easy_assets_user
MYSQL_PASSWORD=strong-password-here
MYSQL_DB=easy_assets_prod
JWT_SECRET=super-long-random-secret-key-32-chars-min
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=60
CORS_ORIGINS=https://assets.yourcompany.com
```
#### 2. 使用 Gunicorn 管理多进程
```bash
pip install gunicorn
gunicorn app.main:app \
--bind 0.0.0.0:8000 \
--workers 4 \
--worker-class uvicorn.workers.UvicornWorker \
--timeout 120
```
#### 3. Nginx 反向代理配置
```nginx
server {
listen 80;
server_name assets.yourcompany.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# HTTPS 重定向(推荐)
# return 301 https://$server_name$request_uri;
}
# HTTPS 配置(强烈推荐生产环境使用)
server {
listen 443 ssl http2;
server_name assets.yourcompany.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
### Docker Compose 部署(推荐)
创建 `docker-compose.yml`:
```yaml
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: easy_mysql
environment:
MYSQL_ROOT_PASSWORD: your-root-password
MYSQL_DATABASE: easy_assets
MYSQL_USER: easy_user
MYSQL_PASSWORD: easy_password
volumes:
- mysql_data:/var/lib/mysql
- ./init_db.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "3306:3306"
networks:
- easy_network
backend:
build: .
container_name: easy_backend
environment:
MYSQL_HOST: mysql
MYSQL_PORT: 3306
MYSQL_USER: easy_user
MYSQL_PASSWORD: easy_password
MYSQL_DB: easy_assets
JWT_SECRET: your-production-secret-key
ACCESS_TOKEN_EXPIRE_MINUTES: 60
CORS_ORIGINS: "*"
depends_on:
- mysql
ports:
- "8000:8000"
networks:
- easy_network
frontend:
build: ./easy_mg_ui
container_name: easy_frontend
ports:
- "80:80"
depends_on:
- backend
networks:
- easy_network
volumes:
mysql_data:
networks:
easy_network:
driver: bridge
```
启动服务:
```bash
docker-compose up -d
```
### 监控与日志
#### 健康检查端点
```http
GET /health
```
#### 应用日志
```bash
# Docker 日志
docker logs -f easy_backend
# Systemd 服务日志
journalctl -u easy_mg -f
```
---
## ❓ 常见问题
### Q1: 忘记密码怎么办?
**A**: 目前版本需要手动重置数据库密码:
```sql
UPDATE user
SET hashed_password = '<新的 bcrypt 哈希值>'
WHERE username = 'admin';
```
可使用 Python 生成哈希:
```python
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"])
hashed = pwd_context.hash("新密码")
print(hashed)
```
### Q2: 如何修改默认 Token 过期时间?
**A**: 修改环境变量 `ACCESS_TOKEN_EXPIRE_MINUTES`(单位:分钟),重启服务生效。
### Q3: 资产误删了能恢复吗?
**A**: 当前版本不支持回收站功能。建议:
- 定期备份数据库
- 使用状态标记代替物理删除(如新增 DELETED 状态)
- 开启数据库 binlog 进行时间点恢复
### Q4: 如何添加新用户?
**A**: 当前版本仅在启动时创建 admin 用户。如需多用户支持,可:
方法 1:直接插入数据库
```sql
INSERT INTO user (username, hashed_password)
VALUES ('newuser', '');
```
方法 2:扩展 API(需二次开发)
### Q5: 状态变更提示"非法的状态流转"?
**A**: 系统严格执行状态机规则,请参考前文的状态流转图。常见错误:
- ❌ SCRAPPED → IDLE(已报废不能恢复)
- ❌ REPAIR → IN_USE(维修中应先回到 IDLE)
### Q6: CORS 跨域错误如何解决?
**A**: 修改 `.env` 中的 `CORS_ORIGINS`:
```bash
# 允许多个域名
CORS_ORIGINS=http://localhost:3000,http://localhost:5173
# 允许所有(仅开发环境)
CORS_ORIGINS=*
```
### Q7: 数据库连接失败?
**A**: 检查以下项:
1. MySQL 服务是否运行
2. 环境变量配置是否正确
3. 数据库是否已创建
4. 用户权限是否足够
5. 防火墙是否开放 3306 端口
---
## 📝 更新日志
### v0.1.0 (当前版本)
- ✅ 初始版本发布
- ✅ 资产管理 CRUD 功能
- ✅ 状态机流转控制
- ✅ 变更日志记录
- ✅ JWT 认证系统
- ✅ 基础前端 UI
- ✅ Docker 部署支持
### 计划中功能
- [ ] 多用户管理与角色权限
- [ ] 批量导入导出
- [ ] 统计报表与图表
- [ ] 邮件通知提醒
- [ ] 移动端适配
---
## 🤝 贡献指南
欢迎提交 Issue 和 Pull Request!
1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 开启 Pull Request
---
## 📄 开源协议
MIT License - 详见 [LICENSE](LICENSE) 文件
---
## 📧 联系方式
- **项目作者**: Jiuqi
---
**如果这个项目对你有帮助,请给一个 ⭐ Star 支持!**
Made with ❤️ by Easy MG Team