```json
{
"summary": "创建高考志愿报名表单,包含个人信息、学业成绩和志愿选择三大板块,采用响应式网格布局确保移动端友好体验。关键字段包括身份证号、成绩录入和院校选择,并设置必填验证规则。",
"widget": {
"type": "formly",
"fields": [
{
"type": "tabs",
"fieldGroup": [
{
"props": {
"label": "个人信息"
},
"fieldGroup": [
{
"className": "grid grid-cols-1 md:grid-cols-2 gap-4",
"fieldGroup": [
{
"key": "name",
"type": "input",
"props": {
"label": "考生姓名",
"required": true
},
"validation": {
"messages": {
"required": "姓名不能为空"
}
}
},
{
"key": "idCard",
"type": "input",
"props": {
"label": "身份证号",
"required": true,
"pattern": "\\d{17}[\\dXx]"
},
"validation": {
"messages": {
"required": "身份证号不能为空",
"pattern": "请输入18位有效身份证号"
}
}
},
{
"key": "gender",
"type": "radio",
"className": "col-span-2",
"defaultValue": "male",
"props": {
"label": "性别",
"options": [
{
"value": "male",
"label": "男"
},
{
"value": "female",
"label": "女"
}
]
}
}
]
}
]
},
{
"props": {
"label": "学业成绩"
},
"fieldGroup": [
{
"className": "grid grid-cols-1 md:grid-cols-3 gap-4",
"fieldGroup": [
{
"key": "chinese",
"type": "input",
"props": {
"label": "语文成绩",
"type": "number",
"min": 0,
"max": 150
}
},
{
"key": "math",
"type": "input",
"props": {
"label": "数学成绩",
"type": "number",
"min": 0,
"max": 150
}
},
{
"key": "english",
"type": "input",
"props": {
"label": "英语成绩",
"type": "number",
"min": 0,
"max": 150
}
},
{
"key": "science",
"type": "input",
"className": "col-span-3",
"props": {
"label": "理科综合",
"type": "number",
"min": 0,
"max": 300
}
}
]
}
]
},
{
"props": {
"label": "志愿选择"
},
"fieldGroup": [
{
"key": "batch",
"type": "select",
"props": {
"label": "录取批次",
"required": true,
"options": [
{
"value": "early",
"label": "提前批"
},
{
"value": "first",
"label": "第一批次"
},
{
"value": "second",
"label": "第二批次"
}
]
}
},
{
"type": "repeat",
"key": "choices",
"className": "grid grid-cols-1 gap-6",
"props": {
"label": "院校志愿",
"addText": "添加志愿"
},
"fieldArray": {
"fieldGroup": [
{
"className": "grid grid-cols-1 md:grid-cols-2 gap-4",
"fieldGroup": [
{
"key": "school",
"type": "input",
"props": {
"label": "院校名称",
"required": true
}
},
{
"key": "major",
"type": "input",
"props": {
"label": "专业名称",
"required": true
}
}
]
}
]
}
},
{
"key": "adjustable",
"type": "toggle",
"props": {
"label": "是否服从调剂"
}
}
]
}
]
},
{
"key": "agreement",
"type": "checkbox",
"className": "mt-6",
"props": {
"label": "我已阅读并同意报名协议",
"required": true
},
"validation": {
"messages": {
"required": "必须同意协议才能提交"
}
}
}
]
},
"next": ["添加成绩计算","设置院校联动","增加科目选择","配置地区限制","添加说明文案"]
}
```
推理
我们正在创建一个高考志愿报名的表单。根据需求,我们需要收集学生的基本信息以及志愿信息。
考虑到字段较多,我们将采用分组和网格布局来组织表单。
字段分析:
1. 学生基本信息:姓名、性别、出生日期、身份证号、民族、政治面貌、联系电话、电子邮箱、家庭住址。
2. 学业信息:考生号、毕业学校、高考成绩(各科成绩及总分)、文理科。
3. 志愿信息:志愿批次(如提前批、本科一批等)、志愿院校、志愿专业、是否服从调剂。
4. 其他:上传照片(头像)、个人陈述(自我介绍)、同意条款(复选框)。
布局思路:
我们将使用Tabs组件将表单分为三个部分:基本信息、学业信息、志愿信息。每个Tab内使用网格布局(grid)来排列字段。
注意事项:
1. 使用Tailwind的grid布局,采用grid-cols-1(移动端)和md:grid-cols-2(桌面端)两列布局。
2. 重要字段(如姓名、身份证号、考生号)需要验证。
3. 使用ngx-formly的内置验证规则,如required、pattern等,并配置中文错误信息。
4. 日期选择使用datepicker类型。
5. 性别、民族、政治面貌、文理科、是否服从调剂等使用单选(radio)或选择框(select)。
6. 个人陈述使用textarea,并可以设置为rich-text以支持富文本(如果需要)。
7. 上传照片使用file类型(但注意ngx-formly默认没有file类型,因此我们可能需要使用input类型并设置type为file,或者使用自定义类型。但根据约束,我们只能使用给定的类型,而给定的类型中没有file,所以这里我们暂时用input并设置props为type: 'file',但注意:ngx-formly的input类型默认支持type属性,所以可以这样用)。
8. 同意条款使用checkbox。
由于字段较多,我们按照Tabs分组,每个Tab下再使用fieldGroup进行网格布局。
验证规则:
对于必填字段,添加required验证,并设置message。
对于身份证号、手机号、邮箱,使用pattern验证。
考虑到表单较大,我们将使用tabs类型来组织。
步骤:
1. 创建tabs,每个tab代表一个部分。
2. 每个tab内,使用fieldGroup,并设置className为grid grid-cols-1 md:grid-cols-2 gap-4,这样内部字段将自动两列布局(在桌面端)。
3. 对于某些可能需要占满整行的字段(如地址、个人陈述),我们可以设置colSpan为2(通过className: 'col-span-2')。
具体字段配置:
注意:由于身份证号、手机号等需要验证格式,我们将使用pattern,并给出相应的正则表达式。
身份证号正则:/^\d{17}[\dXx]$/ (18位,最后一位可以是X)
手机号正则:/^1[3-9]\d{9}$/
邮箱正则:使用ngx-formly内置的email验证(但根据约束,我们只能使用内置的validations,所以我们可以使用内置的email验证器,但是注意约束条件5:禁用validators?这里约束条件第6点说禁用validators,但第5点又说使用validation.messages配置提示。所以这里我们使用validation属性,并设置messages。但是注意,ngx-formly v6中,验证规则是通过validators配置的,而约束条件说禁用validators,这可能是矛盾的。重新阅读约束条件:第5点说“严格遵循 ngx-formly v6 最新 JSON 规范,禁止使用函数,只能使用内置的 validations”,第6点说“禁用 validators”。这里可能是指不能使用自定义validators函数,只能使用内置的验证器名称(如'required'、'email'等)。所以我们可以这样写:
validators: {
validation: ['email'] // 对于邮箱字段
}
但是,在JSON规范中,验证器是以数组形式写在validators.validation里的,而消息写在validation.messages中。
然而,约束条件第6点说“禁用validators”,这可能是笔误?因为如果不使用validators,就无法设置验证规则。我们再看约束条件第5点:只能使用内置的validations。所以这里我们理解为:只能使用内置的验证器(通过validators.validation数组),不能使用自定义验证器函数。
因此,我们将使用内置验证器:required, email, pattern, min, max等。
对于邮箱,我们可以使用内置的email验证器,对于手机和身份证,我们使用pattern验证器。
另外,注意约束条件要求使用validation.messages配置提示,所以我们需要为每个验证器配置对应的消息。
具体配置示例:
{
key: 'email',
type: 'input',
props: {
label: '电子邮箱',
type: 'email',
required: true,
},
validators: {
validation: ['email']
},
validation: {
messages: {
email: '请输入有效的邮箱地址'
}
}
}
但是,对于pattern验证器,我们需要提供pattern选项,可以通过props.pattern设置,也可以通过validation.pattern设置。这里我们使用props.pattern。
接下来,我们开始构建表单的JSON结构。
由于表单字段很多,我们将分三个tab:
第一个Tab:基本信息
第二个Tab:学业信息
第三个Tab:志愿信息
每个Tab的fieldGroup中,我们将字段放入网格中。
另外,我们还需要一个提交前的同意条款,放在最后(不放在tab内,而是作为独立字段放在tabs之后)。但是考虑到tabs是最后一个字段组,我们可以将同意条款放在tabs外面。因此,整个表单结构为:
- 一个tabs字段(包含三个tab)
- 一个checkbox字段(同意条款)
但是,由于tabs已经是一个字段组,我们可以在tabs的同级添加字段。所以整个fields数组结构为:
[
{ type: 'tabs', ... },
{
type: 'checkbox',
key: 'agreement',
props: {
label: '我已阅读并同意相关条款',
required: true
}
}
]
但是,这样同意条款会出现在tabs下面。
现在,我们开始编写每个tab的字段。
注意:每个tab的props.label要设置,每个字段的key、type、props.label等。
由于字段较多,我们只列出关键字段。
具体字段列表:
1. 基本信息Tab:
- 姓名(input,必填)
- 性别(radio,选项:男、女)
- 出生日期(datepicker)
- 身份证号(input,必填,pattern验证)
- 民族(select,选项:汉族、其他民族...,这里我们只列几个示例,实际应该是一个数据源,但这里我们固定写几个)
- 政治面貌(select,选项:群众、共青团员、中共党员等)
- 联系电话(input,必填,pattern验证手机号)
- 电子邮箱(input,type:email,验证邮箱)
- 家庭住址(textarea,可以占两列)
2. 学业信息Tab:
- 考生号(input,必填)
- 毕业学校(input,必填)
- 文理科(radio:文科、理科)
- 高考成绩:这里我们可以拆分成多个字段,比如语文、数学、外语、综合、总分。注意总分可以由其他计算得出,但这里我们让用户输入,也可以后面用表达式计算(但表达式在JSON中不能写函数,所以这里我们不做计算)。
考虑到成绩都是数字,使用input类型,type为number,并设置min和max(比如0-750)。
我们将这些成绩放在一个组内,使用fieldGroup,并设置网格布局。
3. 志愿信息Tab:
- 志愿批次(select,选项:提前批、本科一批、本科二批、专科批)
- 第一志愿院校(input)
- 第一志愿专业(input)
- 第二志愿院校(input)
- 第二志愿专业(input)
- 第三志愿院校(input)
- 第三志愿专业(input)
- 是否服从调剂(radio:是、否)
另外,每个Tab内的字段布局使用网格,所以我们在每个Tab的fieldGroup上设置className: 'grid grid-cols-1 md:grid-cols-2 gap-4'。
对于占两列的字段,我们设置className: 'col-span-2'。
由于字段较多,我们只展示关键配置。
开始编写JSON:
注意:由于是JSON,所有键名必须用双引号,字符串值用双引号。
由于高考志愿报名表单可能包含多个志愿,我们可以使用repeat类型来重复志愿,但这里为了简化,我们固定三个志愿。所以使用三个字段组。
但是,根据需求,我们只使用给定的类型。repeat类型是允许的,但这里我们先用固定字段。
另外,头像(照片)上传我们放在基本信息Tab,使用input类型,type为file。但是注意,ngx-formly的input类型支持type属性,所以可以这样写:
{
key: 'avatar',
type: 'input',
props: {
label: '上传照片',
type: 'file',
accept: 'image/*'
},
className: 'col-span-2' // 占两列
}
但是,文件上传的处理在后台,表单只负责选择文件。
最后,我们给出下一步建议。
由于表单较大,我们只生成关键部分,一些细节可能需要调整。
开始生成JSON:
考虑到字段较多,我们将采用分组和网格布局来组织表单。
字段分析:
1. 学生基本信息:姓名、性别、出生日期、身份证号、民族、政治面貌、联系电话、电子邮箱、家庭住址。
2. 学业信息:考生号、毕业学校、高考成绩(各科成绩及总分)、文理科。
3. 志愿信息:志愿批次(如提前批、本科一批等)、志愿院校、志愿专业、是否服从调剂。
4. 其他:上传照片(头像)、个人陈述(自我介绍)、同意条款(复选框)。
布局思路:
我们将使用Tabs组件将表单分为三个部分:基本信息、学业信息、志愿信息。每个Tab内使用网格布局(grid)来排列字段。
注意事项:
1. 使用Tailwind的grid布局,采用grid-cols-1(移动端)和md:grid-cols-2(桌面端)两列布局。
2. 重要字段(如姓名、身份证号、考生号)需要验证。
3. 使用ngx-formly的内置验证规则,如required、pattern等,并配置中文错误信息。
4. 日期选择使用datepicker类型。
5. 性别、民族、政治面貌、文理科、是否服从调剂等使用单选(radio)或选择框(select)。
6. 个人陈述使用textarea,并可以设置为rich-text以支持富文本(如果需要)。
7. 上传照片使用file类型(但注意ngx-formly默认没有file类型,因此我们可能需要使用input类型并设置type为file,或者使用自定义类型。但根据约束,我们只能使用给定的类型,而给定的类型中没有file,所以这里我们暂时用input并设置props为type: 'file',但注意:ngx-formly的input类型默认支持type属性,所以可以这样用)。
8. 同意条款使用checkbox。
由于字段较多,我们按照Tabs分组,每个Tab下再使用fieldGroup进行网格布局。
验证规则:
对于必填字段,添加required验证,并设置message。
对于身份证号、手机号、邮箱,使用pattern验证。
考虑到表单较大,我们将使用tabs类型来组织。
步骤:
1. 创建tabs,每个tab代表一个部分。
2. 每个tab内,使用fieldGroup,并设置className为grid grid-cols-1 md:grid-cols-2 gap-4,这样内部字段将自动两列布局(在桌面端)。
3. 对于某些可能需要占满整行的字段(如地址、个人陈述),我们可以设置colSpan为2(通过className: 'col-span-2')。
具体字段配置:
注意:由于身份证号、手机号等需要验证格式,我们将使用pattern,并给出相应的正则表达式。
身份证号正则:/^\d{17}[\dXx]$/ (18位,最后一位可以是X)
手机号正则:/^1[3-9]\d{9}$/
邮箱正则:使用ngx-formly内置的email验证(但根据约束,我们只能使用内置的validations,所以我们可以使用内置的email验证器,但是注意约束条件5:禁用validators?这里约束条件第6点说禁用validators,但第5点又说使用validation.messages配置提示。所以这里我们使用validation属性,并设置messages。但是注意,ngx-formly v6中,验证规则是通过validators配置的,而约束条件说禁用validators,这可能是矛盾的。重新阅读约束条件:第5点说“严格遵循 ngx-formly v6 最新 JSON 规范,禁止使用函数,只能使用内置的 validations”,第6点说“禁用 validators”。这里可能是指不能使用自定义validators函数,只能使用内置的验证器名称(如'required'、'email'等)。所以我们可以这样写:
validators: {
validation: ['email'] // 对于邮箱字段
}
但是,在JSON规范中,验证器是以数组形式写在validators.validation里的,而消息写在validation.messages中。
然而,约束条件第6点说“禁用validators”,这可能是笔误?因为如果不使用validators,就无法设置验证规则。我们再看约束条件第5点:只能使用内置的validations。所以这里我们理解为:只能使用内置的验证器(通过validators.validation数组),不能使用自定义验证器函数。
因此,我们将使用内置验证器:required, email, pattern, min, max等。
对于邮箱,我们可以使用内置的email验证器,对于手机和身份证,我们使用pattern验证器。
另外,注意约束条件要求使用validation.messages配置提示,所以我们需要为每个验证器配置对应的消息。
具体配置示例:
{
key: 'email',
type: 'input',
props: {
label: '电子邮箱',
type: 'email',
required: true,
},
validators: {
validation: ['email']
},
validation: {
messages: {
email: '请输入有效的邮箱地址'
}
}
}
但是,对于pattern验证器,我们需要提供pattern选项,可以通过props.pattern设置,也可以通过validation.pattern设置。这里我们使用props.pattern。
接下来,我们开始构建表单的JSON结构。
由于表单字段很多,我们将分三个tab:
第一个Tab:基本信息
第二个Tab:学业信息
第三个Tab:志愿信息
每个Tab的fieldGroup中,我们将字段放入网格中。
另外,我们还需要一个提交前的同意条款,放在最后(不放在tab内,而是作为独立字段放在tabs之后)。但是考虑到tabs是最后一个字段组,我们可以将同意条款放在tabs外面。因此,整个表单结构为:
- 一个tabs字段(包含三个tab)
- 一个checkbox字段(同意条款)
但是,由于tabs已经是一个字段组,我们可以在tabs的同级添加字段。所以整个fields数组结构为:
[
{ type: 'tabs', ... },
{
type: 'checkbox',
key: 'agreement',
props: {
label: '我已阅读并同意相关条款',
required: true
}
}
]
但是,这样同意条款会出现在tabs下面。
现在,我们开始编写每个tab的字段。
注意:每个tab的props.label要设置,每个字段的key、type、props.label等。
由于字段较多,我们只列出关键字段。
具体字段列表:
1. 基本信息Tab:
- 姓名(input,必填)
- 性别(radio,选项:男、女)
- 出生日期(datepicker)
- 身份证号(input,必填,pattern验证)
- 民族(select,选项:汉族、其他民族...,这里我们只列几个示例,实际应该是一个数据源,但这里我们固定写几个)
- 政治面貌(select,选项:群众、共青团员、中共党员等)
- 联系电话(input,必填,pattern验证手机号)
- 电子邮箱(input,type:email,验证邮箱)
- 家庭住址(textarea,可以占两列)
2. 学业信息Tab:
- 考生号(input,必填)
- 毕业学校(input,必填)
- 文理科(radio:文科、理科)
- 高考成绩:这里我们可以拆分成多个字段,比如语文、数学、外语、综合、总分。注意总分可以由其他计算得出,但这里我们让用户输入,也可以后面用表达式计算(但表达式在JSON中不能写函数,所以这里我们不做计算)。
考虑到成绩都是数字,使用input类型,type为number,并设置min和max(比如0-750)。
我们将这些成绩放在一个组内,使用fieldGroup,并设置网格布局。
3. 志愿信息Tab:
- 志愿批次(select,选项:提前批、本科一批、本科二批、专科批)
- 第一志愿院校(input)
- 第一志愿专业(input)
- 第二志愿院校(input)
- 第二志愿专业(input)
- 第三志愿院校(input)
- 第三志愿专业(input)
- 是否服从调剂(radio:是、否)
另外,每个Tab内的字段布局使用网格,所以我们在每个Tab的fieldGroup上设置className: 'grid grid-cols-1 md:grid-cols-2 gap-4'。
对于占两列的字段,我们设置className: 'col-span-2'。
由于字段较多,我们只展示关键配置。
开始编写JSON:
注意:由于是JSON,所有键名必须用双引号,字符串值用双引号。
由于高考志愿报名表单可能包含多个志愿,我们可以使用repeat类型来重复志愿,但这里为了简化,我们固定三个志愿。所以使用三个字段组。
但是,根据需求,我们只使用给定的类型。repeat类型是允许的,但这里我们先用固定字段。
另外,头像(照片)上传我们放在基本信息Tab,使用input类型,type为file。但是注意,ngx-formly的input类型支持type属性,所以可以这样写:
{
key: 'avatar',
type: 'input',
props: {
label: '上传照片',
type: 'file',
accept: 'image/*'
},
className: 'col-span-2' // 占两列
}
但是,文件上传的处理在后台,表单只负责选择文件。
最后,我们给出下一步建议。
由于表单较大,我们只生成关键部分,一些细节可能需要调整。
开始生成JSON:
角色
assistant
content
total_tokens
3931