Crud核心配置

SmartCRUD 使用说明 #

基于 SmartChart 平台的低代码 CRUD 框架,通过可视化配置面板快速构建数据管理界面。


目录 #

  1. 快速开始
  2. 整体架构
  3. 数据集绑定(⚙️ 数据管理)
  4. 表格显示配置(📋 表格显示)
  5. 查询与过滤(🔍 筛选过滤)
  6. 新增与修改(✏️ 新增修改)
  7. 字段类型参考
  8. 模型管理(🔧 模型管理)
  9. 高级功能
  10. 常见问题

1. 快速开始 #

1.1 打开配置面板 #

页面右下角点击 「CRUD配置」 按钮,弹出底部配置抽屉,共有 5 个 Tab:

Tab 功能
📋 表格显示 表格外观、列设置、分页
🔍 筛选过滤 查询区、过滤条件、选项
✏️ 新增修改 表单字段、权限按钮
⚙️ 数据管理 绑定各功能的数据集 ID
🔧 模型管理 数据库表结构管理

1.2 基本配置流程 #

① ⚙️ 数据管理 → 填写 table_id(查询数据集)
② ⚙️ 数据管理 → 填写 add_id / update_id / delete_id
③ 📋 表格显示 → 设置 tableFields(表格显示字段)和 nameDict(字段中文名)
④ ✏️ 新增修改 → 设置 aform(新增字段)和 constFields(只读/主键字段)
⑤ 点击「预览」查看效果 → 确认后点击「发布」

1.3 三个操作按钮 #

每个 Tab 底部均有三个按钮:

按钮 行为
预览 将当前配置应用到页面(不保存)
保存 应用并写入服务器(开发环境)
发布 二次确认后覆盖线上配置

2. 配置值格式说明 #

在配置面板中填写配置时,支持以下输入格式:

格式类型 输入示例 实际含义
逗号分隔列表 code,name,status 字段列表
键值对字典 code:编码,name:名称 键值对
JSON字典 {"status":1} JSON 对象
数字 5 数据集 ID

3. 数据集绑定 #

⚙️ 数据管理 Tab

3.1 核心数据集 #

配置项 说明 必填
table_id 主表查询数据集,返回二维数组 ✅
add_id 新增数据集,接收表单参数,返回 {status:200, msg:'...'} ✅
update_id 修改数据集,同上 ✅
delete_id 删除数据集,接收主键值;为空则不显示删除按钮 —

3.2 扩展数据集 #

配置项 说明
ztable_id 子表(明细)查询数据集,传参 fid=主表主键值
statistic_id 顶部统计数据集,返回的键值对显示为统计卡片
detail_id 点击「查看」时调用的数据集,返回的数据在弹窗展示
option_id 下拉选项数据集(支持多个字段的选项)
addb_id 提交前校验数据集
adda_id 提交成功后触发的数据集
uploadds 导入 Excel/CSV 的数据集(设置后显示上传按钮)
daochu_id 自定义导出数据集(不设则导出当前表格数据)
daochut_id 导入模板下载数据集
tree_ds 左侧树形菜单数据集
tree_id 树形表格懒加载子级数据集
audit_id 审批/变更申请提交数据集(默认为 1)
action_id 批量动作专用数据集(不设则用 add_id)

3.3 联动数据集 #

配置项 格式 说明
selectDsDict 字段名:数据集ID 选择框变化时带出其他字段值(支持字典返回同时带出子表)
remoteDsDict 字段名:数据集ID 字段支持远程搜索(模糊输入)
selectParamDict JSON 联动/远程搜索时额外传参的字段,如 {"供应商":["物料","地区"]}
optionParam field1,field2 表单中这些字段值变更时,自动刷新固定选项(option_id)并传参
funDsDict 图标:数据集ID 工具栏功能按钮,末尾加 ! 弹出窗口
viewDsDict 图标:数据集ID 操作列自定义按钮,末尾加 ! 弹窗,!! 静默刷新
iframeFormDict JSON 操作列按钮弹出 iframe 表单页(见 9.4)
editDict JSON 多编辑按钮:每个按钮可指定独立数据集和字段(见 9.5)
chartids 3,4,5 点击「查询」时联动刷新的图形 ID
chartids_t 3,4 点击表格行时联动刷新的图形 ID

3.4 后端分页 #

开启 isBackPage = true 后,每次翻页都请求后端。数据集需返回两个数据帧:

df0: [['total'], [总条数]]              // 表头行 + 总条数行
df1: [[字段名列表], [数据行1], [数据行2], ...]

框架自动传递参数:limit(每页条数)和 offset(偏移量 = 每页条数 ×(当前页-1))。


4. 表格显示配置 #

📋 表格显示 Tab

4.1 字段显示 #

配置项 格式 说明
nameDict code:编码,name:名称 字段英文名 → 中文名映射,作为列标题
tableFields code,name,status 表格显示的字段(为空则显示全部)
shortTableFields code,name 设置后启用折叠展开行,短列用于主表格,tableFields 用于展开内容
fixedFields code,name 固定在左侧不随滚动消失的字段
widthDict code:100px,name:200px 各字段列宽
alignDict amount:right 各字段对齐方式(left/center/right)
columnAlign center 全局默认对齐方式
sortableFields code,amount 允许排序的字段(为空则全部允许排序;mergeFields 启用时排序禁用)
exSumFields id,phone 不参与底部合计的字段

4.2 外观配置 #

配置项 默认值 说明
title 数据清单 表格标题(也用作导出文件名)
tableHeaderColor #475254 表头背景色
hColor #fff 表头字体颜色
hBorder false 显示表头边框
stripe false 斑马纹
showIndex false 序号列
showSummary false 底部合计行
maxheight 600 表格最大高度(px)
minheight — 表格最小高度,如 300px
tableAutoHeight true 表格高度自动适应可视区域(开启时忽略 maxheight)
actionFixed true 操作列固定在右侧
toolbar true 显示右侧工具栏(刷新、导出、列配置等)
print false 显示打印按钮(打印样式与内容可通过 printConfig 自定义)
showTable true 是否显示表格(关闭后可只显示统计卡片/图形)
isChart false 加载图形区域(配合看板图形联动)
smtdrag false 开启拖拽
isMobileCard false 移动端切换为卡片列表模式
shortCol 2 展开详情卡片/移动卡片的列数
shortBord false 详情卡片显示边框
shortDire false 详情卡片竖向排列

4.3 特殊列展示 #

Tag 标签:

tagFields = status,category
statusColor = 启用:green,禁用:red,待审:#ff9900
tagColorMode = bg

字段值会渲染为彩色 Tag,多个值(逗号分隔)会展示多个 Tag。

tagColorMode 默认值 说明
bg ✅ 彩色作为背景色(默认)
text — 彩色作为文字色(背景透明)

表头高亮(spotFields):

spotFields = status:red,amount:green

表头说明(tooltipDict):

tooltipDict = code:这是物料的唯一编码,amount:金额单位为元

配置后对应列表头旁出现 ℹ️ 图标,鼠标悬停显示说明文字。

双击列触发数据集(cellDblDsDict):

cellDblDsDict = 产品编码:5,订单号:6!,状态:7!!

双击指定列的单元格时触发对应数据集,格式与 viewDsDict 一致:

后缀 行为
无 调用数据集,打开查看弹窗
! 调用数据集,弹出图形窗口
!! 调用数据集,静默刷新(无弹窗)

该配置优先于单元格编辑(cellEditable),即某列同时配置了双击触发时,双击将触发数据集而非进入编辑。

行合并(mergeFields):

mergeFields = department,category

相邻行中该字段值相同时自动合并单元格。启用后该字段排序禁用。列表页打印时同样做行合并,与页面显示一致。

4.4 分页配置 #

配置项 默认值 说明
pageSize 30 每页条数
pageSizes 30,50,100,500,1000 可选分页条数
isBackPage false 是否启用后端分页

提示: 设置 pageSize=9999 可隐藏分页控件(适合数据量少的场景)。

4.5 列配置(隐藏列) #

工具栏(toolbar = true)中的「列配置」按钮可弹窗勾选各列的显示/隐藏(对应 hiddenColumns),用户可按需临时隐藏不关心的列,切换 Tab 或刷新页面后恢复。


5. 查询与过滤 #

🔍 筛选过滤 Tab

5.1 后端查询(searchDict) #

点击「查询」按钮后,将字段值提交给后端数据集作为查询参数。

searchDict = status,department,order_date
typeDict = order_date:date,status:select

特殊处理:

  • date/month 类型 → 区间选择,自动拆分为 字段名_s(开始)和 字段名_e(结束)
  • date1/month1 类型 → 单个日期/月份,直接以字段名传参(不拆分)
  • 多选(selects)→ 自动转为 'val1','val2' 的 SQL IN 格式
  • 设置 defaultDict = {"status":1} 可配置查询初始默认值
  • 日期/月份控件内置快捷选项(今天、昨天、本周、本月、近7/30/90天;月份:本月、近3/6月、今年)

5.2 前端实时过滤(filterDict) #

在已加载的数据中实时过滤,不请求后端,适合快速筛选。

filterDict = status,amount,name

支持运算符:

输入 含义
abc 正则模糊匹配(含 abc)
=100 精确等于 100
>100 大于 100
<100 小于 100
>=100 大于等于 100
<=100 小于等于 100

过滤模式(filterMode): 多个过滤条件默认为 AND(同时满足),开启 filterMode = true 切换为 OR(任一满足),工具栏中也可点击切换。

5.3 全局关键词搜索(isfilter) #

开启 isfilter = true 后显示全局搜索框,对所有字段进行模糊匹配:

  • 空格分隔多个关键词(AND 逻辑)
  • 匹配内容黄色高亮显示
  • 200ms 防抖优化
  • searchHint 可设置搜索框的提示文字

5.4 表头筛选(headerFilter) #

headerFilter = status,type

配置后对应列的表头出现筛选图标,选项自动从全量数据去重生成,支持多选,属于前端过滤(不请求后端)。

5.5 查询区其他配置 #

配置项 默认值 说明
searchHead true 显示查询区
btnSearch true 显示查询按钮(关闭后输入即实时查询)
showLabel false 查询框显示字段中文标签
inputWidth 100px 查询输入框宽度
swidthDict — 逐字段查询框宽度,如 name:200px
placeholderDict — 字段占位提示,如 code:请输入编码(查询区与表单通用)
line_input false 查询输入框使用线性(下划线)风格
dmFields — 维度切换字段(显示为 CheckboxButton)
treeWidth 150px 左侧树区域宽度

6. 新增与修改 #

✏️ 新增修改 Tab

6.1 表单字段配置 #

配置项 说明
aform 新增表单字段列表,如 code,name,status
mform 修改表单字段列表(不设则复用 aform)
constFields 只读字段列表,第一位必须是主键字段名,默认 id。编辑弹窗打印时只读字段正常显示(仅排除第一位主键,见 9.19)
requiredFields 必填字段,会自动生成校验规则
cform 折叠到「其它」分组的字段

⚠️ 重要: constFields 的第一位必须是主键字段名,框架依赖它来区分新增和修改。

6.2 按钮权限控制 #

配置项 默认值 说明
btnAdd true 新增按钮
btnEdit false 编辑按钮(操作列)
btnView false 查看按钮(操作列)
btnDownload true 导出按钮
delete_id — 不为空则显示删除按钮

行级权限(数据驱动): 数据集返回的数据中若包含 操作 字段,可控制单行按钮显示:

  • 包含 E → 显示编辑按钮
  • 包含 D → 显示删除按钮
  • 包含自定义图标名 → 显示对应的 viewDsDict 按钮

6.3 表单外观配置 #

配置项 说明
dialogWidth 弹窗宽度,如 60%、800px
dialogFull true 则全屏弹窗
formLabelWidth 表单标签宽度,如 80px、auto
labelPosition 标签位置:top/left/right
formSize 表单字段尺寸:medium/small/mini(非空时切换为 inline 模式)
ainfo 新增弹窗顶部提示文字
minfo 修改弹窗顶部提示文字
formRows 表单行布局(见 6.5)

6.4 高级表单行为 #

配置项 说明
adefaultDict 新增时字段默认值,如 {"status":1}
remainFields 新增提交后不清空的字段(适合连续录入)
submitFields 新增修改时不提交的字段,逗号分隔
submitFields1 子表不提交的字段,逗号分隔
iseditadd 编辑即新增:点编辑按钮时以新增模式打开
isEditRequest 编辑走审批流,需填写变更原因
addHead 新增表单显示在页面顶部而非弹窗
cellEditable 允许双击单元格直接编辑(字段需在 mform 中且非只读),保存时调用 update_id 提交 {主键, 字段}
scanSubmit 扫码后自动提交表单
ossUpload 文件/图片直传云存储(OSS/COS),填写 apiconfig 中 smtoss 的配置名,如 ali1

6.5 表单行布局(formRows) #

默认表单字段逐个排列,通过 formRows 可自定义分组标题与多列布局:

[{"label":"基本信息"}, "name,code:16,8", "remark"]
元素 含义
{"label":"基本信息"} 渲染一个分组分隔标题
"name,code:16,8" name 与 code 同一行,冒号后为各字段栅格宽度(总计 24)
"remark" 单独占一行(不写宽度时按字段数均分 24 栅格)

6.6 子表(明细录入) #

在新增/修改弹窗中内嵌明细数据录入,适用于主从表场景:

ztable_id = 8      // 查询子表数据,传参 fid=主键值
aform1 = product_code,qty,unit_price   // 子表新增字段
mform1 = product_code,qty,unit_price   // 子表修改字段
detailSummary = true   // 子表底部显示合计行
submitFields1 = temp_field  // 子表不提交的字段

开启 detailSummary 后,子表底部自动出现合计行,首列显示「合计」文字,其余数值列自动求和(保留两位小数)。非数值列留空。

该功能使用 getDetailSummaries 方法实现,如需自定义合计逻辑可重写该方法(参数为 {columns, data},返回与列数等长的数组)。

提交数据格式:

{
  "main_field": "xxx",
  "_child": {
    "fid": "主键值",
    "add": [{"product_code":"A001","qty":10}],
    "mod": [{"id":5,"qty":20}],
    "del": [3, 7]
  }
}

7. 字段类型参考 #

通过 typeDict 配置字段类型,格式:字段名:类型。

typeDict = status:select,birthday:date,amount:number,remark:text
类型值 查询区控件 表单控件 表格展示
text 普通输入框 多行文本域 普通文本
date 日期范围选择器 日期选择器 普通文本
date1 日期单选(单值传参) 日期选择器 普通文本
month 月份范围选择器 月份选择器 普通文本
month1 月份单选(单值传参) 月份选择器 普通文本
datetime 日期范围选择器 日期时间选择器 普通文本
select 下拉单选 下拉单选 普通文本
selects 下拉多选 下拉多选 普通文本
popselect — 弹窗单选 普通文本
popselects — 弹窗多选 普通文本
radio 下拉单选 单选按钮组 普通文本
selec 级联选择器 级联选择器 普通文本
number 普通输入框 数字输入框 普通文本
switch 开关 开关 只读开关
progress 普通输入框 数字输入框 进度条
rate — 星级评分 只读评分
color — 颜色选择器 颜色图标
file 普通输入框 文件上传 下载链接
img 普通输入框 图片上传 图片预览
qr 输入+扫码按钮 输入+扫码按钮 普通文本
qrcode 普通输入框 输入+二维码预览 普通文本
remark — 只读文本 普通文本
action — 魔法棒按钮 —

💡 qr 配合 remoteDsDict: 当字段类型为 qr 且同时在 remoteDsDict 中配置了数据集时,输入框会升级为联想输入框(el-autocomplete),支持输入时实时搜索,同时保留扫码按钮。适用于既需要扫码又需要手动搜索的场景。

💡 popselect / popselects 弹窗选择: 需配合 remoteDsDict 指定弹窗数据集。点击字段右侧按钮弹出表格选择对话框,popselect 为单选(选中一行确认带出),popselects 为多选(选中多行批量添加子表行)。通过 popSearchConfig 可配置弹窗搜索区字段(逗号分隔,如 status,name)。详见 9.15。

选项数据配置(optionDict):

{
  "status": [[1, "启用"], [0, "禁用"]],
  "category": [["A", "类别A"], ["B", "类别B"]]
}

格式:二维数组,每项 [值, 显示文本]。也可通过 option_id 从数据集动态加载。

💡 选项数据带出: 当选项数据集返回多列时(如 产品编码,产品名称,规格,单位),选择选项后框架自动将同名字段的值填充到表单,无需额外配置 selectDsDict 做远程查询。适用于 select、remoteDsDict、popselect 等类型(selects 多选除外)。详见 9.16。

弹窗搜索字段(popSearchConfig):

popSearchConfig = status,name,date

配置弹窗选择对话框中搜索区的字段列表,逗号分隔。日期类型字段自动使用日期范围选择器(拆分为 _s/_e 传参)。


8. 模型管理 #

🔧 模型管理 Tab(仅 Dev 模式可见)

提供可视化的数据库表结构管理,支持建表和字段变更(兼容 MySQL / PostgreSQL / SQLite,连接类型为 gp/gppool/vectorPostgres 时按 PostgreSQL 处理,字段类型下拉会按数据库类型自动切换候选)。

8.1 操作流程 #

① 输入表名(可选)→ 点「查询」
   ├─ 有表名:从数据库读取真实表结构
   └─ 无表名:从当前 CRUD 配置中收集字段
   (也可点「Excel导入」从 Excel 文件生成字段清单,见 8.5)
② 在列表中修改字段属性
③ 点「预览」→ 将字段配置应用到 CRUD 设置面板
④ 点「保存」→ 保存 CRUD 配置
⑤ 点「执行」→ 生成并执行 SQL(⚠️ 不可恢复)

8.2 字段属性说明 #

列名 说明
字段名 数据库列名
备注 字段中文说明(对应 nameDict)
实际类型 数据库类型,如 varchar(50)、int、decimal(10,2)
默认 字段默认值
空 是否允许 NULL
类型 前端表单类型(见第 7 节)
对齐 列对齐方式
宽度 列宽度
只读 加入 constFields
新增 加入 aform
修改 加入 mform
必填 加入 requiredFields
查询 加入 searchDict
过滤 加入 filterDict
长显 加入 tableFields
短显 加入 shortTableFields
子增 加入 aform1
子修 加入 mform1
其它 加入 cform
▲▼ 调整字段顺序
🗑 标记删除(执行后从数据库删除列)

8.3 特殊字段自动处理 #

字段名 自动处理
id 自动设置为自增主键(MySQL: PRIMARY KEY AUTO_INCREMENT;PostgreSQL: serial;SQLite: PRIMARY KEY AUTOINCREMENT)
create_time 自动设置为 DEFAULT CURRENT_TIMESTAMP
update_time 自动设置为 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

字段重命名: 在字段列表中修改已有字段的名称,执行时会生成 RENAME COLUMN 语句(SQLite 不支持)。

8.4 数据库兼容说明 #

操作 MySQL PostgreSQL SQLite
建表 ✅ 支持 COMMENT ✅ COMMENT ON 语句 ✅(无 COMMENT)
新增字段 ✅ ✅ ✅
修改字段 ✅ CHANGE COLUMN ✅ ALTER COLUMN(类型/空值/默认值/备注分条语句) ❌ 不支持
重命名字段 ✅ RENAME COLUMN ✅ RENAME COLUMN ❌ 不支持
删除字段 ✅ ✅ ❌ 不支持
自增主键 AUTO_INCREMENT serial / bigserial AUTOINCREMENT

8.5 Excel 导入建表 #

点「Excel导入」上传 .xlsx 文件,可自动生成字段清单:

  • 第一行 = 字段名(自动转小写、空格转下划线)
  • 第二行 = 字段备注(可选,为空时用字段名)
  • 后续行 = 数据样本,用于自动推断字段类型(整数/数值/日期/文本,按数据库类型映射)
  • 文件名(去扩展名)自动作为表备注

预览确认后字段填入列表并切换到「新建表」模式,输入表名后点「执行」建表。


9. 高级功能 #

9.1 选择联动(selectDsDict) #

当某字段值变化时,调用数据集自动带出其他字段:

selectDsDict = supplier_code:5

字段 supplier_code 变化时,调用数据集 5(传参 {supplier_code: 值}),返回数据自动填充到表单同名字段。

如需额外传参:

selectParamDict = {"supplier_code": ["warehouse", "category"]}

9.2 远程搜索(remoteDsDict) #

让下拉框支持输入搜索:

remoteDsDict = product_code:8
typeDict = product_code:select

输入时实时调用数据集 8(传参 {product_code: 输入值}),返回结果作为选项列表。

9.3 自定义操作按钮(viewDsDict) #

在操作列添加自定义按钮:

viewDsDict = el-icon-printer:9,详情:10!,el-icon-goods:11!!
后缀 行为
无 调用数据集,打开查看弹窗
! 调用数据集,弹出图形窗口
!! 调用数据集,静默刷新(无弹窗)

按钮名用 Element Icon 类名(如 el-icon-printer)显示为图标,中文则显示为文字按钮。

9.4 弹窗表单(iframeFormDict) #

在操作列添加按钮,点击后以 iframe 弹窗打开另一个页面(如独立的 Form 表单页):

iframeFormDict = {"审批":{"url":"/echart/?type=form","params":["order_id"],"width":"80%","height":"80vh"}}
属性 说明
url 弹窗页面地址;若只填类型名(不含 /),自动拼为 /echart/?type=xx
params 从当前行取值传递的字段列表,统一以 param={"xx":"xx"} 形式拼到 URL
width / height 弹窗尺寸,默认 80% / 80vh

弹窗关闭后自动刷新表格。按钮名同样支持行级权限(操作 字段包含按钮名才显示)。

9.5 多编辑按钮(editDict) #

在操作列配置多个编辑按钮,每个按钮可指定独立的数据集和字段子集:

editDict = {"编辑库存":{"ds":5,"fields":"qty,warehouse","icon":"el-icon-s-goods"}}
属性 说明
ds 提交时调用的数据集 ID(代替 update_id)
fields 弹窗表单中显示的字段(代替 mform)
icon 按钮图标
add true 则以新增模式提交(如「复制新增」场景),如 {"复制新增":{"ds":5,"fields":"name,qty","add":true}}

9.6 工具栏功能按钮(funDsDict) #

在工具栏添加批量操作按钮:

funDsDict = el-icon-check:12!,批量审批:13

传参:action(按钮 key)、updatelist(选中行主键列表,逗号分隔)。

9.7 批量动作(actionDict) #

开启多选后,针对选中行执行批量状态变更(需要表中有 status 字段),key 为要变更的状态值:

actionDict = {"已审批": ["批量审批", "green"], "已驳回": ["批量驳回", "red"]}

显示为按钮,点击后带二次确认,执行时传参 action(状态值)和 updatelist(选中行主键列表)。默认调用 add_id,可通过 action_id 指定专用数据集。

9.8 左侧树形菜单(tree_ds) #

tree_ds = 15       // 树形菜单数据集 ID
treeWidth = 180px  // 树宽度

数据集返回树形结构数据,点击叶子节点自动向后端传 _label 参数并刷新表格。

9.9 提交前后处理(addb_id / adda_id) #

提交前校验(addb_id): 在数据提交到数据库前进行校验。校验通过返回 status:200,校验不通过返回 status:400 并给出提示信息 msg。可用于检查数据完整性、重复性等。若返回中带 data,将替换实际提交的参数(可在校验时补充/加工字段)。

提交后触发(adda_id): 数据提交成功后自动执行的操作,可用于发送通知、触发工作流、更新关联数据等。

9.10 扫码输入 #

typeDict = barcode:qr
qrFormats = code_128,qr_code   // 支持的码格式(空则全支持)
qrCheckStr = SC                // 扫码内容必须以 SC 开头
scanSubmit = true              // 扫码后自动提交表单

9.11 文件/图片上传 #

typeDict = avatar:img,attachment:file
uploadpath = my_files   // 文件存储路径

上传地址:/echart/upload_file/,存储路径:/static/custom/{uploadpath}/{filename}。表格中展示时,若字段值以 http 开头则直接使用原地址。

设置 ossUpload = 配置名(apiconfig 中 smtoss 的配置名,如 ali1)可将文件直传阿里云 OSS / 腾讯云 COS 等云存储。

9.12 多表 Tab(tabs) #

一个 CRUD 页面可配置多个 Tab,每个 Tab 拥有独立的数据集和显示配置(类似多张表切换):

配置项 说明
tabs Tab 列表(在配置面板中新增/删除 Tab 时自动维护)
tabLabel 当前 Tab 的显示名称
tabIcon 当前 Tab 的图标,如 el-icon-goods
tabColor 当前 Tab 的颜色
tabRefreshMode 切换 Tab 时的刷新策略:always 始终刷新(默认)/ ifempty 有数据不刷新 / never 不刷新

工作机制:

  • 第一个 Tab 保存页面完整配置,其余 Tab 仅保存与默认配置的差异项,切换时自动应用
  • 切换 Tab 时数据自动缓存(ifempty/never 模式下回切不重新请求)
  • 配置方法:在配置面板切换到目标 Tab 后修改配置并保存,各 Tab 配置互不影响

9.13 钩子函数总览 #

钩子函数是框架预留的空方法,在看板 JS 中通过 vapp.方法名 = function(参数) {...} 重写后,会在对应操作发生时自动调用。所有钩子默认为空方法,不重写不影响任何功能。

钩子 参数 触发时机 适用模块
calcChange(k, row) k:字段名,row:行数据(子表传入,主表为 null) 表单中任意字段值变化时(主表传 k,子表传 k + row) CRUD / 表单
onAdd() 无 打开新增表单后、连续录入重置后 CRUD / 表单
onSave(param) param:提交内容 提交成功后(普通新增/修改、多编辑、审批模式) CRUD / 表单
beforeDelete(row) row:待删除行数据 删除执行前(返回 false 阻止删除) CRUD
onDelete(row) row:被删除行数据 删除成功后 CRUD
onEdit(row) row:当前编辑行数据 打开编辑表单后(单编辑、多编辑、表单模式加载) CRUD / 表单
onRefreshTable() 无 表格数据刷新完成后 CRUD
onTabSwitch(idx) idx:目标 Tab 索引 多表 Tab 切换完成后 CRUD
onTableRowClick(row) row:被点击行数据 表格行点击后(补充 chartids_t 联动) CRUD
actionClick(k) k:按钮标识 表单中 action 类型按钮点击时 CRUD / 表单
tableRowClassName({row, rowIndex}) 返回 CSS 类名 表格行渲染时 CRUD

9.13.1 calcChange — 字段值变化计算 #

函数签名:calcChange(k, row=null),其中 k 为字段名,row 为行数据(子表传入,主表为 null)。

主表字段联动:

主表表单中任意字段值变化时触发,row 为 null,通过 vapp.form 读写表单数据:

vapp.calcChange = function(k, row) {
    if (k === 'qty') {
        vapp.form.amount = vapp.form.qty * vapp.form.price;
    }
}

子表字段联动:

子表中任意字段值变化时同样触发 calcChange,此时 row 为当前行数据对象。适合做整列汇总或行间计算:

vapp.calcChange = function(k, row) {
    // 子表字段变化时,汇总到主表
    if (k === '小计') {
        let total = 0;
        for (let r of vapp.detailData) {
            total += Number(r.小计) || 0;
        }
        vapp.form.合计金额 = total;
    }
    // 也可以针对当前行做计算
    if (row && k === 'qty') {
        row.小计 = row.qty * row.price;
    }
}

选择联动触发:

当字段配置了 selectDsDict(选择联动)时,选择变化也会触发 calcChange,此时 row 同样会被传入(子表场景):

vapp.calcChange = function(k, row) {
    // selectDsDict 联动后也可在此追加处理
    if (k === 'supplier_code') {
        console.log('供应商变更', row ? row[k] : vapp.form[k]);
    }
}
  • 所有字段类型均会触发(包括 text、date、number、switch、qr、select 等)
  • 主表触发时 row 为 null,通过 vapp.form 访问表单数据
  • 子表触发时 row 为当前行数据对象,可直接读写行内字段
  • 选择联动(selectChange)内部也会调用 calcChange

9.13.2 onAdd — 新增初始化 #

vapp.onAdd = function() {
    // 前端生成单据号(日期+随机数)
    let d = new Date();
    let no = d.getFullYear() +
        String(d.getMonth()+1).padStart(2,'0') +
        String(d.getDate()).padStart(2,'0') +
        String(d.getHours()).padStart(2,'0') +
        String(d.getMinutes()).padStart(2,'0') +
        String(d.getSeconds()).padStart(2,'0') +
        String(Math.floor(Math.random()*1000)).padStart(3,'0');
    vapp.form.单据号 = no;

    // 或通过数据集服务端生成:
    // let r = ds_refresh(数据集ID, null, 'list');
    // vapp.form.单据号 = r[0][0];
};

触发时机:点击「新增」按钮打开表单后、以及连续录入(remainFields)提交后重新初始化时。

9.13.3 onSave — 提交成功 #

vapp.onSave = function(param) {
    // param 包含本次提交的所有字段
    // 新增时: {字段1:值, 字段2:值, _child: [...]}
    // 修改时: {id:主键, 修改字段:值, _child: {fid, mod, add, del}}

    console.log('提交内容', param);

    // 示例: 提交后调用其他数据集做后续处理
    // ds_refresh(数据集ID, param);
};

在所有提交成功路径都会触发:普通新增/修改、多编辑提交、审批模式提交。

9.13.4 beforeDelete — 删除前校验 #

vapp.beforeDelete = function(row) {
    // row 为待删除行的完整数据
    // 返回 false 阻止删除,不返回或返回其他值则继续执行删除
    if (row.status === '已审批') {
        vapp.$message.error('已审批的记录不允许删除');
        return false;
    }
};

在 handleDeleteClick 中、实际删除请求发出前触发。返回 false 阻止删除,不返回或返回其他值则继续执行。

9.13.5 onDelete — 删除成功 #

vapp.onDelete = function(row) {
    // row 为被删除的完整行数据
    console.log('删除了', row);

    // 示例: 删除后触发级联清理
    // ds_refresh(数据集ID, row);
};

在 handleDeleteClick 中删除成功后触发,早于 refreshTable()。

9.13.6 onEdit — 编辑打开 #

vapp.onEdit = function(row) {
    // row 为当前编辑行的完整数据
    // 此时表单已填充完毕,可在此追加自定义处理

    // 示例: 根据行数据加载额外信息
    // let extra = ds_refresh(数据集ID, row, 'list');
    // vapp.form.附加字段 = extra[1][0];
};

在 handleEditClick / loadEditData 中表单数据填充完毕后触发,包括单编辑、多编辑、表单模式加载。

9.13.7 onRefreshTable — 表格刷新后 #

vapp.onRefreshTable = function() {
    // 表格数据已刷新完毕,fullData/tableData 已更新

    // 示例: 根据数据条件高亮某些行
    // let rows = vapp.fullData;
    // ...
};

在 refreshTable() 方法末尾触发。所有导致刷新的操作(查询、翻页、提交后刷新等)都会调用。

9.13.8 onTabSwitch — Tab 切换 #

vapp.onTabSwitch = function(idx) {
    // idx 为切换后的目标 Tab 索引(从 0 开始)
    console.log('切换到 Tab', idx);
};

在 switchTab() 方法末尾触发,此时配置已恢复、数据已刷新。

9.13.9 onTableRowClick — 行点击 #

vapp.onTableRowClick = function(row) {
    // row 为被点击的行数据
    console.log('点击了行', row);
};

在 handleRowClickChange 中触发,补充 chartids_t 的图形联动。如果仅需刷新关联图表,配置 chartids_t 即可;需自定义逻辑时重写此钩子。

9.13.10 actionClick — 自定义按钮 #

在 typeDict 中将字段类型设为 action,该字段会渲染为按钮,点击时触发:

vapp.actionClick = function(k) {
    // k 为字段名(即按钮标识)
    if (k === 'btn1') {
        // 自定义逻辑
    }
};

9.13.11 tableRowClassName — 行样式 #

vapp.tableRowClassName = function({row, rowIndex}) {
    if (row.amount > 1000) {
        return 'warning-row';
    }
    return '';
};

返回 CSS 类名,需在页面样式中定义对应类(如 .warning-row { background: #fdf6ec; })。

9.14 双击列触发数据集(cellDblDsDict) #

配置指定列的单元格双击事件,触发对应数据集,实现行级数据交互:

cellDblDsDict = 产品编码:5,订单号:6!,状态:7!!
后缀 行为
无 调用 ds_refresh(数据集ID, {当前行数据}),弹出查看弹窗
! 调用数据集,弹出图形窗口
!! 调用数据集,静默刷新(无弹窗)
  • 配置位于「表格显示」→「列特性」分组
  • 优先级高于单元格编辑(cellEditable),未配置的列不受影响
  • 也可在 JS 中动态设置(需在 rend() 执行前):vapp.cellDblDsDict = '产品编码:5,订单号:6!'

9.15 弹窗选择(popselect / popselects) #

通过 typeDict 将字段设为 popselect(单选)或 popselects(多选),配合 remoteDsDict 指定数据集,点击按钮弹出表格选择对话框:

typeDict = product_code:popselect remoteDsDict = product_code:8 popSearchConfig = product_name,category

单选模式(popselect):

  • 弹窗表格支持模糊搜索、前端分页、后端分页
  • 选中一行后点确认,字段值和同名列值自动带出到表单
  • 可配合 selectDsDict 实现远程联动带出
  • 支持主表字段和子表字段

多选模式(popselects):

  • 弹窗表格显示复选框,可选中多行
  • 主表:选中行的 key 字段逗号拼接,其余列取首行值
  • 子表:选中多行时批量新增子表行,每行调用 selectChange 联动
  • 单选一行时等同于单选模式行为

弹窗功能:

  • 模糊搜索:输入关键词实时过滤(支持所有列)
  • 弹窗搜索区:通过 popSearchConfig 配置搜索字段(日期类型自动区间选择)
  • 后端分页:数据集返回 {df0: 总条数, df1: 分页数据} 时自动启用
  • 数据缓存:首次加载后缓存,重复打开不重新请求(带搜索条件时不缓存)

9.16 选项数据带出 #

选择下拉/弹窗选项后,自动从选项数据中提取同名字段填充到表单,无需额外配置 selectDsDict 做远程查询:

适用类型:

类型 数据来源 触发带出
select(固定选项) option_id / optionDict ✅
select + remoteDsDict remoteMethod 远程搜索 ✅
remoteDsDict(autocomplete) querySearch 远程搜索 ✅
popselect / popselects 弹窗表格 ✅
selects(多选) — ❌ 不触发

工作原理:

  • 选项数据集返回多列时(如 产品编码,产品名称,规格,单位),框架自动缓存表头
  • 选择某选项后,从选项数据中查找匹配行,将同名列的值填充到表单
  • 值为空时自动清空对应字段

优先级:

  1. 选项数据带出(立即执行,无网络请求)
  2. selectDsDict 远程联动(200ms 延迟,覆盖选项数据带出的值)

如果选项数据集只返回两列(值和显示文本),则不会触发带出(表头长度 ≤ 1)。

9.17 自定义校验规则(exrules) #

通过 JS 代码设置 exrules,可在标准必填校验之外添加自定义校验逻辑。exrules 合并到 Element UI 的 rules 中,主表和子表均支持。

validator 函数签名: (rule, value, callback)

参数 说明
rule.field 当前字段名
rule.row 当前行数据(子表场景可访问同行其他字段,主表为 undefined)
value 当前字段值
callback 校验通过调 callback(),失败调 callback(new Error('错误信息'))

主表场景可通过闭包访问 vapp.form.xxx 对比其他表单字段。

子表行内字段对比:

vapp.exrules = {
    end_qty: [{
        validator: function(rule, value, callback) {
            // rule.row 访问同行数据
            if (value && rule.row.start_qty && Number(value) <= Number(rule.row.start_qty)) {
                callback(new Error('结束数量必须大于开始数量'));
            } else {
                callback();
            }
        }, trigger: 'blur'
    }]
};

子表字段与主表对比:

vapp.exrules = {
    sub_date: [{
        validator: function(rule, value, callback) {
            // vapp.form 访问主表数据
            if (value && vapp.form.main_date && value < vapp.form.main_date) {
                callback(new Error('子表日期不能早于主表日期'));
            } else {
                callback();
            }
        }, trigger: 'blur'
    }]
};

多规则组合:

vapp.exrules = {
    amount: [
        { required: true, message: '金额不能为空', trigger: 'blur' },
        {
            validator: function(rule, value, callback) {
                if (value !== null && value !== '' && Number(value) <= 0) {
                    callback(new Error('金额必须大于 0'));
                } else {
                    callback();
                }
            }, trigger: 'blur'
        }
    ]
};

注意: exrules 通过 JS 代码配置(不通过配置面板),需在 vapp.rend() 之前设置。子表校验时必填检查先于自定义校验执行。

9.18 批量生成二维码(qrGenConfig) #

在工具栏添加「生成二维码」按钮,勾选行后批量生成指定字段的二维码,支持打印输出标签。

配置位置: ⚙️ 数据管理 → 批量按钮

qrGenConfig = {"field":"order_no","label":"order_no","size":120,"cols":4}
属性 说明 默认值
field 生成二维码内容的字段名 必填
label 二维码下方显示的标签字段名 同 field
size 二维码尺寸(px) 120
cols 每行显示几列 4
template URL 模板,{value} 会被替换为字段值,如 "https://xx.com/scan?id={value}" 空(用原始值)
correctLevel 纠错等级:L(7%) / M(15%) / Q(25%) / H(30%) H
colorDark 前景色(二维码深色部分) #000000
colorLight 背景色(二维码浅色部分) #ffffff

使用流程:

  1. 在表格中勾选一行或多行数据
  2. 工具栏自动出现绿色「QR Code」按钮
  3. 点击按钮弹出对话框,网格展示所有选中行的二维码 + 标签文字
  4. 点击「打印」批量打印二维码标签(每个带虚线边框,方便裁剪)

示例:

基础用法——直接用字段值生成二维码:

{"field":"order_no","label":"order_no","size":120,"cols":4}

URL 模板——扫码后跳转到指定页面:

{"field":"order_no","label":"order_no","template":"https://mysite.com/track?id={value}","size":100,"cols":5}

自定义外观——带品牌色的二维码:

{"field":"code","label":"name","size":150,"cols":3,"correctLevel":"M","colorDark":"#1a73e8"}

配置后表格自动显示勾选列(无需额外设置 showSelectionCol)。当二维码内容过长导致生成失败时,自动降级为文本展示。

9.19 打印配置(printConfig) #

开启 print = true 显示打印按钮后,通过 printConfig(JSON 格式)自定义打印样式与内容,无需开发即可输出规范的单据/报表。

配置位置: 📋 表格显示 → 显示开关 → 打印配置

printConfig = {"printTitle":"领料单","showIndex":true,"footer":"制表人:___|审核人:___"}

基础配置项:

属性 说明 默认值
printTitle 自定义打印标题(空则用页面标题) 空
showDate 标题下显示打印日期 false
landscape 纸张方向:auto(列数>8 自动横向)/ landscape / portrait auto
pageMargin 页边距,如 12mm 12mm
fontFamily 打印字体 微软雅黑
fontSize 打印字号,如 14px 12px
formGridCols 表单字段列数(1/2/3) 2
showIndex 显示序号列 false
stripe 隔行变色 false
showSummary 主表合计行 同页面 showSummary
detailSummary 子表合计行 同页面 detailSummary
excludeFields 不打印的字段,逗号分隔,如 id,status 空

二维码 / 条码:

属性 说明 默认值
qrField 二维码内容字段,如 order_no 空
qrSize 二维码尺寸(px) 80
qrLabel 二维码下方显示字段名标签 false
barField 一维码(CODE128)内容字段 空
barHeight 一维码高度(px) 50
barWidth 一维码线条宽度 1.5
barDisplayValue 一维码下方显示原始值 true

表单引擎(Form 模板)中未配置 qrField 时,自动回退页面头部二维码(qrHeaderField),与页面显示内容一致(含 qrHeaderTemplate 模板)。

页脚签名(footer):

"footer": "申请人:___|审批人:___|日期:___"

| 分列左右对齐显示,\n 分行,适合打印审批签字区。

场景化配置:

一个 CRUD 页面有多处打印入口,全局配置对所有场景生效;也可用场景子键为指定场景单独定制,场景中未配置的项自动回退全局:

场景键 覆盖的打印入口
table 列表页表格
form 新增/修改弹窗(及 Form 模板页)
card 查看弹窗详情卡片
printConfig = {
  "fontSize": "12px",
  "table": {"landscape": "portrait", "showIndex": true},
  "form": {"formGridCols": 3, "footer": "制表:___|审核:___"},
  "card": {"showDate": true}
}

上例:列表页纵向带序号,编辑弹窗三列布局带签字区,查看弹窗显示日期,其余配置三处共用。

打印内容规则:

  • 列表页:打印当前表格字段,mergeFields(行合并)生效,与页面显示一致
  • 编辑弹窗:主表字段 + 子表明细,formGridCols 控制主表字段列数;只读字段(constFields)正常显示,仅排除第一位主键;其他不想打印的字段用 excludeFields
  • 查看弹窗:详情字段 + 关联子表(viewDsDict 弹窗数据)

10. 常见问题 #

Q: 配置保存后没有生效?

「保存」写入测试配置,「发布」才会覆盖线上。确认点击的是正确按钮。

Q: 新增提交提示「没有任何修改项」?

所有字段值为 null 时会触发此提示。检查 aform 配置是否正确,字段名是否与数据一致。

Q: 修改时找不到主键?

constFields 第一位必须是主键字段名,且该字段必须存在于表格数据中(加入 tableFields 或不设置 tableFields)。

Q: 下拉框没有选项?

设置 optionDict 配置固定选项,或设置 option_id 从数据集动态加载,数据集第一行第一列为字段名。

Q: 子表数据没有加载?

确认设置了 ztable_id,且该数据集支持接收 fid 参数(主键值)。子表必须包含 id 字段作为主键。

Q: 表格列太多横向滚动?

设置 shortTableFields 显示少量关键列,其余字段在展开行中显示。或使用 widthDict 控制列宽。

Q: 导出按钮导出的是什么?

默认导出 shortTableFields 或 tableFields 中的字段,使用 fullData(全量数据,非当前页)。导出对话框可自定义文件名并选择 CSV 或 Excel 格式。设置 daochu_id 可自定义导出数据集。

Q: 如何只导出选中的行?

导出下拉菜单选「选择行导出」,表格会出现勾选列,勾选后再导出即可(文件名自动带 _选中行 后缀)。

Q: 双击单元格编辑不生效?

需开启 cellEditable = true,且该字段必须在 mform 中并且不在 constFields 里。保存时调用 update_id。

Q: 子表如何做跨字段/跨表校验?

通过 exrules 配置自定义 validator 函数,validator 中可通过 rule.row 访问同行其他字段,通过 vapp.form 访问主表字段。详见 9.17。

Q: 移动端显示效果不好?

开启 isMobileCard = true 在移动端切换为卡片列表模式,通过 tableFields 控制显示字段,shortCol 控制列数。移动端点击行第一列可弹出操作菜单,底部固定「搜索/新增」工具栏,过滤与搜索收纳在底部面板中。


版权说明: SmartChart / SmartCRUD 由 JohnYan 设计

EN