{"id":20144189,"url":"https://github.com/quansitech/qs-cusform","last_synced_at":"2025-04-09T18:54:06.071Z","repository":{"id":38425097,"uuid":"265159088","full_name":"quansitech/qs-cusform","owner":"quansitech","description":"零代码自定义表单组件扩展","archived":false,"fork":false,"pushed_at":"2024-01-30T06:07:29.000Z","size":5866,"stargazers_count":6,"open_issues_count":11,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-23T20:51:18.402Z","etag":null,"topics":["designable","form","formily","lowcode","qscmf"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quansitech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-05-19T06:00:31.000Z","updated_at":"2024-01-18T15:00:09.000Z","dependencies_parsed_at":"2024-01-30T07:35:54.078Z","dependency_job_id":null,"html_url":"https://github.com/quansitech/qs-cusform","commit_stats":{"total_commits":61,"total_committers":5,"mean_commits":12.2,"dds":"0.47540983606557374","last_synced_commit":"1cf3cf33519b31919a41c4e94b912978eaab3239"},"previous_names":[],"tags_count":58,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quansitech%2Fqs-cusform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quansitech%2Fqs-cusform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quansitech%2Fqs-cusform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quansitech%2Fqs-cusform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quansitech","download_url":"https://codeload.github.com/quansitech/qs-cusform/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248093818,"owners_count":21046756,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["designable","form","formily","lowcode","qscmf"],"created_at":"2024-11-13T22:09:06.684Z","updated_at":"2025-04-09T18:54:06.032Z","avatar_url":"https://github.com/quansitech.png","language":"JavaScript","readme":"# qs-cusform 自定义表单\n\n提示: v2版与v1无法平滑升级，v2版会废弃v1的数据表（不会删除），请确认数据无需继承的场景下再执行升级操作    [v1版本文档](https://github.com/quansitech/qs-cusform/blob/master/README_v1.md)\n\nv2版本是基于[alibaba/formily](https://github.com/alibaba/formily)和[alibaba/designable](https://github.com/alibaba/designable)开发的零代码自定义表单扩展，大大简化原来designable对于用户不优化的操作界面，仅留下必须的部分组件和控制选项，降低用户的使用和学习门槛，并与qscmf无缝整合。\n\n## 效果图\n\n![](https://raw.githubusercontent.com/quansitech/files/master/qscusform1.png)\n\n## \n\n## 用法\n\n### 1.安装及执行迁移\n\n```shell\ncomposer require quansitech/cus-form\nphp artisan migrate\n```\n\n### 2. 配置\n\n在根目录的PackageConfig.php文件添加配置项，配置项说明看注释\n\n```php\n'cusform' =\u003e [\n    'form_description'=\u003etrue, //默认false ， true表示开启表单描述字段\n    'ue_extra_attr'=\u003e'data-url=\"/Public/libs/ueditor/php/controller.php?oss=1\u0026type=image\"' // 自定义ueditor组件的extra_attr参数\n    'force_delete' =\u003e true, //默认为false,表示存在用户提交的表单内容则禁止删除，true表示不做删除检测\n    'jsOptions' =\u003e [\n        'urlPrefix' =\u003e '', //一般不用填写，如采用了非规则的网站前缀（如 https://qscmf.test/project1），需要显式添加\n        'area' =\u003e [\n            'url' =\u003e '', //地区组件获取地区数据的api，一般不用填写，如需要自定义获取api，可通过填写覆盖默认的api\n        ],\n        'upload' =\u003e [\n            'uploadTo' =\u003e 'oss',//设置图片存储方式，可选项：oss、tos、cos、server\n            'hashCheck' =\u003e false, //是否开启查重 默认true\n            'wasmUrl' =\u003e 'http://qsproject.test/Public/libs/oss/wasm/md5.wasm', //指定计算md5的wasm文件地址，默认当前域名/Public/cusform/*****.wasm\n            'action' =\u003e '' //上传地址，默认请求组件提供的上传接口，如需自定义可修改\n        ]\n    ]\n]\n```\n\n### 3.表单管理页\n\n地址 http://[host]:[port]/admin/Form/index\n\n## \n\n## API说明\n\n+ CusForm\n  \n  | 方法             | 说明                  | 参数                                                               | 返回值类型                                                                              |\n  | -------------- | ------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------- |\n  | getInstance    | 生成CusForm实例对象       |                                                                  |                                                                                    |\n  | formSchema     | 自定义表单的jsonSchema字符串 | int form_id 表单主键                                                 | string                                                                             |\n  | getApplySchema | 获取用户提交的表单数据         | int apply_id 用户数据的主键id\u003cbr /\u003estring mode edit(可编辑)\\|readonly (只读) | stdClass json对象类型                                                                  |\n  | editApply      | 编辑用户提交的表单数据         | int apply_id 用户数据的主键id\u003cbr /\u003estdClass post_object 提交字段的json对象     | [flag, error] \u003cbr /\u003efalg为true或者false\u003cbr /\u003efalse时error保存出错信息                        |\n  | submitApply    | 新增用户提交的表单数据         | int form_id 自定义表单主键id\u003cbr /\u003estdClass post_object 提交的字段json对象      | [res, error] \u003cbr /\u003eres 如果是false error保存出错信息\u003cbr /\u003e否则 res 返回 apply_id                |\n  | getApplyRecord | 获取用户填写记录            | int apply_id 用户数据主键id                                            | array 内容索引数组\u003cbr /\u003e`[ 0 =\u003e { component_type: 'input', title：'标题', value: '1234'} ]` |\n\n+ Builder\n  \n  | 方法         | 说明                     | 参数                        | 返回值类型    |\n  | ---------- | ---------------------- | ------------------------- | -------- |\n  | __contruct | 构造函数                   | Object json_schema的json对象 | 无        |\n  | build      | 生成新的json_schema的json对象 |                           | stdClass |\n  | addBefore  | 在自定义表单前插入字段组件          | BaseComponent 组件对象        | this     |\n  | addAfter   | 在自定义表单后插入字段组件          | BaseComponent 组件对象        | this     |\n\n+ BaseComponent \n  \n  | 方法          | 说明              | 参数                                                                                       | 返回值类型                                                                    |\n  | ----------- | --------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |\n  | __construct | 构造函数            | string sign  字段标识                                                                        |                                                                          |\n  | value       | 设置组件的值          | string \\| stdClass \\| array \\| number value                                              | this                                                                     |\n  | type        | 组件值类型           | string type                                                                              | this                                                                     |\n  | title       | 标题              | string title                                                                             | this                                                                     |\n  | required    | 必填              | bool required 默认值true                                                                    | this                                                                     |\n  | description | 说明              | string description                                                                       | this                                                                     |\n  | default     | 默认值             | string \\| stdClass \\| array \\| number default                                            | this                                                                     |\n  | validator   | 验证器             | string validator  \u003cbr /\u003e可选项： email、enum、idcard、integer、number\u003cbr /\u003e、phone、required、url   | this                                                                     |\n  | enum        | 数据源             | array enum \u003cbr /\u003e[[ 'label' =\u003e '1分', 'value' =\u003e 1],[ 'label' =\u003e '2分', 'value' =\u003e 2]]this | this                                                                     |\n  | validate    | 验证              |                                                                                          | array\u003cbr /\u003e[true, ''] 验证通过\u003cbr /\u003e[false, '错误原因'] 验证失败                     |\n  | readonly    | 设置成只读           |                                                                                          | BaseComponent 当前对象                                                       |\n  | build       | 创建组件json_schema |                                                                                          | array\u003cbr /\u003e[sign, component]\u003cbr /\u003esign: 组件标识\u003cbr /\u003ecomponent: json_schema |\n\n+ Input （BaseComponent实现类）\n  \n  | 方法          | 说明    | 参数                                      | 返回值类型 |\n  | ----------- | ----- | --------------------------------------- | ----- |\n  | __construct | 构造函数  | string sign 组件标识\u003cbr /\u003estring title 组件标题 |       |\n  | placeholder | 占位符   | string placeholder 占位符                  | this  |\n  | allowClear  | 是否可清空 | bool allowclear \u003cbr /\u003etrue 启用可清空按钮      | this  |\n  | maxLength   | 最大长度  | int maxLength                           | this  |\n\n+ Radio （BaseComponent实现类）\n  \n  | 方法          | 说明   | 参数                                      | 返回值类型 |\n  | ----------- | ---- | --------------------------------------- | ----- |\n  | __construct | 构造函数 | string sign 组件标识\u003cbr /\u003estring title 组件标题 |       |\n\n+ Textarea （BaseComponent实现类）\n  \n  | 方法          | 说明    | 参数                                      | 返回值类型 |\n  | ----------- | ----- | --------------------------------------- | ----- |\n  | __construct | 构造函数  | string sign 组件标识\u003cbr /\u003estring title 组件标题 |       |\n  | placeholder | 占位符   | string placeholder 占位符this              | this  |\n  | allowClear  | 是否可清空 | bool allowclear \u003cbr /\u003etrue 启用可清空按钮      | this  |\n  | showCount   | 展示字数  | bool showCount                          | this  |\n\n+ Text （BaseComponent实现类）\n  \n  | 方法          | 说明   | 参数                     | 返回值类型 |\n  | ----------- | ---- | ---------------------- | ----- |\n  | __construct | 构造函数 | string title 组件标题 默认为空 |       |\n  | content     | 设置内容 | string content         | this  |\n\n+ DatePicker （BaseComponent实现类）\n  \n  | 方法          | 说明      | 参数                                                        | 返回值类型 |\n  | ----------- | ------- | --------------------------------------------------------- | ----- |\n  | __construct | 构造函数    | string sign 组件标识\u003cbr /\u003estring title 组件标题                   |       |\n  | placeholder | 占位符     | string placeholder 占位符this                                | this  |\n  | allowClear  | 是否可清空   | bool allowclear \u003cbr /\u003etrue 启用可清空按钮                        | this  |\n  | picker      | 设置展示类型  | string mode\u003cbr /\u003eyear \\| time \\| date \\| month \\| quarter | this  |\n  | showTime    | 是否可录入时间 | bool show                                                 | this  |\n\n+ formilyBuilder\n  \n  | 方法           | 说明                                       | 参数                                               | 返回值类型 |\n  | ------------ | ---------------------------------------- | ------------------------------------------------ | ----- |\n  | __construct  | 构造函数                                     | int apply_id 用户数据的主键id\u003cbr /\u003estdClass json_schema |       |\n  | setMode      | 只读\\|编辑                                   | string mode\u003cbr /\u003ereadonly \\| edit                | this  |\n  | setPostUrl   | 设置表单提交地址\u003cbr /\u003e默认提交到 admin/formApply/edit | string url                                       | this  |\n  | hideButton   | 隐藏按钮 默认为不隐藏                              | bool hide                                        | this  |\n  | setReturnUrl | 设置返回按钮跳转地址                               | string return_url                                | this  |\n\n## \n\n## 自定义验证器\n\n1. 在Schema\\Validator 新增新的验证类\n2. 继承BaseValidator基类\n3. 实现validate 和 errorMsg方法, validate负责对数据进行验证， errorMsg返回验证失败时的错误提示\n\n## \n\n## 用例\n\n### 1. 后台获取用户提交的表单数据\n\n```php\n$apply_id = 5; //qs_form_apply的主键，是用户提交的内容主键\n$mode = 'edit'; //表单模式，edit 编辑  readonly 自读\n$schema = CusForm::getInstance()-\u003egetApplySchema($apply_id, $mode);  \n$builder = new FormilyBuilder($apply_id, $schema);\n$builder-\u003esetMode($mode);\n\necho (string)$builder;\n```\n\n### 2. 生成自定义表单的jsonSchema\n\n```php\nuse CusForm\\Schema\\Builder;\nuse CusForm\\CusForm;\n\n$json = CusForm::getInstance()-\u003eformSchema(1);\n$builder = new Builder(json_decode($json));\n$this-\u003eajaxReturn($builder-\u003ebuild());\n```\n\n### 3.  保存表单内容\n\n```php\nuse CusForm\\Helper;\nuse CusForm\\CusForm;\n\n$data = Helper::iJson();\n$form_id = (int)$data.form_id;\nlist($r, $errMsg) = CusForm::getInstance()-\u003esubmitApply($form_id, $data);\nif($r === false){\n    $this-\u003eajaxReturn(['status' =\u003e 0, 'info' =\u003e $errMsg]);\n}\nelse {\n    $this-\u003eajaxReturn(['status' =\u003e 1, 'info' =\u003e '成功']);\n}\n```\n\n### 4. 生成用户提交的内容 jsonSchema\n\n```php\nuse CusForm\\CusForm;\nuse CusForm\\Schema\\Builder;\n\n$apply_id = 5;\n$mode = 'readonly';\n\n$json = CusForm::getInstance()-\u003egetApplySchema(5, 'readonly');\n$builder = new Builder($json);\n\n$this-\u003eajaxReturn($builder-\u003ebuild());\n```\n\n### 5. 固定字段与自定义字段结合\n\n```\nuse CusForm\\CusForm;\nuse CusForm\\Schema\\Builder;\nuse CusForm\\Schema\\Components\\Radio;\nuse CusForm\\Schema\\Components\\Input;\nuse CusForm\\Schema\\Components\\Textarea;\n\n$json = CusForm::getInstance()-\u003egetApplySchema(5, 'readonly');\n$builder = new Builder($json);\n$bq1 = new Textarea('bq1', '问题1');\n$bq1-\u003emaxLength(150)-\u003eshowCount(true)-\u003erequired()-\u003edefault('非常棒了')-\u003ereadonly();\n$builder-\u003eaddBefore($bq1); //将bq1固定字段添加到表单前\n\n$bq2 = new Input('bq2', '问题2');\n$bq2-\u003eplaceholder('占位符')-\u003eallowClear(true)-\u003erequired()-\u003ereadonly();\n$builder-\u003eaddBefore($bq2);\n\n$aq1 = new Radio('aq1', '问题3');\n$aq1-\u003eenum([\n    [\n        'label' =\u003e '1分',\n        'value' =\u003e 1\n    ],\n    [\n        'label' =\u003e '2分',\n        'value' =\u003e 2\n    ],\n    [\n        'label' =\u003e '3分',\n        'value' =\u003e 3\n    ],\n    [\n        'label' =\u003e '4分',\n        'value' =\u003e 4\n    ],\n    [\n        'label' =\u003e '5分',\n        'value' =\u003e 5\n    ]\n])-\u003erequired()-\u003edefault(5)-\u003ereadonly();\n$builder-\u003eaddAfter($aq1); //将aq1固定字段添加到表单后\n$this-\u003eajaxReturn($builder-\u003ebuild());\n```\n\n### 6.前台获取自定义表单\n\n安装扩展\n```shell\nnpm i @formily/core @formily/react @formily/antd @quansitech/qs-formily antd\n```\n\n```php\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  FormItem,\n  DatePicker,\n  Checkbox,\n  Cascader,\n  Editable,\n  Input,\n  NumberPicker,\n  Switch,\n  Password,\n  PreviewText,\n  Radio,\n  Reset,\n  Select,\n  Space,\n  Submit,\n  TimePicker,\n  Transfer,\n  TreeSelect,\n  FormGrid,\n  FormLayout,\n  FormTab,\n  FormCollapse,\n  ArrayTable,\n  ArrayCards,\n} from '@formily/antd'\nimport {Card, Slider, Rate, message} from 'antd'\nimport {Form, Area, Upload} from \"@quansitech/qs-formily\"\n\nimport 'antd/dist/antd.less'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n    components: {\n          Space,\n        FormGrid,\n        FormLayout,\n        FormTab,\n        FormCollapse,\n        ArrayTable,\n        ArrayCards,\n        FormItem,\n        DatePicker,\n        Checkbox,\n        Cascader,\n        Editable,\n        Input,\n        NumberPicker,\n        Switch,\n        Password,\n        PreviewText,\n        Radio,\n        Reset,\n        Select,\n        Submit,\n        TimePicker,\n        Transfer,\n        TreeSelect,\n        Upload,\n        Card,\n        Slider,\n        Rate,\n        Area\n    },\n  })\n\nexport const SchedulePage = () =\u003e {\n    const [ formProps, setFormProps ] = React.useState();\n    const [ schema, setSchema ] = React.useState();\n\n    React.useEffect(() =\u003e {\n        //获取jsonSchema\n        fetch('schema').then(res =\u003e {\n            setFormProps(res.form);\n            setSchema(res.schema);\n        })\n    }, []);\n\n    const handleSubmit = async (data) =\u003e {\n        //to do submit\n    }\n\n    return \u003cForm form={form} {...formProps} onAutoSubmit={handleSubmit}\u003e\n      \u003cSchemaField schema={schema} /\u003e\n          \u003cSubmit block size=\"large\"\u003e提交\u003c/Submit\u003e}\n    \u003c/Form\u003e\n}\n```\n\n## 开发步骤\n\nnode 18.19.0\n\n1. clone 本仓库到本地\n\n2. clone [quansitech/qs-formily (github.com)](https://github.com/quansitech/qs-formily)到js/packages\n\n3. clone [alibaba/formily: Alibaba Group Unified Form Solution -- Support React/ReactNative/Vue2/Vue3 (github.com)](https://github.com/alibaba/formily)将packages改名formilySrc，并移到js文件夹下（仅调试formily的源码时才需要）\n\n4. 在js目录下执行npm i\n\n5. cd js/formily/antd npm run start 进入开发调试模式；npm run build:playground 编译打包js\n\n## 编译步骤\n\nnode 18.19.0\n\n1. clone 本仓库到本地\n\n2. 在js目录下执行npm i\n\n3. cd js/formily/antd npm run build:playground 编译打包js\n\n## 如何自定义组件\n\n1. 自定义组件分两种情况\n   \n   + 组件需要与formitem进行属性映射\n     \n     *需要通过 @formily/react 的connect和mapRrops接口进行属性映射，可参考@formily相关文档及@formily/antd 的源码*\n   \n   + 无需与formitem属性映射\n     \n     定义普通的react组件即可\n\n2. 在js/formily/antd/src/components下新增组件文件夹，增加behavior和resource接口，用于定义组件在designable的展示及预置行为。 如果需要给组件添加固定属性，可以在createResource方法中传入固定属性参数；\n   \n   如组件中需要用到Config配置，可定义init方法，并将组件通过addInitComponent注册进初始化列表。\n\n3. 在js/formily/antd/src/schemas添加组件的配置选项\n\n4. 在js/formily/antd/src/locales中添加中英对照\n\n5. 如需要添加自定义属性组件，可在js/formily/setters/src/components下新增组件\n\n## v3升级\n\nthink-core v13升级后，builder的display方法启用，以及上传接口的改变,旧oss模块弃用，改用新的qscmf-formitem-object-storage来代替，v3做了这方便的兼容处理\n\nv3会删除v1的废弃数据表，需要自行处理数据备份。","funding_links":[],"categories":["优秀组件"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquansitech%2Fqs-cusform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquansitech%2Fqs-cusform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquansitech%2Fqs-cusform/lists"}