-
Notifications
You must be signed in to change notification settings - Fork 2
feat: 添加form表单的mcp工具 #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
<template> | ||
<div class="demo-form"> | ||
<div class="title"> | ||
<div>validate 用法:<tiny-button-group :data="validTypeList" v-model="validType"></tiny-button-group></div> | ||
</div> | ||
<tiny-form | ||
ref="ruleFormRef" | ||
:model="createData" | ||
:tiny_mcp_config="{ | ||
server, | ||
business: { | ||
id: 'form-validate', | ||
description: '表单验证示例' | ||
} | ||
}" | ||
:rules="rules" | ||
label-width="100px" | ||
> | ||
<tiny-form-item label="等级" prop="radio"> | ||
<tiny-radio-group v-model="createData.radio" :options="options"></tiny-radio-group> | ||
</tiny-form-item> | ||
<tiny-form-item label="IP字段" prop="ip"> | ||
<tiny-ip-address v-model="createData.ip"></tiny-ip-address> | ||
</tiny-form-item> | ||
<tiny-form-item label="必填" prop="users" :validate-icon="validateIcon"> | ||
<tiny-input v-model="createData.users"></tiny-input> | ||
</tiny-form-item> | ||
<tiny-form-item label="日期" prop="datepicker"> | ||
<tiny-date-picker v-model="createData.datepicker"></tiny-date-picker> | ||
</tiny-form-item> | ||
<tiny-form-item label="URL" prop="url"> | ||
<tiny-input v-model="createData.url"></tiny-input> | ||
</tiny-form-item> | ||
<tiny-form-item label="邮件" prop="email"> | ||
<tiny-input v-model="createData.email"></tiny-input> | ||
</tiny-form-item> | ||
<tiny-form-item label="数字" prop="num1"> | ||
<tiny-numeric v-model="createData.num1"></tiny-numeric> | ||
</tiny-form-item> | ||
<tiny-form-item> | ||
<tiny-button type="primary" @click="validType === 'callback' ? handleSubmit() : handleSubmitPromise()"> | ||
提交 | ||
</tiny-button> | ||
<tiny-button @click="clearFormValid"> 移除校验 </tiny-button> | ||
<tiny-button @click="resetForm"> 重置表单 </tiny-button> | ||
</tiny-form-item> | ||
</tiny-form> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import { ref, reactive } from 'vue' | ||
import { | ||
TinyForm, | ||
TinyFormItem, | ||
TinyInput, | ||
TinyDatePicker, | ||
TinyButton, | ||
TinyModal, | ||
TinyRadioGroup, | ||
TinyNumeric, | ||
TinyIpAddress, | ||
TinyButtonGroup | ||
} from '@opentiny/vue' | ||
import { iconWarning } from '@opentiny/vue-icon' | ||
import { useNextServer } from '@opentiny/next-vue' | ||
|
||
const ruleFormRef = ref() | ||
function handleClick() { | ||
TinyModal.message({ message: 'click', status: 'info' }) | ||
} | ||
const validateIcon = ref(iconWarning()) | ||
const validType = ref('promise') | ||
const validTypeList = ref([ | ||
{ text: 'promise', value: 'promise' }, | ||
{ text: '回调', value: 'callback' } | ||
]) | ||
const options = ref([ | ||
{ label: 'A', text: '很好', events: { click: handleClick } }, | ||
{ label: 'B', text: '一般' } | ||
]) | ||
const createData = reactive({ | ||
radio: '', | ||
users: '', | ||
url: '', | ||
email: '', | ||
datepicker: '', | ||
ip: '', | ||
num1: 0 | ||
}) | ||
const rules = ref({ | ||
radio: [{ required: true, message: '必填', trigger: 'change' }], | ||
users: [ | ||
{ required: true, message: '必填', trigger: 'blur' }, | ||
{ min: 2, max: 11, message: '长度必须不小于 2', trigger: ['change', 'blur'] } | ||
], | ||
datepicker: { type: 'date' }, | ||
url: { type: 'url' }, | ||
email: { type: 'email' }, | ||
ip: [ | ||
{ | ||
validator: (rule, value, cb) => (value === '1.1.1.1' ? cb() : cb(new Error('必填 1.1.1.1'))), | ||
trigger: 'change' | ||
} | ||
], | ||
num1: [{ type: 'number', min: 2, max: 11, message: '必填 2~11 之间的数字', trigger: 'change' }] | ||
}) | ||
|
||
function handleSubmit() { | ||
ruleFormRef.value.validate((valid) => { | ||
if (valid) { | ||
TinyModal.alert('回调用法:提交成功') | ||
} else { | ||
TinyModal.alert('回调用法:提交失败') | ||
} | ||
}) | ||
} | ||
|
||
function handleSubmitPromise() { | ||
ruleFormRef.value | ||
.validate() | ||
.then(() => { | ||
TinyModal.alert('promise 用法:提交成功') | ||
}) | ||
.catch(() => { | ||
TinyModal.alert('promise 用法:提交失败') | ||
}) | ||
} | ||
|
||
function clearFormValid() { | ||
ruleFormRef.value.clearValidate() | ||
} | ||
|
||
function resetForm() { | ||
ruleFormRef.value.resetFields() | ||
} | ||
|
||
const { server } = useNextServer({ | ||
serverInfo: { name: 'ecs-form', version: '1.0.0' } | ||
}) | ||
</script> | ||
|
||
<style scoped> | ||
.demo-form { | ||
width: 450px; | ||
} | ||
.title { | ||
margin-bottom: 20px; | ||
font-size: 14px; | ||
} | ||
</style> |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,67 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { z } from 'zod' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { defineComponentTool } from '../utils/defineComponentTool' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import resourcesZh from './resouces.zh.md?raw' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import resourcesEn from './resouces.en.md?raw' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { t } from '../utils/locale' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const resources = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zh: resourcesZh, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
en: resourcesEn | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const getFormConfig = () => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
defineComponentTool({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
name: 'form_component_tools', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
description: t('ai.form.description'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tools: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
resetFields: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.boolean().optional().describe(t('ai.form.resetFields')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.resetFields() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
clearValidate: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.string().optional().describe(t('ai.form.clearValidate')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance, value) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (typeof value === 'string' && value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const arr = value.split(',') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if(arr.length > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.clearValidate(arr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.clearValidate(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
clearValidateAll: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.boolean().optional().describe(t('ai.form.clearValidateAll')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.clearValidate() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
validate: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.boolean().optional().describe(t('ai.form.validate')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: async (instance) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const result = await instance.validate() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: result ? 'success' : 'fail' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
validateField: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
paramsSchema: z.string().optional().describe(t('ai.form.validateField')), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cb: (instance, value) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (typeof value === 'string' && value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const arr = value.split(',') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if(arr.length > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.validateField(arr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance.validateField(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { type: 'text', text: 'success' } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+52
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix identical logic error in validateField. This tool has the same logic error as Apply this diff to fix the logic: - cb: (instance, value) => {
- if (typeof value === 'string' && value) {
- const arr = value.split(',')
- if(arr.length > 0) {
- instance.validateField(arr)
- }else {
- instance.validateField(value)
- }
- }
- return { type: 'text', text: 'success' }
- }
+ cb: (instance, value) => {
+ if (typeof value === 'string' && value) {
+ const arr = value.split(',').map(s => s.trim()).filter(s => s)
+ if (arr.length > 1) {
+ instance.validateField(arr)
+ } else if (arr.length === 1) {
+ instance.validateField(arr[0])
+ }
+ }
+ return { type: 'text', text: 'success' }
+ } 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Form Component | ||
|
||
Composed of buttons, input boxes, selectors, radio buttons, multiple-choice boxes, and other controls, used for collecting, verifying, and submitting data. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Form 表单 | ||
|
||
由按钮、输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix logic error in field name handling.
The condition
if(arr.length > 0)
will always be true aftersplit(',')
because split always returns at least one element. This makes the else block unreachable and the logic incorrect.Apply this diff to fix the logic:
📝 Committable suggestion
🤖 Prompt for AI Agents