以下是针对你提供的模板代码编写的 **Markdown 格式技术文档**,涵盖所有五个核心模板(数据浏览器、获取数据、新增数据、更新数据、删除数据)以及关联操作模板。该文档适用于开发人员理解这些 Jinja2 模板的结构、变量用途和整体工作机制。 --- # 📄 数据管理模块模板技术文档 本技术文档描述了用于构建动态数据表格组件及后端数据处理逻辑的一系列 **Jinja2 模板**。这些模板共同实现了一个完整的数据浏览与增删改查(CRUD)系统,支持权限控制、字段加密、过滤条件、分页等功能。 --- ## 🔧 模板概览 | 模板名称 | 作用 | |--------|------| | `data_browser_tmpl` | 定义前端“数据浏览器”组件配置(JSON 结构) | | `get_data_tmpl` | 处理数据查询请求的 Python 脚本模板 | | `data_new_tmpl` | 新增记录的处理脚本 | | `data_update_tmpl` | 更新记录的处理脚本 | | `data_delete_tmpl` | 删除记录的处理脚本 | | `check_changed_tmpls` | 多对多关系中复选框变更时触发添加/删除中间表记录 | --- ## 1. `data_browser_tmpl` —— 前端数据表格组件定义 ### 功能说明 生成一个符合前端框架要求的 **Tabular(表格)组件 JSON 配置对象**,用于渲染可编辑的数据列表。 ### 输出示例(简化) ```json { "id": "user_tbl", "widgettype": "Tabular", "options": { "title": "用户列表", "description": "系统用户信息", "width": "100%", "height": "100%", "css": "card", "toolbar": { ... }, "editable": { ... }, "data_url": "/api/get_user.dspy", "data_method": "GET", "data_params": {}, "row_options": { "idField": "id", "fields": [ ... ] }, "page_rows": 160, "cache_limit": 5 }, "binds": { ... } } ``` ### 参数说明 | 变量名 | 类型 | 是否必需 | 描述 | |-------|------|----------|------| | `tblname` | string | ✅ | 表格唯一 ID 和命名基础(如 `user_tbl`) | | `title` | string | ❌ | 显示标题;若未提供则使用 `summary[0].title` | | `notitle` | boolean | ❌ | 若为真,则不显示标题 | | `description` | string | ❌ | 表格描述文本 | | `toolbar` | dict/list | ❌ | 工具栏按钮配置(JSON 序列化) | | `editor` | dict | ❌ | 编辑器配置(弹窗或内联编辑设置) | | `noedit` | boolean | ❌ | 若为真,则禁用编辑功能(无新增/删除/更新按钮) | | `new_data_url` | string | ❌ | 自定义新增接口 URL;否则自动生成 `/add_{name}.dspy` | | `delete_data_url` | string | ❌ | 自定义删除接口 URL;否则自动生成 | | `update_data_url` | string | ❌ | 自定义更新接口 URL;否则自动生成 | | `get_data_url` | string | ❌ | 获取数据接口 URL;否则自动生成 `/get_{name}.dspy` | | `data_method` | string | ❌ | 请求方法,默认 `"GET"` | | `params_kw` | dict | ✅ | 发送给后端的初始参数(JSON 序列化) | | `idField` | string | ❌ | 主键字段名,默认 `'id'` | | `checkField` | string | ❌ | 可勾选字段名(用于批量操作) | | `browserfields` | list | ❌ | 浏览模式下可见字段列表 | | `editexclouded` | list | ❌ | 编辑时隐藏的字段列表 | | `fieldliststr` | string | ✅ | 字段定义字符串(已格式化的 JSON 或表达式) | | `content_view` | dict | ❌ | 内容视图配置(如详情页嵌套) | | `subtables_condition` | string | ❌ | 条件判断表达式,决定是否渲染子表格区域 | | `bindsstr` | string | ❌ | 绑定事件或其他交互逻辑(JSON 字符串) | > ⚠️ 注意:`{%- raw -%}` 和 `{%- endraw %}` 是为了防止 Jinja2 解析内部模板语法而使用的保护标签。 --- ## 2. `get_data_tmpl` —— 数据查询处理脚本 ### 功能说明 根据传入参数执行 SQL 查询并返回分页结果。支持自动过滤、排序、用户身份绑定等。 ### 执行流程 1. 复制输入参数 `params_kw` 2. (可选)检查登录状态并注入 `userid` / `userorgid` 3. 设置默认分页和排序规则 4. 构造过滤条件(`data_filter` 支持 JSON 过滤器) 5. 替换 SQL 中的变量(如 `${userid}$`, `${filterstr}$`) 6. 执行分页查询并返回 `{total, rows}` ### 关键特性 - ✅ 支持复杂过滤条件(通过 `DBFilter` 类解析) - ✅ 支持动态变量替换(`${var}`) - ✅ 支持外键关联排序(`relation.outter_field_text`) - ✅ 支持模块级数据库隔离(`get_module_dbname()`) ### 使用变量 | 变量 | 描述 | |------|------| | `sql` | 原始 SQL 查询语句(含变量占位符) | | `modulename` | 所属模块名称,用于确定数据库 | | `sortby` | 默认排序字段(字符串或数组) | | `logined_userid` | 若设置,则必须登录才能访问,并将当前用户 ID 注入查询 | | `logined_userorgid` | 同上,组织 ID | | `relation` | 如果是关联子表,启用特殊排序逻辑 | | `fields` | 字段元信息列表,用于生成默认过滤器 | ### 返回格式 ```json { "total": 100, "rows": [ {"id": "1", "name": "Alice"}, ... ] } ``` --- ## 3. `data_new_tmpl` —— 新增数据处理脚本 ### 功能说明 接收客户端提交的数据,插入新记录到指定表中。 ### 关键行为 - 自动生成 UUID 作为主键(若未提供或长度非法) - 对敏感字段进行密码加密(`password_encode()`) - 注入当前用户/组织 ID(如果启用了权限绑定) - 调用 ORM 的 `C()` 方法创建记录 ### 使用变量 | 变量 | 描述 | |------|------| | `confidential_fields` | 需要加密存储的字段列表(如密码) | | `logined_userid` / `logined_userorgid` | 控制是否需要登录并注入上下文 | | `modulename` | 确定目标数据库 | | `summary[0].name` | 目标数据表名 | ### 成功响应 ```json { "widgettype": "Message", "options": { "title": "Add Success", "message": "ok", "timeout": 3 } } ``` ### 失败响应 ```json { "widgettype": "Error", "options": { "title": "Add Error", "message": "failed" } } ``` --- ## 4. `data_update_tmpl` —— 更新数据处理脚本 ### 功能说明 更新已有记录,支持字段加密和权限校验。 ### 特性 - 支持对 `confidential_fields` 加密后再保存 - 必须包含 `id` 字段用于定位记录 - 使用 ORM 的 `U()` 方法执行更新 ### 成功响应 ```json { "widgettype": "Message", "options": { "title": "Update Success", "message": "ok", "timeout": 3 } } ``` ### 失败响应 同新增失败格式。 --- ## 5. `data_delete_tmpl` —— 删除数据处理脚本 ### 功能说明 根据 `id` 删除一条记录,支持权限上下文注入。 ### 行为说明 - 接收 `params_kw.id` - 可选注入 `userid` / `userorgid` 到删除条件中 - 使用 ORM 的 `D()` 方法执行软/硬删除 ### 成功响应 ```json { "widgettype": "Message", "options": { "title": "Delete Success", "message": "ok", "timeout": 3 } } ``` --- ## 6. `check_changed_tmpls` —— 多对多关系复选处理 ### 场景 用于处理“角色分配”、“权限勾选”等场景中的中间表记录增删。 ### 实现机制 - 接收 `has_xxx` 参数表示是否选中 - 若为 `'true'` → 插入中间表记录 - 否则 → 删除对应中间表记录(通过组合键删除) ### 示例场景 用户 A 是否拥有角色 B: - 表:`user_role` - 字段:`user_id`, `role_id` - 当复选框变化时调用此脚本 ### SQL 示例 ```sql DELETE FROM user_role WHERE user_id='${user_id}$' AND role_id='${role_id}$' ``` ### 成功响应 统一返回消息提示(成功 + 自动关闭)。 --- ## 🧩 公共工具函数依赖 以下函数在模板运行环境中需可用: | 函数 | 说明 | |------|------| | `uuid()` | 生成 UUID 字符串 | | `get_user()` | 异步获取当前登录用户 ID | | `get_userorgid()` | 异步获取当前用户所属组织 ID | | `entire_url(path)` | 将相对路径转为完整 URL | | `password_encode(val)` | 对敏感值进行加密(如 bcrypt/scrypt) | | `default_filterjson(fields, ns)` | 根据字段生成默认搜索过滤器 | | `DBFilter(filterjson)` | 解析前端传来的过滤 JSON 并生成 SQL 条件 | | `ArgsConvert('[[]]', ']]')` | 处理 `[[var]]` 类型变量替换 | | `debug(msg)` | 输出调试日志 | | `DBPools()` | 获取数据库连接池实例 | | `get_module_dbname(modulename)` | 根据模块名获取对应数据库名 | --- ## 🛡️ 安全机制 | 机制 | 说明 | |------|------| | 登录校验 | 所有写操作均可配置强制登录验证 | | 敏感字段加密 | 支持自动加密指定字段(如密码) | | 参数绑定 | 所有变量均通过命名参数传递,避免 SQL 注入 | | 过滤器抽象 | 使用 `DBFilter` 类安全地构造 WHERE 子句 | | 变量沙箱 | 使用 `${}` 占位符 + 命名空间替换,防止直接拼接 | --- ## 📎 总结:典型使用流程 1. **前端渲染**:使用 `data_browser_tmpl` 渲染表格组件 2. **加载数据**:调用 `get_data_url`(由 `get_data_tmpl` 提供服务) 3. **编辑操作**: - 新增 → `new_data_url` → `data_new_tmpl` - 修改 → `update_data_url` → `data_update_tmpl` - 删除 → `delete_data_url` → `data_delete_tmpl` 4. **关联操作**:通过 `check_changed_tmpls` 处理多对多关系变更 --- ## 📚 附录:变量命名约定 | 前缀/后缀 | 含义 | |----------|------| | `_url` | 接口地址 | | `_tmpl` | Jinja2 模板字符串 | | `ns` | namespace,即参数命名空间 | | `params_kw` | 客户端传入的所有参数字典 | | `sor` | `sqlorContext` 实例,封装了 ORM 操作 | | `db` | 数据库连接池 | --- > 📝 文档版本:v1.0 > 💬 维护团队:Backend & Low-code Platform Team > 🕒 最后更新:2025年4月5日 --- ✅ *建议配合实际模板引擎调试工具(如预览渲染结果)以确保变量正确注入。*