# `xls2crud` 工具技术文档 > **用途**:将基于 JSON 描述的数据库模型和 CRUD 配置文件转换为前端 UI 代码(CRUD 或树形结构界面)。 --- ## 概述 本脚本是一个命令行工具,用于根据指定的模型目录和 JSON 配置文件生成前端 CRUD(增删改查)或树形结构(Tree)UI 所需的代码。它通过解析 Excel 衍生出的 JSON 结构,并结合环境变量与模板机制,动态生成对应模块的用户界面代码。 主要功能包括: - 解析命令行参数 - 加载并处理数据库模型定义 - 处理多个 JSON 格式的 CRUD 配置文件 - 支持环境变量注入(模板替换) - 分发至不同的 UI 构建器(CRUD / Tree) --- ## 依赖说明 ### 第三方/内部模块 | 模块 | 用途 | |------|------| | `os`, `sys` | 系统路径、环境变量、退出控制 | | `argparse` | 命令行参数解析 | | `json`, `codecs` | JSON 文件读取(支持 UTF-8 编码) | | `copy` | 对象拷贝 | | `appPublic.argsConvert.ArgsConvert` | 支持 `${}` 形式模板变量替换 | | `appPublic.dictObject.DictObject` | 将字典转为可点式访问的对象 | | `xls2crud.build_dbdesc`, `build_crud_ui` | 构建数据库描述及 CRUD 界面 | | `singletree.build_tree_ui` | 构建树形结构 UI | > ⚠️ 注意:`appPublic`、`xls2crud` 和 `singletree` 是项目内部模块,请确保已安装或在 Python 路径中可用。 --- ## 命令行使用方式 ```bash python xls2crud.py [-m models_dir] [-o output_dir] modulename [json_file ...] ``` ### 参数说明 | 参数 | 必需 | 说明 | |------|------|------| | `modulename` | ✅ | 指定生成代码所属的模块名称(通常用于命名空间或路由前缀) | | `json_file ...` | ✅(至少一个) | 一个或多个描述表单逻辑的 `.json` 配置文件路径 | | `-m`, `--models_dir` | ❌ | 数据库模型文件所在的目录列表(可多个),用于构建 `dbdesc` 对象 | | `-o`, `--output_dir` | ❌ | 输出代码的目标根目录,默认行为可能由配置决定 | > 如果未提供任何 JSON 文件,程序将打印用法提示并退出。 --- ## 输入文件格式:CRUD JSON 配置 每个 JSON 文件应遵循如下结构: ```json { "tblname": "user", "alias": "usr", // 可选,作为输出目录名 "uitype": "crud", // 或 "tree" "params": { "title": "用户管理", "fields": [...], "actions": [...] } } ``` ### 字段说明 | 字段 | 类型 | 是否必需 | 说明 | |------|------|----------|------| | `tblname` | string | ✅ | 关联的数据表名 | | `alias` | string | ❌ | 输出目录名称;若不存在则使用 `tblname` | | `uitype` | string | ❌ | UI 类型,可选 `"crud"`(默认)或 `"tree"` | | `params` | object | ✅ | 包含具体 UI 参数的对象,如标题、字段、操作等 | | `params.modulename` | string | ❌ | 自动生成,由命令行传入 | | `params.tblname` | string | ❌ | 自动生成,来自 `tblname` 字段 | > 💡 支持模板语法 `${VAR_NAME}`,会从环境变量中自动替换。 --- ## 环境变量支持(模板替换) 系统使用 `ArgsConvert('${', '}$')` 实现对配置中的 `${...}` 占位符进行替换。 例如: ```json { "params": { "api_base": "${API_HOST}/v1/data" } } ``` 若环境变量中有 `API_HOST=http://localhost:8000`,则最终值会被替换为: ```json "api_base": "http://localhost:8000/v1/data" ``` 所有当前进程的环境变量均会被加载进命名空间 `ns` 中供替换使用。 --- ## 核心流程说明 ### 1. 参数解析 使用 `argparse` 解析输入参数,获取: - 模型目录 (`models_dir`) - 输出目录 (`output_dir`) - 模块名 (`modulename`) - 一个或多个 JSON 配置文件路径 ### 2. 构建数据库描述对象 (`dbdesc`) 调用 `build_dbdesc(models_dir)` 从模型目录中提取数据库元信息(如表结构、字段类型等),结果封装为 `DictObject` 以便点式访问。 ```python dbdesc = DictObject(**dbdesc) ``` ### 3. 遍历处理每个 JSON 文件 对每一个 JSON 文件执行以下步骤: #### a. 读取并解析 JSON 使用 `codecs.open(..., 'utf-8')` 安全读取 UTF-8 编码内容,防止中文乱码。 #### b. 模板变量替换 利用 `ArgsConvert` 将 `${VAR}` 替换为环境变量实际值。 #### c. 转换为 `DictObject` 便于后续通过 `obj.field.subfield` 访问嵌套属性。 #### d. 设置输出目录 ```python crud_data.output_dir = os.path.join(args.output_dir, tblname) ``` 以表名或别名为子目录创建独立输出路径。 #### e. 注入模块名和表名到 params ```python crud_data.params.modulename = args.modulename crud_data.params.tblname = crud_data.tblname ``` #### f. 克隆数据库描述 避免污染原始 `dbdesc`,每次传递副本: ```python db = dbdesc.copy() ``` #### g. 分发 UI 构建任务 根据 `uitype` 决定调用哪个构建函数: | `uitype` | 函数调用 | |---------|--------| | `"tree"` | `build_tree_ui(crud_data, db)` | | 其他(默认) | `build_crud_ui(crud_data, db)` | --- ## 示例运行命令 ```bash python xls2crud.py \ -m ./models/user -m ./models/shared \ -o ./output \ admin \ ./crud_configs/user.json \ ./crud_configs/org.json ``` 输出结构示例: ``` ./output/ ├── user/ │ ├── form.js │ ├── list.vue │ └── api.js └── org/ ├── form.js ├── list.vue └── api.js ``` --- ## 错误处理 - 若未提供 JSON 文件,输出帮助信息并退出码为 `1` - 若文件无法打开或 JSON 格式错误,抛出异常(建议添加 try-except 包裹增强健壮性) --- ## 待改进点(建议) | 问题 | 建议 | |------|------| | 缺少异常捕获 | 添加 `try...except` 处理文件读取、JSON 解析错误 | | 日志输出简单 | 使用 `logging` 模块替代 `print()` | | 输出目录自动创建 | 添加 `os.makedirs(crud_data.output_dir, exist_ok=True)` | | 更详细的帮助信息 | 在 `ArgumentParser` 中补充描述 | --- ## 总结 该脚本是自动化生成前端管理界面的重要一环,适用于基于模型驱动开发的企业级后台系统。通过灵活的配置与模板机制,实现了高复用性和可维护性。 --- ## 附录:完整调用链示意图 ``` [CLI Input] ↓ argparse → args(models_dir, output_dir, modulename, files[]) ↓ build_dbdesc(models_dir) → dbdesc (DictObject) ↓ for each file in files: read JSON → a ac.convert(a, env) → 替换 ${} 变量 a → DictObject → crud_data crud_data.output_dir = output_dir/tblname crud_data.params.{modulename,tblname} = ... db = dbdesc.copy() if uitype == 'tree': build_tree_ui(crud_data, db) else: build_crud_ui(crud_data, db) ``` --- ✅ **版本**:1.0 📅 **最后更新**:2025-04-05