mapServe.tsx 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. import React, { useState, useEffect, useMemo } from 'react';
  2. import { FlowchartFormWrapper } from '@antv/xflow';
  3. import {
  4. Position,
  5. Size,
  6. ColorPicker,
  7. InputNumberField,
  8. InputField,
  9. SelectField,
  10. } from '../fields';
  11. import { PREFIX } from '../constants';
  12. import { connect } from 'umi';
  13. import { UnityAction } from '@/utils/utils';
  14. import { Button, Card } from 'antd';
  15. import AddCondition from '../../components/judgeModal';
  16. import RenderJudge, { JudgeType } from '../../components/judgeComponent';
  17. import { TYPE } from '../auditNode/mapServe';
  18. import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
  19. // export const enum TYPE {
  20. // AUDIT,
  21. // INITIATOR,
  22. // COPYMAN,
  23. // }
  24. export const enum ComponentName {
  25. Inner = 'InnerContactField',
  26. Depart = 'DepartmentField',
  27. Select = 'DDSelectField',
  28. Money = 'MoneyField',
  29. MultiSelect = 'DDMultiSelectField',
  30. Number = 'NumberField',
  31. }
  32. export interface IConfig {
  33. label?: string;
  34. x?: number;
  35. y?: number;
  36. width?: number;
  37. height?: number;
  38. count?: number;
  39. fontSize?: number;
  40. fontFill?: string;
  41. fill?: string;
  42. stroke?: string;
  43. flow_id?: string;
  44. flow_node_id?: string;
  45. process_code?: string;
  46. type: TYPE;
  47. // 条件 【此字段存在是为了兼容旧格式】
  48. formItems: string;
  49. // 条件组 【新版用此字段】 formItems和formItemsOr同时只能存在一个
  50. formItemsOr: string[];
  51. priority?: number; //优先级
  52. }
  53. export interface FormItem {
  54. componentName: string;
  55. props: {
  56. label: string;
  57. id: string;
  58. options?: string[];
  59. required: boolean;
  60. placeholder?: string;
  61. };
  62. judge?: JudgeType;
  63. }
  64. const Component = (props: any) => {
  65. const { config, plugin = {}, formData } = props;
  66. const { updateNode } = plugin;
  67. // const formData: FormItem[] = [
  68. // {
  69. // componentName: 'InnerContactField',
  70. // props: {
  71. // label: '申请人',
  72. // id: 'InnerContactField-JEQRQ5VH',
  73. // required: true,
  74. // },
  75. // },
  76. // {
  77. // componentName: 'DepartmentField',
  78. // props: {
  79. // label: '选择部门',
  80. // id: 'DepartmentField_1VALX0GTRNVK0',
  81. // required: true,
  82. // },
  83. // },
  84. // {
  85. // componentName: 'DDSelectField',
  86. // props: {
  87. // id: 'DDSelectField_LWFCJRK508W0',
  88. // label: '文件类型',
  89. // options: [
  90. // '{"value":"新增|FT008","key":"option_1IXTB1VDV9EO0"}',
  91. // '{"value":"补充|FT009","key":"option_1DVWNV9BNZNK0"}',
  92. // ],
  93. // required: true,
  94. // },
  95. // },
  96. // {
  97. // componentName: 'DDSelectField',
  98. // props: {
  99. // id: 'DDSelectField_21WUQ0OWR7R40',
  100. // label: '是否外带',
  101. // options: [
  102. // '{"value":"是","key":"option_DUSP6XANFKO0"}',
  103. // '{"value":"否","key":"option_CC5VQ63ZLJK0"}',
  104. // ],
  105. // required: true,
  106. // },
  107. // },
  108. // {
  109. // componentName: 'MoneyField',
  110. // props: {
  111. // id: 'MoneyField-JSCUC2GG',
  112. // label: '文件金额(元)',
  113. // placeholder: '请输入金额',
  114. // required: true,
  115. // },
  116. // },
  117. // ];
  118. const [nodeConfig, setNodeConfig] = useState<IConfig>({
  119. ...config,
  120. });
  121. const formItemsGroup = nodeConfig.formItemsOr || [];
  122. const onNodeConfigChange = (key: string, value: number | string | object) => {
  123. if (key) {
  124. setNodeConfig({
  125. ...nodeConfig,
  126. [key]: value,
  127. });
  128. updateNode({
  129. type: TYPE.JUDGE,
  130. [key]: value,
  131. });
  132. } else if (value instanceof Object) {
  133. setNodeConfig({
  134. ...nodeConfig,
  135. ...value,
  136. });
  137. updateNode({
  138. type: TYPE.JUDGE,
  139. ...value,
  140. });
  141. }
  142. };
  143. const onSave = () => {
  144. UnityAction.emit('NODE_SAVE', nodeConfig);
  145. };
  146. const onAddConditionGroup = () => {
  147. onNodeConfigChange('formItemsOr', [...formItemsGroup, '[]']);
  148. };
  149. const onRemoveConditionGroup = (index: number) => {
  150. let tempGroup = [...formItemsGroup];
  151. tempGroup.splice(index, 1);
  152. onNodeConfigChange('formItemsOr', [...tempGroup]);
  153. };
  154. const onAddCondition = (values: FormItem[], index: number) => {
  155. const getFormItemsStr = (formItems: string) => {
  156. let newFormItems: FormItem[] = [];
  157. let oldFormItems = JSON.parse(formItems || '[]');
  158. values.forEach((item) => {
  159. let id = item.props.id;
  160. // 判断是否含有旧的item
  161. let oldItem = oldFormItems.find(
  162. (formItem: FormItem) => formItem.props.id == id,
  163. );
  164. if (oldItem) {
  165. newFormItems.push(oldItem);
  166. } else {
  167. newFormItems.push(item);
  168. }
  169. });
  170. return JSON.stringify(newFormItems);
  171. };
  172. let tempGroup = [...formItemsGroup];
  173. // 更新条件组
  174. tempGroup[index] = getFormItemsStr(tempGroup[index]);
  175. onNodeConfigChange('formItemsOr', tempGroup);
  176. };
  177. const renderCondition = () => {
  178. let Cards: any = [];
  179. formItemsGroup.forEach((formItems: string, index: number) => {
  180. Cards.push(
  181. <Card
  182. key={index}
  183. title={`条件组${index + 1}`}
  184. extra={
  185. <CloseOutlined onClick={() => onRemoveConditionGroup(index)} />
  186. }
  187. >
  188. <AddCondition
  189. items={formData}
  190. formItems={formItems}
  191. onOk={(values: FormItem[]) => onAddCondition(values, index)}
  192. />
  193. <RenderJudge
  194. formItems={formItems}
  195. onChange={(values: FormItem[]) => {
  196. let tempGroup = [...formItemsGroup];
  197. tempGroup[index] = JSON.stringify(values);
  198. onNodeConfigChange('formItemsOr', tempGroup);
  199. }}
  200. />
  201. </Card>,
  202. );
  203. if (index != formItemsGroup.length - 1) {
  204. Cards.push(<div>或</div>);
  205. }
  206. });
  207. return Cards;
  208. };
  209. useEffect(() => {
  210. setNodeConfig({
  211. ...config,
  212. });
  213. }, [config]);
  214. return (
  215. <div className={`${PREFIX}-panel-body`}>
  216. <div className={`${PREFIX}-panel-group`}>
  217. <h5>内容</h5>
  218. <InputField
  219. label="标题"
  220. value={nodeConfig.label}
  221. onChange={(value) => {
  222. onNodeConfigChange('label', value);
  223. }}
  224. />
  225. </div>
  226. <div className={`${PREFIX}-panel-group`}>
  227. <h5>样式</h5>
  228. <Position
  229. x={nodeConfig.x}
  230. y={nodeConfig.y}
  231. onChange={(key, value) => {
  232. onNodeConfigChange(key, value);
  233. }}
  234. />
  235. <Size
  236. width={nodeConfig.width}
  237. height={nodeConfig.height}
  238. onChange={(key, value) => {
  239. onNodeConfigChange(key, value);
  240. }}
  241. />
  242. <ColorPicker
  243. label="填充"
  244. value={nodeConfig.fill}
  245. onChange={(value: string) => {
  246. onNodeConfigChange('fill', value);
  247. }}
  248. />
  249. <ColorPicker
  250. label="边框"
  251. value={nodeConfig.stroke}
  252. onChange={(value: string) => {
  253. onNodeConfigChange('stroke', value);
  254. }}
  255. />
  256. <InputNumberField
  257. label="消息数量"
  258. value={nodeConfig.count}
  259. onChange={(value) => {
  260. onNodeConfigChange('count', value);
  261. }}
  262. />
  263. <div className={`${PREFIX}-node-text-style`}>
  264. <InputNumberField
  265. label="字号"
  266. value={nodeConfig.fontSize}
  267. width={68}
  268. onChange={(value) => {
  269. onNodeConfigChange('fontSize', value);
  270. }}
  271. />
  272. <ColorPicker
  273. value={nodeConfig.fontFill}
  274. onChange={(value: string) => {
  275. onNodeConfigChange('fontFill', value);
  276. }}
  277. />
  278. </div>
  279. <InputNumberField
  280. label="优先级"
  281. value={nodeConfig.priority}
  282. width={68}
  283. onChange={(value) => {
  284. onNodeConfigChange('priority', value);
  285. }}
  286. />
  287. <Button icon={<PlusOutlined />} onClick={() => onAddConditionGroup()}>
  288. 新增条件组
  289. </Button>
  290. {renderCondition()}
  291. </div>
  292. <Button style={{ marginTop: 20 }} type="primary" onClick={onSave}>
  293. 保存
  294. </Button>
  295. </div>
  296. );
  297. };
  298. function RecthServe(props: any) {
  299. return (
  300. <FlowchartFormWrapper {...props}>
  301. {(config, plugin) => (
  302. <Component {...props} plugin={plugin} config={config} />
  303. )}
  304. </FlowchartFormWrapper>
  305. );
  306. }
  307. export default connect(({ xflow }: any) => ({
  308. auditList: xflow.auditList,
  309. formData: xflow.formData,
  310. }))(RecthServe);