| name | yida-custom-page |
| description | 宜搭自定义页面开发技能,包含宜搭表单 JS API 调用(增删改查/流程/工具类共 27 个)、React 16 JSX 组件开发规范、状态管理模式与编码约束。 |
| license | MIT |
| compatibility | ["opencode","claude-code"] |
| metadata | {"audience":"developers","workflow":"yida-development","version":"1.0.0","tags":["yida","low-code","react","custom-page"]} |
宜搭自定义页面开发技能
概述
本技能提供在阿里宜搭低代码平台上开发自定义页面的完整能力,涵盖从编码到部署的全流程:
| 能力 | 说明 |
|---|
| 表单数据操作 | 通过宜搭前端 JS API(this.utils.yida.*)对表单数据进行增删改查 |
| JSX 组件开发 | 编写 React 16 兼容的 JSX 代码,实现个性化定制页面 |
| AI 能力集成 | 调用大模型 AI 接口(/query/intelligent/txtFromAI.json)实现智能文本生成 |
| 自动编译部署 | 通过工具链将源码编译、压缩,并自动合并到宜搭 Schema 中保存 |
何时使用
当以下场景发生时使用此技能:
- 用户需要开发自定义展示页面(非表单)
- 用户需要实现复杂的页面交互逻辑
- 用户需要调用宜搭 JS API 进行数据操作
- 已有自定义页面,需要编写或修改 JSX 代码
使用示例
注意:编译和发布功能由 yida-publish-page 技能提供,此处仅作流程说明。
示例 1:编译源码
场景:将 JSX 源码编译为宜搭可用的格式
依赖:需先安装 yida-publish-page 依赖
命令:
cd .claude/skills/yida-publish-page/scripts && npm install
node babel-transform/transform.js pages/src/my-page.js
示例 2:发布页面
场景:编译并发布自定义页面到宜搭平台
命令:
node .claude/skills/yida-publish-page/scripts/publish.js APP_XXX FORM-XXX pages/src/my-page.js
快速开始
前置条件
- Node.js 16+(用于 Babel 编译和发布)
- Python 3.12+ +
playwright(用于登录态管理)
- 首次使用需安装依赖:
cd .claude/skills/yida-publish/scripts && npm install
pip install playwright && playwright install chromium
编译源码
node scripts/babel-transform/transform.js <源文件路径>
编译流程:
源文件(.js) → @ali/vu-babel-transform (Babel 转换) → UglifyJS (压缩) → <name>.compile.js
部署到宜搭
cd .claude/skills/yida-publish-page/scripts
npm install
node publish.js <appType> <formUuid> <源文件路径>
部署流程:
编译源码(Babel + UglifyJS) → 代码动态构建 Schema JSON(填入 source/compiled)
→ 调用 yida-login 获取登录态(Cookie 持久化) → 调用 saveFormSchema 接口保存
参数说明:
| 参数 | 说明 | 示例 |
|---|
appType | 应用 ID | APP_XXX |
formUuid | 表单 ID | FORM-XXX |
源文件路径 | 源码文件路径 | pages/src/xxx.js |
baseUrl 无需手动传入,脚本会自动调用 login.py 获取登录态并从中读取 base_url。
开发规范
以下规范是编写宜搭自定义页面代码的核心约束,必须严格遵守。
运行环境与约束
宜搭自定义页面的 JSX 组件本质上是 React 类组件中的 render 方法,而非独立的 React 组件。因此存在以下关键约束:
| 约束 | 说明 |
|---|
| React 版本 | 必须兼容 React 16,禁止使用 Hooks(useState、useEffect 等) |
| 单文件 | 所有代码写在一个文件中(如 index.js) |
| 三方包引入 | 禁止使用 import/require 语法,如需使用第三方库,必须通过 this.utils.loadScript 加载 CDN 脚本,参考 yida-api.md 的「工具类 API」章节。 |
| 函数导出格式 | 使用 export function xxx() {} 格式导出函数 |
| 样式 | 所有 css 必须写在 renderJsx 的方法中,通过 style 的方式引入 |
this 上下文 | 所有导出函数中的 this 指向宜搭页面的 React 类实例 |
禁止使用 this.setState 管理业务状态 | this.setState 已被覆盖,仅用于 forceUpdate(通过更新 timestamp) |
| JavaScript 版本 | 使用 ES2015 (ES6) 语法,不能高于 ES2015 版本 |
| 必须定义 renderJsx 函数 | renderJsx 是宜搭自定义页面核心渲染函数,也是入口函数,必须严格定义,不要改为其他名称 |
文件结构
一个完整的宜搭自定义页面源文件必须包含:
_customState 变量
- getCustomState 函数
- setCustomState 函数
- forceUpdate 函数
- didMount 函数
- didUnmount 函数
- renderJsx 函数
以下是一个完整自定义页面示例,包含状态管理、生命周期钩子、渲染函数
const _customState = {
count: 0,
loading: false,
};
export function getCustomState(key) {
if (key) {
return _customState[key];
}
return { ..._customState };
}
export function setCustomState(newState) {
Object.keys(newState).forEach(function(key) {
_customState[key] = newState[key];
});
this.forceUpdate();
}
export function forceUpdate() {
this.setState({ timestamp: new Date().getTime() });
}
() {
}
() {
}
() {
.({ : });
..({ : , : });
}
() {
{ timestamp } = .;
(
);
}
状态管理使用方式
const state = this.getCustomState();
const count = this.getCustomState('count');
this.setCustomState({ count: count + 1, loading: true });
this.forceUpdate();
生命周期钩子
| 钩子函数 | 触发时机 | 典型用途 |
|---|
didMount() | 页面 DOM 加载渲染完毕 | 初始化数据加载、启动定时器、绑定事件 |
didUnmount() | 页面节点从 DOM 移除 | 清理 setInterval / setTimeout、解绑事件 |
全局变量
| 变量 | 类型 | 说明 |
|---|
window.g_config._csrf_token | String | CSRF Token,调用需认证的接口(如 AI 接口、Schema 保存)时必须携带 |
window.loginUser.userId | String | 当前登录用户的工号 |
window.loginUser.userName | String | 当前登录用户的姓名 |
this.state.urlParams | Object | 页面 URL 中的查询参数 |
编码注意事项
-
自定义方法必须用 export function 定义:凡是需要在方法内部使用 this(包括 this.utils.yida.*、this.setCustomState 等)的自定义方法,必须且只能使用 export function 方法名() {} 的形式定义,调用时使用 this.方法名()。禁止使用 const fn = () => {}、const fn = function() {} 等形式定义需要访问 this 的方法,这些形式无法被宜搭运行时正确绑定 this:
export function didMount() {
this.loadStatistics();
}
export function loadStatistics() {
this.utils.yida.searchFormDatas({ formUuid: 'FORM-XXX', pageSize: 10 });
}
export function didMount() {
loadStatistics();
}
function loadStatistics() {
this.utils.yida.searchFormDatas(...);
}
const loadStatistics = () => {
this...(...);
};
loadStatistics = () {
...(...);
};
API 参考
表单数据操作
通过 this.utils.yida.<方法名>(params) 调用,所有接口返回 Promise。
| 方法 | 说明 | 必填参数 |
|---|
saveFormData | 新建表单实例 | formUuid, appType, formDataJson |
updateFormData | 更新表单实例 | formInstId, updateFormDataJson |
deleteFormData | 删除表单实例 | formUuid |
getFormDataById | 根据实例 ID 查询详情 | formInstId |
searchFormDatas | 按条件搜索表单实例详情列表 | formUuid |
searchFormDataIds | 按条件搜索表单实例 ID 列表 | formUuid |
getFormComponentDefinationList | 获取表单定义 | formUuid |
常用示例 — 新建表单数据:
this.utils.yida.saveFormData({
formUuid: 'FORM-XXX',
appType: window.pageConfig.appType,
formDataJson: JSON.stringify({
textField_xxx: '单行文本',
textareaField_xxx: '多行文本',
}),
}).then(function(res) {
console.log('新建成功,实例ID:', res.result);
}).catch(function(err) {
this.utils.toast({ title: err.message, type: 'error' });
}.bind(this));
常用示例 — 搜索表单数据:
this.utils.yida.searchFormDatas({
formUuid: 'FORM-XXX',
searchFieldJson: JSON.stringify({ textField_xxx: '查询值' }),
currentPage: 1,
pageSize: 10,
}).then(function(res) {
console.log('查询结果:', res.data);
}).catch(function(err) {
this.utils.toast({ title: err.message, type: 'error' });
}.bind(this));
流程操作
| 方法 | 说明 | 必填参数 |
|---|
startProcessInstance | 发起流程 | formUuid, processCode, formDataJson |
updateProcessInstance | 更新流程实例 | processInstanceId, updateFormDataJson |
deleteProcessInstance | 删除流程实例 | processInstanceId |
getProcessInstanceById | 根据实例 ID 查询流程详情 | processInstanceId |
getProcessInstances | 按条件搜索流程实例详情列表 | — |
getProcessInstanceIds | 按条件搜索流程实例 ID 列表 | — |
表单设计类 API
以下接口用于表单页面的创建和配置,通过 HTTP 请求调用:
| 方法 | 说明 | 调用方式 |
|---|
saveFormSchemaInfo | 创建空白表单 | POST /dingtalk/web/{appType}/query/formdesign/saveFormSchemaInfo.json |
getFormSchema | 获取表单 Schema | GET /alibaba/web/{appType}/_view/query/formdesign/getFormSchema.json |
saveFormSchema | 保存表单 Schema | POST /dingtalk/web/{appType}/_view/query/formdesign/saveFormSchema.json |
updateFormConfig | 更新表单配置 | POST /dingtalk/web/{appType}/query/formdesign/updateFormConfig.json |
完整参数说明请参考 yida-api.md 的「表单设计类 API」章节。
大模型 AI 接口
以下接口用于调用大模型 AI 文本生成能力:
| 方法 | 说明 | 调用方式 |
|---|
txtFromAI | AI 文本生成 | POST /query/intelligent/txtFromAI.json |
主要参数:_csrf_token(CSRF 令牌)、prompt(提示词)、skill(技能类型,如 ToText)、maxTokens(最大返回 token 数)
完整参数说明和示例请参考 model-api.md。
工具类 API 速查
以下工具函数通过 this.utils.<方法名>() 调用,无需 yida 命名空间:
| 方法 | 用途 | 典型场景 |
|---|
toast | 轻提示 | 操作成功/失败提示、loading 状态 |
dialog | 对话框 | 确认操作、复杂内容展示 |
formatter | 格式化 | 日期、金额、手机号格式化 |
getDateTimeRange | 获取时间范围 | 按日/月/周筛选数据 |
getLoginUserId / getLoginUserName | 获取当前用户 | 记录操作人、数据权限控制 |
getLocale | 获取语言环境 | 多语言适配 |
isMobile | 判断移动端 | 响应式布局适配 |
isSubmissionPage | 判断是否提交页面 | 页面逻辑区分 |
isViewPage | 判断是否查看页面 | 页面逻辑区分 |
openPage | 打开新页面 | 页面跳转、外链打开 |
router.push | 页面路由跳转工具 | 页面路由跳转、避免新开页面 |
previewImage | 图片预览 | 图片查看、多图轮播 |
loadScript | 动态加载脚本 | 引入第三方库(如二维码生成) |
完整参数说明和示例请参考 yida-api.md 的「工具类 API」章节。
工具链
| Skill | 说明 | 用法 |
|---|
| yida-login | 登录态管理(Cookie 持久化 + 扫码登录) | python3 .claude/skills/yida-login/scripts/login.py |
| yida-publish-page | 编译源码 + 构建 Schema + 发布到宜搭 | node .claude/skills/yida-publish-page/scripts/publish.js <appType> <formUuid> <源文件路径> |
| yida-page-config | 页面配置(URL 验证、公开访问/分享配置) | node .claude/skills/yida-page-config/scripts/verify-short-url.js <appType> <formUuid> /o/xxx |
编译 + 发布(一键完成)
cd .claude/skills/yida-publish-page/scripts
npm install
node publish.js <appType> <formUuid> <源文件路径>
处理流程:
- 通过
@ali/vu-babel-transform 将 JSX 转换为 ES5 + UglifyJS 压缩
- 通过代码动态构建完整的 Schema JSON,将
source 和 compiled 填入 actions.module
- 调用
yida-login 获取登录态(Cookie 持久化,首次需扫码登录)
- 通过 HTTP POST 调用
saveFormSchema 接口保存 Schema
仅编译(不发布)
node .claude/skills/yida-publish-page/scripts/babel-transform/transform.js <源文件路径>
输入 JSX 源文件,输出编译压缩后的 <name>.compile.js(与源文件同目录)。