From fdc5b02c30e61c4a2c103ea364d9ecfac4b89fcc Mon Sep 17 00:00:00 2001 From: Squall2017 <252766926@qq.com> Date: Wed, 25 Sep 2024 18:11:02 +0800 Subject: [PATCH] feat(form): add merge form functionality (#4495) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: captcha example * fix: fix lint errors * chore: event handling and methods * chore: add accessibility features ARIA labels and roles * refactor: refactor code structure and improve captcha demo page * feat: add captcha internationalization * chore: 适配时间戳国际化展示 * fix: 1. 添加点击位置边界校验,防止点击外部导致x,y误差。2. 演示页面宽度过长添加滚动条。3. 添加hooks * feat: sync test * feat: 添加合并表单功能 * fix: 修复上一步不展示问题 --------- Co-authored-by: vince --- packages/@core/ui-kit/form-ui/src/form-api.ts | 41 +++++++ .../captcha/hooks/useCaptchaPoints.ts | 1 + playground/src/locales/langs/en-US.json | 3 +- playground/src/locales/langs/zh-CN.json | 3 +- .../src/router/routes/modules/examples.ts | 8 ++ playground/src/views/examples/form/merge.vue | 116 ++++++++++++++++++ 6 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 playground/src/views/examples/form/merge.vue diff --git a/packages/@core/ui-kit/form-ui/src/form-api.ts b/packages/@core/ui-kit/form-ui/src/form-api.ts index 77f3204e..3b78e039 100644 --- a/packages/@core/ui-kit/form-ui/src/form-api.ts +++ b/packages/@core/ui-kit/form-ui/src/form-api.ts @@ -123,6 +123,47 @@ export class FormApi { return form.values; } + merge(formApi: FormApi) { + const chain = [this, formApi]; + const proxy = new Proxy(formApi, { + get(target: any, prop: any) { + if (prop === 'merge') { + return (nextFormApi: FormApi) => { + chain.push(nextFormApi); + return proxy; + }; + } + if (prop === 'submitAllForm') { + return async (needMerge: boolean = true) => { + try { + const results = await Promise.all( + chain.map(async (api) => { + const form = await api.getForm(); + const validateResult = await api.validate(); + if (!validateResult.valid) { + return; + } + const rawValues = toRaw(form.values || {}); + return rawValues; + }), + ); + if (needMerge) { + const mergedResults = Object.assign({}, ...results); + return mergedResults; + } + return results; + } catch (error) { + console.error('Validation error:', error); + } + }; + } + return target[prop]; + }, + }); + + return proxy; + } + mount(formActions: FormActions) { if (!this.isMounted) { Object.assign(this.form, formActions); diff --git a/packages/effects/common-ui/src/components/captcha/hooks/useCaptchaPoints.ts b/packages/effects/common-ui/src/components/captcha/hooks/useCaptchaPoints.ts index 6032d41a..511fb3b7 100644 --- a/packages/effects/common-ui/src/components/captcha/hooks/useCaptchaPoints.ts +++ b/packages/effects/common-ui/src/components/captcha/hooks/useCaptchaPoints.ts @@ -7,6 +7,7 @@ export function useCaptchaPoints() { function addPoint(point: CaptchaPoint) { points.push(point); } + function clearPoints() { points.splice(0, points.length); } diff --git a/playground/src/locales/langs/en-US.json b/playground/src/locales/langs/en-US.json index 9e926ca8..92ce74fc 100644 --- a/playground/src/locales/langs/en-US.json +++ b/playground/src/locales/langs/en-US.json @@ -79,7 +79,8 @@ "rules": "Form Rules", "dynamic": "Dynamic Form", "custom": "Custom Component", - "api": "Api" + "api": "Api", + "merge": "Merge Form" }, "captcha": { "title": "Captcha", diff --git a/playground/src/locales/langs/zh-CN.json b/playground/src/locales/langs/zh-CN.json index 08a2c38f..ca28d818 100644 --- a/playground/src/locales/langs/zh-CN.json +++ b/playground/src/locales/langs/zh-CN.json @@ -79,7 +79,8 @@ "rules": "表单校验", "dynamic": "动态表单", "custom": "自定义组件", - "api": "Api" + "api": "Api", + "merge": "合并表单" }, "captcha": { "title": "验证码", diff --git a/playground/src/router/routes/modules/examples.ts b/playground/src/router/routes/modules/examples.ts index 954c1154..697d4789 100644 --- a/playground/src/router/routes/modules/examples.ts +++ b/playground/src/router/routes/modules/examples.ts @@ -99,6 +99,14 @@ const routes: RouteRecordRaw[] = [ title: $t('page.examples.form.api'), }, }, + { + name: 'FormMergeExample', + path: '/examples/form/merge', + component: () => import('#/views/examples/form/merge.vue'), + meta: { + title: $t('page.examples.form.merge'), + }, + }, ], }, { diff --git a/playground/src/views/examples/form/merge.vue b/playground/src/views/examples/form/merge.vue new file mode 100644 index 00000000..88292697 --- /dev/null +++ b/playground/src/views/examples/form/merge.vue @@ -0,0 +1,116 @@ + + +