跳到主要内容

数据录入页面

数据录入页面是专门用于创建表单数据录入界面的页面类型,基于网格布局架构实现可视化表单设计和数据提交功能。它负责表单组件的布局管理、数据模型绑定和用户交互处理,支持可视化配置的表单字段排列、验证规则和提交流程。

数据录入页面元素分层结构为Meta(pages.Meta) → Type(pages.FormPageType) → 实例,开发者可通过JitAi的可视化开发工具快捷地创建数据录入页面实例元素。

当然,开发者也可以创建自己的Type元素,或者在自己的App中改写JitAi官方提供的pages.FormPageType元素,以实现自己的封装。

快速开始

创建实例元素

目录结构

testDataEntryPage/
├── e.json # 元素配置文件
├── scheme.json # 页面布局和组件配置
├── page.ts # 页面逻辑代码
├── PageRender.tsx # 页面渲染组件
├── page.style.ts # 页面样式文件
└── index.ts # 入口文件

e.json文件

e.json配置示例
{
"type": "pages.FormPageType",
"resourceName": "index",
"title": "客户信息录入",
"dataModel": "models.CustomerModel",
"platform": "PC",
"frontBundleEntry": "./index.ts",
"outputName": "index"
}

scheme.json文件

scheme.json配置示例
{
"layout": [
{
"i": "Form1",
"x": 0,
"y": 0,
"w": 48,
"h": 30,
"minW": 20,
"minH": 10,
"maxW": 48,
"maxH": 50
}
],
"componentList": [
{
"name": "Form1",
"title": "表单组件",
"type": "components.Form",
"config": {
"isShowAllEditField": true,
"isShowCreateAgain": true,
"isShowResultRecord": true,
"requireElements": [
{
"type": "models.Meta",
"name": "models.CustomerModel"
}
],
"layoutDict": {
"custName": {
"key": "custName",
"pos": "mid",
"layout": {
"w": 120,
"h": 2,
"x": 0,
"y": 0,
"i": "custName"
}
}
}
}
}
],
"variableList": [
{
"name": "currentUser",
"title": "当前用户",
"dataType": "Stext",
"value": ""
}
],
"functionList": [
{
"name": "validateForm",
"title": "表单验证",
"args": [
{
"name": "formData",
"title": "表单数据",
"dataType": "JitDict"
}
],
"returnType": "Checkbox"
}
],
"matchUarParamsVariableNameList": ["userId", "deptId"],
"autoIncrementId": 1
}

page.style.ts文件

page.style.ts样式配置
import type { GlobalToken } from 'antd';
import { css } from '@emotion/react';

export const pageStyle = (token: GlobalToken) => css`
.form-container {
padding: 24px;
background: ${token.colorBgContainer};
border-radius: ${token.borderRadius}px;
}

.form-title {
font-size: ${token.fontSizeLG}px;
color: ${token.colorTextHeading};
margin-bottom: 16px;
}
`;

export const pageGlobalStyle = (token: GlobalToken) => css`
.ant-form-item-label {
font-weight: 500;
}

.required-field {
color: ${token.colorError};
}
`;

page.ts文件

page.ts实现示例
import { Jit } from 'jit';
import schemeJson from './scheme.json';

type BaseComponent = InstanceType<typeof Jit.BaseComponent>;

class PageCls extends Jit.GridPage {
Form1!: BaseComponent;
currentUser!: InstanceType<typeof Jit.datatypes.Stext>;
scheme: Record<string, any> = schemeJson;

bindEvent() {
// 绑定表单提交事件
this.Form1.subscribeEvent("afterSubmit", async (e) => {
console.log("表单提交成功:", e.data);
this.refresh();
});

// 绑定表单调用事件
this.Form1.subscribeEvent("afterCall", async () => {
console.log("表单调用完成");
});
}

validateForm(formData: any): boolean {
// 自定义验证逻辑
return formData.custName && formData.phone;
}
}

export default PageCls;

调用示例

在其他页面中调用数据录入页面
// 跳转到数据录入页面
this.app.openPage('pages.CustomerDataEntry');

// 在模态框中打开数据录入页面
this.app.openModal({
element: 'pages.CustomerDataEntry',
title: '新增客户',
width: 800,
height: 600
});

// 带参数跳转
this.app.openPage('pages.CustomerDataEntry', {
userId: '123',
deptId: 'dept001'
});

元素配置

e.json配置

参数名类型必填默认值说明
typestring-固定值"pages.FormPageType"
titlestring-页面标题
dataModelstring-关联的数据模型fullName
platformstring"PC"平台类型,支持PC、Mobile
resourceNamestring"index"资源名称
frontBundleEntrystring"./index.ts"前端入口文件路径
outputNamestring"index"输出名称

scheme.json配置

参数名类型必填默认值说明
layoutLayout[][]组件布局配置数组
componentListobject[][]页面组件配置列表
variableListobject[][]页面变量列表
functionListobject[][]页面函数列表
matchUarParamsVariableNameListstring[][]匹配URL参数的变量名列表
autoIncrementIdnumber1自增ID
aiConfigobject-AI配置

Layout布局配置

参数名类型必填默认值说明
istring-组件唯一标识
xnumber-水平位置(网格单位)
ynumber-垂直位置(网格单位)
wnumber-宽度(网格单位)
hnumber-高度(网格单位)
minWnumber-最小宽度
minHnumber-最小高度
maxWnumber-最大宽度
maxHnumber-最大高度
staticbooleanfalse是否静态(不可拖拽)
isDraggablebooleantrue是否可拖拽
isResizablebooleantrue是否可调整大小

方法

init

初始化页面,加载配置、变量和组件。

返回值

类型说明
Promise<void>初始化完成Promise

使用示例

页面初始化
class PageCls extends Jit.GridPage {
async init() {
await super.init();
console.log('页面初始化完成,isReady:', this.isReady);
}
}

bindEvent

绑定页面事件,在页面初始化后自动调用。

使用示例

事件绑定
bindEvent() {
// 绑定表单提交事件
this.Form1.subscribeEvent("afterSubmit", async (e) => {
console.log('提交的数据:', e.data);
});

// 绑定页面刷新事件
this.subscribeEvent("PAGE_REFRESH", async () => {
this.refresh();
});
}

subscribeEvent

订阅页面级事件。

参数详解

参数名类型必填说明
messageNamestring | symbol事件名称
callbackHandler<T>事件回调函数

返回值

类型说明
string事件句柄ID

使用示例

订阅事件
const handlerId = this.subscribeEvent('CUSTOM_EVENT', async (e) => {
console.log('接收到自定义事件:', e);
});

publishEvent

发布页面级事件。

参数详解

参数名类型必填说明
messageNamestring | symbol事件名称
exRecord<string, any>附加数据

返回值

类型说明
Promise<any>事件发布结果

使用示例

发布事件
await this.publishEvent('DATA_UPDATED', {
dataId: 123,
timestamp: Date.now()
});

unSubscribeEvent

取消订阅事件。

参数详解

参数名类型必填说明
handlerIdstring事件句柄ID

使用示例

取消订阅
const handlerId = this.subscribeEvent('TEST_EVENT', callback);
this.unSubscribeEvent(handlerId);

off

取消事件订阅的简化方法。

参数详解

参数名类型必填说明
handlerIdstring事件句柄ID

使用示例

取消事件订阅
const handlerId = this.subscribeEvent('TEST_EVENT', callback);
this.off(handlerId);

newVariable

创建页面变量实例。

参数详解

参数名类型必填说明
varConfigDataTypeConfig变量配置
valueany初始值

返回值

类型说明
any变量实例

使用示例

创建变量
const userNameVar = this.newVariable({
name: 'userName',
title: '用户名',
dataType: 'Stext'
}, '张三');

newComponent

创建组件实例。

参数详解

参数名类型必填说明
typestring组件类型
createCompConfigany组件配置

返回值

类型说明
Promise<any>组件实例

使用示例

创建组件
const button = await this.newComponent('components.Button', {
name: 'submitBtn',
title: '提交按钮',
config: {
btnType: 'primary'
}
});

refresh

刷新页面。

使用示例

刷新页面
// 手动触发页面刷新
this.refresh();

// 在数据更新后刷新页面
async updateData() {
await this.saveData();
this.refresh();
}

refreshPageVariable

刷新页面变量值,从URL参数重新获取变量值。

使用示例

刷新页面变量
// 当URL参数变化时,重新加载变量值
onUrlChange() {
this.refreshPageVariable();
console.log('页面变量已更新');
}

parseVariableInQ

解析Q表达式中的变量引用。

参数详解

参数名类型必填说明
strstring包含变量的Q表达式字符串

返回值

类型说明
string解析后的Q表达式字符串

使用示例

解析Q表达式变量
const qStr = "Q(userId='${this.currentUser.value}')";
const parsedQ = this.parseVariableInQ(qStr);
console.log('解析后的Q表达式:', parsedQ);

sendAiMessage

发送AI消息,触发AI助手处理。

参数详解

参数名类型必填说明
messagestring发送给AI的消息内容
inNewChatnumber是否在新聊天中发送,0=当前对话,1=新对话

使用示例

发送AI消息
async handleAIAssist() {
if (this.aiConfig?.useAi) {
await this.sendAiMessage('请帮我分析这个客户的信息', 0);
}
}

getScheme

获取页面配置方案,支持继承合并。

返回值

类型说明
IScheme页面配置对象

使用示例

获取页面配置
const scheme = this.getScheme();
console.log('当前页面配置:', scheme);
console.log('组件列表:', scheme.componentList);

getUIContext

获取页面UI上下文信息,包含页面和组件的函数、变量信息。

返回值

类型说明
object包含functionList和variables的对象

使用示例

获取UI上下文
const context = this.getUIContext();
console.log('页面函数列表:', context.functionList);
console.log('页面变量列表:', context.variables);

getVariableValue

获取变量值,支持页面变量和组件变量。

参数详解

参数名类型必填说明
varNamestring | BaseDataType变量名或变量实例

返回值

类型说明
any变量值

使用示例

获取变量值
// 获取页面变量值
const userName = this.getVariableValue('userName');

// 获取组件变量值
const formData = this.getVariableValue('Form1.formData');

loadComponents

加载页面组件。

返回值

类型说明
Promise<void>加载完成Promise

loadVariables

加载页面变量。

destroy

销毁页面实例,清理资源。

属性

scheme

页面配置方案对象。

  • 类型: IScheme
  • 说明: 包含layout、componentList、variableList等配置信息

compInsList

组件实例列表。

  • 类型: any[]
  • 说明: 页面所有组件实例的数组

compInsDict

组件实例字典。

  • 类型: Record<string, any>
  • 说明: 以组件名为key的组件实例字典

isReady

页面就绪状态。

  • 类型: boolean
  • 说明: 标识页面是否已完成初始化

extend

继承的页面元素名称。

  • 类型: string | undefined
  • 说明: 当前页面继承的父页面fullName

app

应用实例。

  • 类型: App
  • 说明: 当前运行时应用实例

name

页面名称。

  • 类型: string
  • 说明: 页面元素名称

title

页面标题。

  • 类型: string
  • 说明: 页面显示标题

fullName

页面完整名称。

  • 类型: string
  • 说明: 页面元素的完整路径名

ePath

页面元素路径。

  • 类型: string
  • 说明: 页面元素在文件系统中的路径

pagePerm

页面权限配置。

  • 类型: Record<string, any> | undefined
  • 说明: 页面的权限控制配置

aiConfig

AI配置。

  • 类型: object
  • 说明: 页面的AI助手配置信息

高级特性

页面继承

数据录入页面支持继承机制,可以基于已有页面创建新页面。

配置示例

继承配置
{
"type": "pages.FormPageType",
"title": "高级客户录入页面",
"extend": "pages.BasicCustomerForm",
"dataModel": "models.CustomerModel"
}

使用示例

继承实现
class AdvancedPageCls extends Jit.GridPage {
constructor(info: any = {}) {
super(info);
// 继承的页面会自动合并父页面的配置
}

bindEvent() {
super.bindEvent?.(); // 调用父页面事件绑定

// 添加新的事件绑定
this.Form1.subscribeEvent("beforeSubmit", async (e) => {
// 高级验证逻辑
return this.validateAdvancedRules(e.data);
});
}
}

URL参数绑定

通过matchUarParamsVariableNameList配置,页面变量可以自动从URL参数获取值。

配置示例

URL参数绑定配置
{
"scheme": {
"matchUarParamsVariableNameList": ["userId", "deptId"],
"variableList": [
{
"name": "userId",
"title": "用户ID",
"dataType": "Stext"
},
{
"name": "deptId",
"title": "部门ID",
"dataType": "Stext"
}
]
}
}

使用示例

URL参数使用
// 页面URL: /pages/CustomerForm?userId=123&deptId=dept001
class PageCls extends Jit.GridPage {
bindEvent() {
// 页面初始化时,userId和deptId自动从URL获取值
console.log('用户ID:', this.userId.value); // 输出: 123
console.log('部门ID:', this.deptId.value); // 输出: dept001

// 监听URL变化
this.subscribeEvent('URL_CHANGED', () => {
this.refreshPageVariable(); // 重新从URL获取参数
});
}
}

动态组件加载

支持运行时动态添加和配置组件。

使用示例

动态组件管理
class PageCls extends Jit.GridPage {
async addDynamicComponent() {
// 创建新组件
const newComp = await this.newComponent('components.Button', {
name: 'dynamicBtn',
title: '动态按钮',
config: {
btnType: 'default'
}
});

// 绑定到页面
newComp.bindApp(this.app);
newComp.bindPage(this);

// 添加到组件字典
this.compInsDict['dynamicBtn'] = newComp;
this[newComp.name] = newComp;

// 更新布局
this.scheme.layout.push({
i: 'dynamicBtn',
x: 0,
y: 10,
w: 12,
h: 4
});

this.refresh();
}
}

AI集成

数据录入页面支持AI助手功能,可以为用户提供智能填写建议。

配置示例

AI配置
{
"scheme": {
"aiConfig": {
"useAi": 1,
"aiAssistant": "models.CustomerAIAssistant"
}
}
}

使用示例

AI助手集成
class PageCls extends Jit.GridPage {
async handleAIAssist() {
if (this.aiConfig?.useAi) {
await this.sendAiMessage('请帮我分析这个客户的信息', 0);
}
}

bindEvent() {
// 监听AI消息发送事件
this.subscribeEvent('SEND_AI_MESSAGE', async (e) => {
console.log('AI消息:', e.message);
});

// 绑定AI建议按钮
this.subscribeEvent('AI_SUGGEST', async () => {
const formData = this.Form1.getFormData();
await this.sendAiMessage(`请为以下表单数据提供建议:${JSON.stringify(formData)}`, 0);
});
}
}

样式定制

通过page.style.ts文件可以自定义页面样式。

使用示例

高级样式定制
import type { GlobalToken } from 'antd';
import { css } from '@emotion/react';

export const pageStyle = (token: GlobalToken) => css`
.data-entry-container {
min-height: 100vh;
background: linear-gradient(135deg, ${token.colorBgBase} 0%, ${token.colorBgLayout} 100%);

.form-section {
background: ${token.colorBgContainer};
border-radius: ${token.borderRadiusLG}px;
box-shadow: ${token.boxShadowSecondary};
padding: ${token.paddingLG}px;
margin-bottom: ${token.marginLG}px;

&.highlight {
border: 2px solid ${token.colorPrimary};
}
}

.required-indicator {
color: ${token.colorError};
font-weight: bold;
}
}
`;

export const pageGlobalStyle = (token: GlobalToken) => css`
.ant-form-item-required::before {
color: ${token.colorError} !important;
}

.custom-form-button {
background: ${token.colorPrimary};
border-color: ${token.colorPrimary};

&:hover {
background: ${token.colorPrimaryHover};
border-color: ${token.colorPrimaryHover};
}
}
`;