index.tsx 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. import { Button, message, Modal } from 'antd';
  2. import { createForm, registerValidateRules } from '@formily/core';
  3. import { createSchemaField } from '@formily/react';
  4. import React, { useEffect, useState } from 'react';
  5. import * as ICONS from '@ant-design/icons';
  6. import { Form, FormGrid, FormItem, Input, Select } from '@formily/antd';
  7. import type { ISchema } from '@formily/json-schema';
  8. import { service } from '@/pages/link/Protocol';
  9. import FileUpload from '../FileUpload';
  10. import type { ProtocolItem } from '@/pages/link/Protocol/typings';
  11. import { PermissionButton } from '@/components';
  12. interface Props {
  13. data: ProtocolItem | undefined;
  14. close: () => void;
  15. reload: () => void;
  16. }
  17. const Save = (props: Props) => {
  18. const [data, setData] = useState<ProtocolItem | undefined>(props.data);
  19. const { permission } = PermissionButton.usePermission('link/Protocol');
  20. useEffect(() => {
  21. setData(props.data);
  22. }, [props.data]);
  23. const form = createForm({
  24. validateFirst: true,
  25. initialValues: data || {},
  26. });
  27. registerValidateRules({
  28. validateId(value) {
  29. if (!value) return '';
  30. const reg = new RegExp('^[0-9a-zA-Z_\\\\-]+$');
  31. return reg.exec(value) ? '' : 'ID只能由数字、26个英文字母或者下划线组成';
  32. },
  33. });
  34. const SchemaField = createSchemaField({
  35. components: {
  36. FormItem,
  37. Input,
  38. Select,
  39. FileUpload,
  40. FormGrid,
  41. },
  42. scope: {
  43. icon(name: any) {
  44. return React.createElement(ICONS[name]);
  45. },
  46. },
  47. });
  48. const schema: ISchema = {
  49. type: 'object',
  50. properties: {
  51. layout: {
  52. type: 'void',
  53. 'x-component': 'FormGrid',
  54. 'x-component-props': {
  55. maxColumns: 1,
  56. minColumns: 1,
  57. },
  58. properties: {
  59. id: {
  60. title: 'ID',
  61. 'x-component': 'Input',
  62. 'x-decorator': 'FormItem',
  63. 'x-disabled': !!props.data?.id,
  64. 'x-decorator-props': {
  65. gridSpan: 1,
  66. },
  67. 'x-validator': [
  68. {
  69. required: true,
  70. message: '请输入ID',
  71. },
  72. {
  73. max: 64,
  74. message: '最多可输入64个字符',
  75. },
  76. {
  77. validateId: true,
  78. message: 'ID只能由数字、26个英文字母或者下划线组成',
  79. },
  80. {
  81. triggerType: 'onBlur',
  82. validator: (value: string) => {
  83. if (!value) return;
  84. return new Promise((resolve) => {
  85. service
  86. .validator(value)
  87. .then((resp) => {
  88. if (!!resp?.result) {
  89. resolve('ID已存在');
  90. } else {
  91. resolve('');
  92. }
  93. })
  94. .catch(() => '验证失败!');
  95. });
  96. },
  97. },
  98. ],
  99. 'x-component-props': {
  100. placeholder: '请输入ID',
  101. },
  102. },
  103. name: {
  104. title: '名称',
  105. 'x-component': 'Input',
  106. 'x-decorator': 'FormItem',
  107. 'x-decorator-props': {
  108. gridSpan: 1,
  109. },
  110. 'x-component-props': {
  111. placeholder: '请输入名称',
  112. },
  113. 'x-validator': [
  114. {
  115. required: true,
  116. message: '请输入名称',
  117. },
  118. {
  119. max: 64,
  120. message: '最多可输入64个字符',
  121. },
  122. ],
  123. },
  124. type: {
  125. title: '类型',
  126. 'x-component': 'Select',
  127. 'x-decorator': 'FormItem',
  128. 'x-disabled': !!props.data?.id,
  129. 'x-decorator-props': {
  130. tooltip: <div>jar:上传协议jar包,文件格式支持.jar或.zip</div>,
  131. },
  132. 'x-component-props': {
  133. placeholder: '请选择类型',
  134. },
  135. 'x-validator': [
  136. {
  137. required: true,
  138. message: '请选择类型',
  139. },
  140. ],
  141. enum: [
  142. { label: 'jar', value: 'jar' },
  143. { label: 'local', value: 'local' },
  144. // { label: 'script', value: 'script' },
  145. ],
  146. },
  147. configuration: {
  148. type: 'object',
  149. properties: {
  150. location: {
  151. title: '文件地址',
  152. 'x-decorator': 'FormItem',
  153. 'x-visible': false,
  154. 'x-decorator-props': {
  155. tooltip: (
  156. <div>
  157. local:填写本地协议编译目录绝对地址,如:d:/workspace/protocol/target/classes
  158. </div>
  159. ),
  160. },
  161. 'x-validator': [
  162. {
  163. required: true,
  164. message: '请输入文件地址',
  165. },
  166. ],
  167. 'x-reactions': {
  168. dependencies: ['..type'],
  169. fulfill: {
  170. state: {
  171. visible: '{{["jar","local"].includes($deps[0])}}',
  172. componentType: '{{$deps[0]==="jar"?"FileUpload":"Input"}}',
  173. componentProps:
  174. '{{$deps[0]==="jar"?{type:"file", accept: ".jar, .zip"}:{placeholder: "请输入文件地址"}}}',
  175. },
  176. },
  177. },
  178. },
  179. },
  180. },
  181. description: {
  182. title: '说明',
  183. 'x-component': 'Input.TextArea',
  184. 'x-decorator': 'FormItem',
  185. 'x-component-props': {
  186. rows: 3,
  187. showCount: true,
  188. maxLength: 200,
  189. },
  190. },
  191. },
  192. },
  193. },
  194. };
  195. const save = async (deploy: boolean) => {
  196. const value = await form.submit<ProtocolItem>();
  197. let response = undefined;
  198. if (props.data?.id) {
  199. response = await service.save(value);
  200. } else {
  201. response = await service.update(value);
  202. }
  203. if (response && response.status === 200) {
  204. message.success('操作成功');
  205. if (deploy) {
  206. await service.modifyState(value.id, 'deploy');
  207. }
  208. props.reload();
  209. }
  210. };
  211. return (
  212. <Modal
  213. title={props?.data?.id ? '编辑' : '新增'}
  214. maskClosable={false}
  215. visible
  216. onCancel={props.close}
  217. width={700}
  218. footer={[
  219. <Button key={1} onClick={props.close}>
  220. 取消
  221. </Button>,
  222. <Button
  223. type="primary"
  224. key={2}
  225. onClick={() => {
  226. save(false);
  227. }}
  228. disabled={props.data?.id ? !permission.update : !permission.add}
  229. >
  230. 保存
  231. </Button>,
  232. <Button
  233. key={3}
  234. type="primary"
  235. onClick={() => {
  236. save(true);
  237. }}
  238. disabled={
  239. props.data?.id
  240. ? !permission.update && !permission.action
  241. : !permission.add && !permission.action
  242. }
  243. >
  244. 保存并发布
  245. </Button>,
  246. ]}
  247. >
  248. <Form form={form} layout="vertical">
  249. <SchemaField schema={schema} />
  250. </Form>
  251. </Modal>
  252. );
  253. };
  254. export default Save;