From 86e114ccd5791c0a2aaf6b204f3618976ce6522d Mon Sep 17 00:00:00 2001 From: augushong Date: Fri, 11 Sep 2026 13:09:09 +0000 Subject: [PATCH] =?UTF-8?q?docs(skills):=20=E6=9B=B4=E6=96=B0=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=8A=80=E8=83=BD=E6=96=87=E6=A1=A3=E8=A6=86=E7=9B=96?= =?UTF-8?q?=E5=8F=97=E6=8E=A7=E6=A8=A1=E5=BC=8F=E4=B8=8E=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/skills/ulthon-admin-table/SKILL.md | 165 ++++++++++++++++++++- 1 file changed, 162 insertions(+), 3 deletions(-) diff --git a/.agents/skills/ulthon-admin-table/SKILL.md b/.agents/skills/ulthon-admin-table/SKILL.md index 8a76249..3a5bf6a 100644 --- a/.agents/skills/ulthon-admin-table/SKILL.md +++ b/.agents/skills/ulthon-admin-table/SKILL.md @@ -1,6 +1,6 @@ --- name: "ulthon-admin-table" -description: "后台列表页表格机制与定制完整指南:核心机制(ua 命名空间、三件套)、字段配置、内置渲染器、按钮系统(含页面分类标准 A/B/C/D)、搜索系统(前端配置 + 后端 buildTableParames)、后端配套、常见模式与排错。需要业务定制 CURD 生成的列表页(加按钮、改字段、调搜索)或排查按钮/搜索不生效时调用。" +description: "后台列表页表格机制与定制完整指南:核心机制(ua 命名空间、三件套)、字段配置、内置渲染器、按钮系统(含页面分类标准 A/B/C/D)、搜索系统(前端配置 + 后端 buildTableParames)、后端配套、常见模式与排错、多形态渲染(受控模式 controlled、layoutList 五级模板协议 tplFunction/tplLay/tplVue/tplLayId/tplVueId、卡片形态、渲染上下文)。需要业务定制 CURD 生成的列表页(加按钮、改字段、调搜索)、排查按钮/搜索不生效、或自定义卡片/模板形态时调用。" --- # 后台表格机制与定制(ulthon-admin-table) @@ -16,6 +16,7 @@ CURD 生成器生成列表页骨架后,所有业务定制(按钮、字段渲 - 自定义字段渲染(图片、状态、关联数据) - 实现状态流转按钮(带 `_if` 显隐) - 跨控制器跳转按钮 +- 列表自定义卡片/模板形态(`controlled` + `layoutList`,见第十一章) ## 一、核心机制总览 @@ -25,9 +26,10 @@ CURD 生成器生成列表页骨架后,所有业务定制(按钮、字段渲 | 文件 | 作用 | |------|------| -| `admin-table.js` (1650 行) | 表格核心:render / formatCols / renderOperat / 内置渲染器 / 搜索监听 | +| `admin-table.js` | 表格核心:render / formatCols / renderOperat / 内置渲染器 / 搜索监听 / 受控模式接线与多形态渲染(reloadData shim、五级模板协议、渲染上下文) | +| `admin-table-store.js` | 受控模式数据层(全局 `window.UA_TABLE_STORE`):dataProvider / pager / selection / reload 四模块 | | `admin-core.js` | ua 全局组装、headers、url、parame 等工具 | -| `admin-utils.js` | `ua.getDataBrage` 等数据读取工具 | +| `admin-utils.js` | `ua.getDataBrage`、`ua.checkMobile`、`ua.getPageSetting` 等工具 | | `admin-listen.js` | 事件监听(`ua.listen`) | | `admin-api.js` | AJAX 请求封装(`ua.request`) | | `ulthon-admin.js` | 入口(把 UA_ADMIN 挂到 window.ua) | @@ -650,6 +652,163 @@ CURD 生成时会将关联模型的全部字段(如 `systemAdmin.*`)输出 | 实际示例:标准 CRUD | `extend/base/admin/view/system/admin/index.js` | | 实际示例:`_if` 条件按钮 | `app/admin/view/system/timer_config/index.js` | | 实际示例:自定义 templet | `app/admin/view/system/timer_log/index.js` | +| `controlled` 受控分支接线 | `admin-table.js:914`(注册 store、自建分页与模板容器、首屏取数) | +| reloadData shim(受控分流/透传) | `admin-table.js:21` | +| `ua.table.reloadData` / `ua.table.checkStatus` 分发入口 | `admin-table.js:373` / `:379` | +| store 五入口(register/has/reload/fetch/checkStatus) | `admin-table-store.js:531` | +| layoutList 规范化(字符串/对象条目) | `admin-table.js:69`(normalizeLayoutList) | +| 五级钩子优先级解析 | `admin-table.js:194`(resolveLayoutEngine) | +| 内置 card 模板(tplFunction) | `admin-table.js:112`(builtinCardTemplate) | +| 渲染上下文构建器 | `admin-table.js:394`(buildLayoutContext) | +| tplFunction/laytpl/Vue 调用约定注释 | `admin-table.js:466-508` | +| renderLayoutForm(模板管线入口) | `admin-table.js:511` | +| 统一行选中委托(data-table-id + data-id) | `admin-table.js:158` | +| getLayoutForm / setLayoutForm | `admin-table.js:670` / `:678` | +| 默认形态解析(layoutDefault/checkMobile/记忆) | `admin-table.js:943` | +| 视图切换按钮注入(条目 > 1) | `admin-table.js:732`,记忆写入 `:2025` | +| `ua.checkMobile` 判定 | `admin-utils.js:6`,实现 `public/static/common/js/app.js:63` | +| 实际示例:名片形态(Vue 模板) | `extend/base/admin/view/system/admin/index.html:19` + `index.js:10` | + +## 十一、多形态渲染(受控模式与自定义模板) + +列表除了引擎表格形态,还能以卡片等自定义模板形态渲染。模板形态运行在受控模式之上:数据由框架数据层接管,模板只负责"一行/一屏数据长什么样"。官方完整范例是用户管理的名片形态(`extend/base/admin/view/system/admin/index.html:19` 的 usercardTpl 节点 + `extend/base/admin/view/system/admin/index.js:10` 的 layoutList 配置)。 + +### 11.1 受控模式 + +`ua.table.render` 的 options 加 `controlled: true` 即开启。受控后页面数据由 `admin-table-store.js`(全局 `window.UA_TABLE_STORE`)接管:引擎不再自己发请求,首屏、搜索、排序、翻页、switch 回滚、删除刷新等所有数据重载统一走 reloadData 的 shim 分流进 store。 + +| 组件 | 说明 | +|------|------| +| shim(`table.reloadData` 包装) | 受控表(store 已注册该 id)→ `store.reload`;非受控表原样透传引擎(admin-table.js:21) | +| `ua.table.reloadData(id, opts)` | 页面代码刷新表格的推荐入口:按受控与否自动分流,受控/非受控页面通吃(admin-table.js:373) | +| `ua.table.checkStatus(id)` | 取选中行的推荐入口,同样自动分流(admin-table.js:379) | + +旧页面里直呼 `layui.table.reloadData` / `layui.table.checkStatus` 的代码仍会被 shim 覆盖到,但新代码请统一用 `ua.table.reloadData` / `ua.table.checkStatus`。 + +store 内部四个模块(admin-table-store.js): + +| 模块 | 职责 | +|------|------| +| `dataProvider` | 取数(fetch)与状态:where / sort / 当页数据 / count | +| `pager` | laypage 封装;受控表分页条由框架自建(`.ua-store-pager`),页面不用管 | +| `selection` | 选中集合:跨页保持勾选,与引擎勾选是同一事实源 | +| `reload` | 重载编排:合并 where/page 后 fetch,成功回调里按当前形态分发渲染 | + +对外五个主入口 `register / has / reload / fetch / checkStatus`(admin-table-store.js:531)。业务页面一般不直接调 store,用上表两个 `ua.table.*` 分发入口就够了。 + +受控表在引擎视图与分页条之间有一个模板渲染容器 `#ua-layout-{tableId}`,模板形态的内容渲染在这里,与引擎数据区互斥显隐;工具栏与搜索区两形态共用(卡片形态下新增/批量删除/搜索照常可用)。 + +### 11.2 五级模板协议(layoutList) + +`layoutList` 声明表格支持的形态清单,条目有两种写法: + +```js +// 字符串条目:'table'/'card' 有内置实现(标题缺省「表格」/「卡片」), +// 其他字符串以自身为标题 +layoutList: ['table', 'card'] + +// 对象条目:自定义形态,name 必填,title 供视图切换下拉显示,icon 可选 +layoutList: ['table', {name: 'usercard', title: '名片', tplVueId: '#usercardTpl'}] +``` + +**模板钩子五级优先级**(按序取第一个命中的,提供一种即生效): + +| 优先级 | 钩子 | 类型 | 引擎 | +|--------|------|------|------| +| 1 | `tplFunction` | function | 框架行循环,`(行上下文, 列表上下文)` 返回单行 HTML 字符串 | +| 2 | `tplLay` | string | laytpl 模板字符串,行级作用域 | +| 3 | `tplVue` | string | Vue 模板字符串,列表级单实例 | +| 4 | `tplLayId` | string | ` +``` + +```js +layoutList: ['table', {name: 'mycard', title: '自定义卡', tplLayId: '#myCardTpl'}], +``` + +laytpl 语法实测(layui 2.10.1 内置 laytpl v2.0.0):`{{ d.x }}` 与 `{{= d.x }}` 都会 HTML 转义,`{{- d.x }}` 才是原样输出。`_cells`/`_operatHtml` 是渲染产物 HTML,必须用 `{{- }}`;纯文本用 `{{ }}` 转义更安全;`{{# }}` 写 JS 语句;列表上下文是 `d._list`。 + +**Vue 形态(tplVueId)**,简版: + +```html + + +``` + +```js +layoutList: ['table', {name: 'mycard', title: '自定义卡', tplVueId: '#myVueTpl'}], +``` + +- `v-for="d in rows"` 承接行循环;`_cells`/`_operatHtml` 必须 `v-html` 输出,纯文本字段用 `{{ }}` 原生插值(自动转义);列表上下文是 `list` +- 行根元素带 `data-table-id` + `data-id` 两属性即获得统一行选中委托:点卡片切换勾选、选中态经 `:class` 绑 `ua-data-card-checked` 高亮回显;按钮/表单控件自动豁免不误触,零 JS +- 事件无需自己绑定:操作按钮(data-open/data-request 等属性)与 switch/checkbox 经页面级委托与 form 事件天然生效;`@click` 可用,但处理函数内不要修改模板数据(渲染上下文被冻结,数据更新一律整卡销毁重建) + +**完整官方范例**:用户管理名片卡片,接入面只有两处,建议直接对照源码: + +| 位置 | 内容 | +|------|------| +| `extend/base/admin/view/system/admin/index.html:19` | usercardTpl 模板节点 + 页面级网格样式 | +| `extend/base/admin/view/system/admin/index.js:10` | layoutList 一行接入(`controlled: true` 在第 5 行) | + +该范例演示了三种典型取值通道:渲染器列(status)用 `_cells` + v-html 承接框架语义、纯文本列(username/create_time/phone)直接原始字段插值、头像(head_img)因名片需要圆形大图绕开渲染器直接绑原始字段。模板形态的网格布局由模板自带容器承担(Vue 形态不带内置卡片网格类)。 + +### 11.5 手机端默认行为 + +- 手机端判定 `ua.checkMobile()`(admin-utils.js:6,实现 public/static/common/js/app.js:63):UA 关键字(Android/iPhone/iPad 等)或 `window.screen` 宽 < 600 且高 < 800。判的是物理屏幕指标,**浏览器开发者工具仅改视口宽度不会触发**;设备仿真验证手机默认形态时,必须同时覆写 UA 或仿真 screen 尺寸,仅设 viewport 无效 +- `layoutList` 含 `card` 条目时,手机端默认进入 card 形态;localStorage 记忆值优先级更高(记忆值不在 layoutList 内时忽略) +- 卡片形态能力边界:工具栏(刷新/新增/批量删除/导出)与搜索区两形态共用、照常可用;勾选语义由卡片勾位图标与选中委托承接(checkbox 列本身不进模板上下文);`_disabled` 行整元素不可勾选 ## 相关技能