mapServe.tsx 9.8 KB

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