mapServe.tsx 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. import React, { useState, useEffect } from 'react';
  2. import { FlowchartFormWrapper } from '@antv/xflow';
  3. import { Button, message, Select } from 'antd';
  4. import LuckyExcel from 'luckyexcel';
  5. import {
  6. Position,
  7. Size,
  8. ColorPicker,
  9. InputNumberFiled,
  10. InputFiled,
  11. UploadFiled,
  12. RadioField,
  13. } from '../fields';
  14. import { PREFIX } from '../constants';
  15. import { UnityAction } from '@/utils/utils';
  16. import { connect } from 'dva';
  17. interface ExcelInfo {
  18. file_name?: string;
  19. excel_cols?: any;
  20. }
  21. export interface IConfig {
  22. label?: string;
  23. x?: number;
  24. y?: number;
  25. width?: number;
  26. height?: number;
  27. fontSize?: number;
  28. count?: number;
  29. fontFill?: string;
  30. fill?: string;
  31. stroke?: string;
  32. muti_version?: string | number;
  33. is_start_node?: string | number;
  34. bom_template?: string;
  35. version_name?: string;
  36. data?: any;
  37. excel_info?: ExcelInfo;
  38. role_list?: string;
  39. }
  40. const defaultConfig: IConfig = {
  41. muti_version: 1,
  42. is_start_node: 0,
  43. excel_info: { file_name: '' },
  44. };
  45. const Component = (props: any) => {
  46. const { config, plugin = {}, roleList } = props;
  47. const { updateNode } = plugin;
  48. const [options, setOptions] = useState([]);
  49. const [fileName, setFileName] = useState('');
  50. const [nodeConfig, setNodeConfig] = useState<IConfig>({
  51. ...defaultConfig,
  52. ...config,
  53. });
  54. const onNodeConfigChange = (key: string, value: number | string | object) => {
  55. if (key) {
  56. setNodeConfig({
  57. ...nodeConfig,
  58. [key]: value,
  59. });
  60. updateNode({
  61. [key]: value,
  62. });
  63. } else if (value instanceof Object) {
  64. setNodeConfig({
  65. ...nodeConfig,
  66. ...value,
  67. });
  68. updateNode({
  69. ...value,
  70. });
  71. }
  72. };
  73. const onSave = () => {
  74. UnityAction.emit('NODE_SAVE', nodeConfig);
  75. };
  76. const beforeUpload = (file: any) => {
  77. LuckyExcel.transformExcelToLucky(file, (exportJson, luckysheetfile) => {
  78. if (exportJson.sheets == null || exportJson.sheets.length == 0) {
  79. message.error('读取xlsx文件失败!');
  80. return;
  81. }
  82. console.log(exportJson);
  83. const sheet = exportJson.sheets[0];
  84. let titleCell = [];
  85. sheet.celldata.forEach(item => {
  86. if (item.r == 0) {
  87. // 标题头
  88. titleCell.push(item);
  89. }
  90. // 生成cid
  91. item.v.cid = `${item.r}-${item.c}`;
  92. });
  93. let cell = titleCell.map(item => {
  94. let value = '';
  95. if (item.v?.v) {
  96. value = item.v?.v;
  97. } else if (item.v.ct?.s && item.v.ct?.s instanceof Array) {
  98. value = item.v.ct.s.map(item => item?.v).join?.('');
  99. }
  100. return { sheet_name: sheet.name, col_idx: item.r, col_axis: item.c, col_value: value };
  101. });
  102. onNodeConfigChange(null, {
  103. data: [sheet],
  104. excel_info: {
  105. file_name: file.name,
  106. excel_cols: cell,
  107. },
  108. });
  109. });
  110. };
  111. useEffect(() => {
  112. setNodeConfig({
  113. ...defaultConfig,
  114. ...config,
  115. });
  116. }, [config]);
  117. const updataFileName = (name: string) => {
  118. var idx = name?.lastIndexOf('/');
  119. let str = name.substring(idx + 1, name.length);
  120. setFileName(str);
  121. };
  122. useEffect(() => {
  123. if (config.bom_template) updataFileName(config.bom_template);
  124. if (nodeConfig.excel_info?.file_name) updataFileName(nodeConfig.excel_info.file_name);
  125. }, [nodeConfig.bom_template, nodeConfig.excel_info.file_name]);
  126. // console.log(nodeConfig, config)
  127. useEffect(() => {
  128. if (!roleList || roleList.length <= 0) return;
  129. let op = [];
  130. console.log(roleList);
  131. roleList
  132. .filter(cur => cur.RoleType == 4)
  133. .forEach(item => {
  134. op.push({ label: `${item.Name}(${item.ID})`, value: item.ID });
  135. });
  136. setOptions(op);
  137. console.log(op);
  138. }, [roleList]);
  139. // const handleFileNameClick = () => {
  140. // if (nodeConfig.bom_template) window.open(nodeConfig.bom_template);
  141. // };
  142. return (
  143. <div className={`${PREFIX}-panel-body`}>
  144. <div className={`${PREFIX}-panel-group`}>
  145. <h5>内容</h5>
  146. <InputFiled
  147. label="标题"
  148. value={nodeConfig.label}
  149. onChange={value => {
  150. onNodeConfigChange('label', value);
  151. }}
  152. />
  153. </div>
  154. <div className={`${PREFIX}-panel-group`}>
  155. <h5>数据</h5>
  156. <RadioField
  157. label="多个版本"
  158. value={nodeConfig.muti_version}
  159. onChange={value => {
  160. onNodeConfigChange('muti_version', value);
  161. }}
  162. options={[
  163. { label: '是', value: 1 },
  164. { label: '否', value: 0 },
  165. ]}
  166. />
  167. <RadioField
  168. label="起始起点"
  169. value={nodeConfig.is_start_node}
  170. onChange={value => {
  171. onNodeConfigChange('is_start_node', value);
  172. }}
  173. options={[
  174. { label: '是', value: 1 },
  175. { label: '否', value: 0 },
  176. ]}
  177. />
  178. {nodeConfig.is_start_node == 1 && (
  179. <>
  180. <InputFiled
  181. label="模板名称"
  182. value={nodeConfig.version_name}
  183. onChange={value => {
  184. onNodeConfigChange('version_name', value);
  185. }}
  186. />
  187. <UploadFiled
  188. label="模板"
  189. onChange={url => onNodeConfigChange('bom_template', url)}
  190. beforeUpload={beforeUpload}
  191. />
  192. {/* <div onClick={handleFileNameClick}>{fileName}</div> */}
  193. <a href={nodeConfig.bom_template}>{fileName}</a>
  194. </>
  195. )}
  196. <div className="group">
  197. <label>权限</label>
  198. <Select
  199. value={
  200. nodeConfig.role_list ? nodeConfig.role_list.split(',').map(item => Number(item)) : []
  201. }
  202. mode="multiple"
  203. allowClear
  204. style={{ width: '100%' }}
  205. placeholder="选择权限"
  206. onChange={(v: number[]) => {
  207. onNodeConfigChange('role_list', v.join(','));
  208. }}
  209. options={options}
  210. />
  211. </div>
  212. </div>
  213. <div className={`${PREFIX}-panel-group`}>
  214. <h5>样式</h5>
  215. <Position
  216. x={nodeConfig.x}
  217. y={nodeConfig.y}
  218. onChange={(key, value) => {
  219. onNodeConfigChange(key, value);
  220. }}
  221. />
  222. <Size
  223. width={nodeConfig.width}
  224. height={nodeConfig.height}
  225. onChange={(key, value) => {
  226. onNodeConfigChange(key, value);
  227. }}
  228. />
  229. <ColorPicker
  230. label="填充"
  231. value={nodeConfig.fill}
  232. onChange={(value: string) => {
  233. onNodeConfigChange('fill', value);
  234. }}
  235. />
  236. <ColorPicker
  237. label="边框"
  238. value={nodeConfig.stroke}
  239. onChange={(value: string) => {
  240. onNodeConfigChange('stroke', value);
  241. }}
  242. />
  243. <InputNumberFiled
  244. label="消息数量"
  245. value={nodeConfig.count}
  246. onChange={value => {
  247. onNodeConfigChange('count', value);
  248. }}
  249. />
  250. <div style={{ display: 'flex' }}>
  251. <InputNumberFiled
  252. label="字号"
  253. value={nodeConfig.fontSize}
  254. width={68}
  255. onChange={value => {
  256. onNodeConfigChange('fontSize', value);
  257. }}
  258. style={{ marginRight: 10 }}
  259. />
  260. <ColorPicker
  261. value={nodeConfig.fontFill}
  262. onChange={(value: string) => {
  263. onNodeConfigChange('fontFill', value);
  264. }}
  265. />
  266. </div>
  267. </div>
  268. <Button type="primary" onClick={onSave}>
  269. 保存
  270. </Button>
  271. </div>
  272. );
  273. };
  274. function RecthServe(props: any) {
  275. return (
  276. <FlowchartFormWrapper {...props}>
  277. {(config, plugin) => <Component {...props} plugin={plugin} config={config} />}
  278. </FlowchartFormWrapper>
  279. );
  280. }
  281. export default connect(({ flow }) => ({ roleList: flow.roleList }))(RecthServe);