146 lines
4.9 KiB
Markdown
146 lines
4.9 KiB
Markdown
:::tip 文件模板
|
||
文件模板模块用于管理系统中的文件模板,如导入导出模板、报表模板等。支持模板文件上传、按编码查询、文件 URL 自动转换等功能。
|
||
:::
|
||
|
||
## 模块结构
|
||
|
||
```
|
||
src/modules/file_template/
|
||
├── models.py # 文件模板模型
|
||
├── schema.py # 表单验证(WTForms)
|
||
├── repository.py # 数据访问层
|
||
├── service.py # 业务逻辑层(继承 BaseService)
|
||
└── router.py # 路由控制器
|
||
```
|
||
|
||
## 文件模板模型
|
||
|
||
```python
|
||
# src/modules/file_template/models.py
|
||
class FileTemplate(BaseModel, BaseDB):
|
||
"""
|
||
文件模板模型
|
||
|
||
用于存储文件模板信息,如:导入导出模板、报表模板等。
|
||
"""
|
||
__tablename__ = DB_PREFIX + "file_template"
|
||
__table_comment__ = "文件模板表"
|
||
|
||
# 模板名称
|
||
name = db.Column(db.String(100), nullable=True, index=True, comment="模板名称")
|
||
# 模板编码(唯一标识,用于程序化查询)
|
||
code = db.Column(db.String(50), nullable=False, index=True, comment="模板编码")
|
||
# 文件名称(原始文件名)
|
||
file_name = db.Column(db.String(255), nullable=True, comment="文件名称")
|
||
# 文件路径(存储相对路径,如 /file_template/xxx.xlsx)
|
||
file_path = db.Column(db.String(255), nullable=True, comment="文件路径")
|
||
# 备注
|
||
note = db.Column(db.String(255), nullable=True, comment="文件模板备注")
|
||
# 排序
|
||
sort = db.Column(db.Integer, nullable=False, default=0, server_default=text('0'),
|
||
comment="文件模板顺序")
|
||
```
|
||
|
||
## 服务层特色
|
||
|
||
文件模板服务继承 `BaseService`,通过钩子实现文件处理和 URL 转换:
|
||
|
||
```python
|
||
# src/modules/file_template/service.py
|
||
class FileTemplateService(BaseService):
|
||
repository = FileTemplateRepository
|
||
form = FileTemplateForm
|
||
model_name = "模板"
|
||
|
||
@classmethod
|
||
def before_add(cls, form):
|
||
"""新增前钩子:保存模板文件"""
|
||
_handle_template_file(form)
|
||
|
||
@classmethod
|
||
def before_update(cls, form, obj):
|
||
"""更新前钩子:保存模板文件"""
|
||
_handle_template_file(form)
|
||
|
||
@classmethod
|
||
def _detail_dict(cls, obj):
|
||
"""详情序列化:文件路径转换为可访问URL"""
|
||
data = model_to_dict(obj)
|
||
data["filePath"] = get_file_url(data.get("filePath"))
|
||
return data
|
||
|
||
@classmethod
|
||
def _enrich_page_records(cls, records):
|
||
"""分页富化:文件路径转换为可访问URL"""
|
||
for record in records:
|
||
record["filePath"] = get_file_url(record.get("filePath"))
|
||
return records
|
||
|
||
@classmethod
|
||
def get_by_code(cls, code):
|
||
"""按模板编码查询(用于程序化获取模板)"""
|
||
obj = cls.repository.first_by({"code": code})
|
||
return cls._detail_dict(obj) if obj else None
|
||
```
|
||
|
||
### 文件处理流程
|
||
|
||
```
|
||
前端上传临时文件 → 获得临时 URL(如 /temp/xxx.xlsx)
|
||
↓
|
||
提交表单(filePath 携带临时 URL)
|
||
↓
|
||
Service before_add/before_update 钩子
|
||
↓
|
||
save_file(filePath, "file_template")
|
||
↓
|
||
临时文件迁移到正式目录(upload/file_template/)
|
||
↓
|
||
数据库存相对路径
|
||
↓
|
||
查询时 get_file_url 拼接完整访问地址
|
||
```
|
||
|
||
### 按编码查询
|
||
|
||
`get_by_code` 方法用于程序化获取模板,返回与详情一致的序列化结构:
|
||
|
||
```python
|
||
# 按编码获取导入模板
|
||
template = FileTemplateService.get_by_code("user_import_template")
|
||
if template:
|
||
download_url = template["filePath"] # 已转为完整 URL
|
||
```
|
||
|
||
## API 接口
|
||
|
||
| 方法 | 路径 | 权限节点 | 说明 |
|
||
|:---|:---|:---|:---|
|
||
| GET | `/api/v1/fileTemplate/page` | `sys:fileTemplate:page` | 分页查询 |
|
||
| GET | `/api/v1/fileTemplate/detail/<id>` | `sys:fileTemplate:detail` | 详情查询 |
|
||
| GET | `/api/v1/fileTemplate/code/<code>` | - | 按编码查询 |
|
||
| POST | `/api/v1/fileTemplate/add` | `sys:fileTemplate:add` | 新增模板 |
|
||
| PUT | `/api/v1/fileTemplate/update` | `sys:fileTemplate:update` | 编辑模板 |
|
||
| DELETE | `/api/v1/fileTemplate/delete/<id>` | `sys:fileTemplate:delete` | 删除模板 |
|
||
| DELETE | `/api/v1/fileTemplate/batchDelete` | `sys:fileTemplate:batchDelete` | 批量删除 |
|
||
|
||
## 与 Excel 导入导出的配合
|
||
|
||
文件模板模块常与 Excel 导入导出功能配合使用:
|
||
|
||
```python
|
||
# 1. 获取导入模板下载地址
|
||
template = FileTemplateService.get_by_code("user_import_template")
|
||
download_url = template["filePath"]
|
||
|
||
# 2. 前端下载模板 → 填写数据 → 上传文件
|
||
|
||
# 3. 后端解析上传文件
|
||
abs_path = excel_utils.resolve_uploaded_excel()
|
||
rows, errors = excel_utils.parse_excel_rows(abs_path, USER_IMPORT_COLUMNS)
|
||
```
|
||
|
||
## 总结
|
||
|
||
文件模板模块用于管理系统中的各类模板文件。`before_add`/`before_update` 钩子自动将临时文件迁移到正式目录,`_detail_dict`/`_enrich_page_records` 钩子自动将文件路径转换为可访问 URL。`get_by_code` 方法支持按编码查询,便于程序化获取模板。
|