Files
palladium-monitor/ticket-system/README.md
T
AI Agent 26940c4574 feat: initial commit - lightweight ticket system with Flask+SQLite
Features:
- User authentication (login/register)
- Ticket CRUD with status/priority/category
- Rich text description with paste-to-image
- File attachment upload (images/documents)
- Multi-select CC recipients
- Role-based permission control (admin/user)
- In-app notifications
- Statistics dashboard
- Gunicorn production deployment
2026-07-02 15:31:27 +08:00

237 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 工单系统 (Ticket System)
轻量级工单系统,基于 Flask + SQLite,适合个人或小团队使用。
## 功能特性
### 工单管理
- 创建、编辑、删除、关闭工单
- 状态流转:新建 → 进行中 → 待处理 → 已完成 → 已关闭
- 分类管理:技术故障、功能需求、咨询、事件处理、其他
- 优先级设置:低、中、高、紧急
- 自由标签支持
### 富文本描述
- **内容可编辑**contenteditable 富文本编辑器
- **图片内联显示**:支持 Ctrl+V 粘贴截图,图片直接嵌入描述中
- **插入图片按钮**:📎 点击选择图片上传
- **基础格式**:支持加粗、斜体
- **粘贴上传**:粘贴的图片会自动上传到服务器
### 附件管理
- 支持多种文件类型:图片、文档、压缩包等
- 最大文件大小:20 MB
- 图片预览:支持点击放大查看
- 附件下载:点击即可下载
### 用户系统
- 用户注册、登录、登出
- 默认管理员账号:`admin / admin`
- 密码安全存储(哈希)
### 权限控制
- **管理员**:可查看所有工单
- **普通用户**:只能查看自己参与(提交人/处理人/抄送人)的工单
- 无权限访问时返回 403 错误
### 抄送功能
- 支持多选抄送人
- 自定义下拉选择器
- 抄送人自动收到通知
- 抄送人可查看工单和附件
### 通知系统
- 站内通知:工单分配、评论、关闭等操作自动通知相关人员
- 未读角标:导航栏显示未读通知数量
- 通知列表:可查看通知详情
### 统计看板
- 工单总数统计
- 按状态、优先级、分类聚合
- 最近工单列表
- 我的工单计数
## 技术栈
- **后端**Flask + SQLAlchemy
- **数据库**SQLite
- **前端**Jinja2 模板 + 原生 JavaScript
- **部署**Gunicorn + systemd
## 快速开始
### 安装依赖
```bash
pip install -r requirements.txt --break-system-packages
```
### 启动开发服务器
```bash
python app.py
```
### 启动生产服务器
```bash
gunicorn --workers 2 --bind 0.0.0.0:5000 wsgi:app
```
### 访问系统
打开浏览器访问:`http://localhost:5000`
默认管理员账号:
- 用户名:`admin`
- 密码:`admin`
## 项目结构
```
ticket-system/
├── app.py # Flask 主程序(模型 + 路由)
├── wsgi.py # Gunicorn WSGI 入口
├── requirements.txt # 依赖列表
├── README.md # 项目说明
├── instance/
│ └── tickets.db # SQLite 数据库(自动创建)
├── uploads/ # 上传文件目录
│ └── <ticket_id>/ # 每个工单独立的附件目录
├── templates/ # Jinja2 模板
│ ├── base.html # 基础布局模板
│ ├── login.html # 登录页
│ ├── register.html # 注册页
│ ├── dashboard.html # 统计看板
│ ├── ticket_list.html # 工单列表
│ ├── ticket_form.html # 新建/编辑工单
│ ├── ticket_detail.html # 工单详情
│ ├── notifications.html # 通知列表
│ └── error.html # 错误页
└── static/
└── style.css # 样式文件
```
## 数据模型
### User(用户)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Integer | 主键 |
| username | String(80) | 用户名(唯一) |
| password_hash | String(200) | 密码哈希 |
| role | String(20) | 角色(admin/user |
| created_at | DateTime | 创建时间 |
### Ticket(工单)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Integer | 主键 |
| title | String(200) | 标题 |
| description | Text | 描述(支持 HTML |
| status | String(20) | 状态 |
| priority | String(20) | 优先级 |
| category | String(20) | 分类 |
| assignee | String(100) | 处理人 |
| requester | String(100) | 提交人 |
| cc_users | String(500) | 抄送人(逗号分隔) |
| tags | String(500) | 标签(逗号分隔) |
| created_at | DateTime | 创建时间 |
| updated_at | DateTime | 更新时间 |
### Comment(评论)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Integer | 主键 |
| ticket_id | Integer | 所属工单 |
| author | String(100) | 评论人 |
| content | Text | 评论内容 |
| created_at | DateTime | 创建时间 |
### Attachment(附件)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Integer | 主键 |
| ticket_id | Integer | 所属工单 |
| filename | String(200) | 存储文件名(UUID |
| original_name | String(300) | 原始文件名 |
| content_type | String(100) | MIME 类型 |
| size | Integer | 文件大小(字节) |
| is_image | Boolean | 是否为图片 |
| uploaded_by | String(100) | 上传人 |
| uploaded_at | DateTime | 上传时间 |
### Notification(通知)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Integer | 主键 |
| user_id | Integer | 接收用户 |
| title | String(200) | 通知标题 |
| content | Text | 通知内容 |
| ticket_id | Integer | 关联工单 |
| read | Boolean | 是否已读 |
| created_at | DateTime | 创建时间 |
## 部署说明
### systemd 服务部署
1. 创建服务文件:`/etc/systemd/system/ticket-system.service`
```ini
[Unit]
Description=Ticket System
After=network.target
[Service]
Type=exec
WorkingDirectory=/path/to/ticket-system
Environment="PATH=/usr/local/bin:/usr/bin:/bin"
Environment="PYTHONUNBUFFERED=1"
ExecStart=/usr/local/bin/gunicorn --workers 2 --bind 0.0.0.0:5000 --access-logfile /var/log/ticket-system/access.log --error-logfile /var/log/ticket-system/error.log wsgi:app
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
```
2. 创建日志目录
```bash
mkdir -p /var/log/ticket-system
```
3. 启动服务
```bash
systemctl daemon-reload
systemctl enable --now ticket-system
systemctl status ticket-system
```
### Nginx 反向代理(可选)
```nginx
server {
listen 80;
server_name ticket.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /uploads/ {
alias /path/to/ticket-system/uploads/;
}
}
```
## 注意事项
1. **首次启动**:会自动创建默认管理员账号(admin/admin
2. **数据库迁移**:新增字段需要手动添加到 SQLite 数据库
3. **文件上传**:需要确保 `uploads/` 目录存在且可写
4. **安全配置**:生产环境请修改 `SECRET_KEY` 和默认管理员密码
5. **最大上传大小**:默认 20 MB,可在 `app.py` 中修改 `MAX_CONTENT_LENGTH`
## 许可证
MIT License