AddData.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. import { useEffect, useState, useContext } from 'react';
  2. import { Form, Input, Button, Steps, Tabs, Space, Switch, Breadcrumb, Radio, TreeSelect, Tree, Tag, Card, message, Modal } from 'antd';
  3. import './index.less';
  4. import DataContext from './data-context';
  5. import MenuTree from './MenuTree';
  6. import { useSelector } from 'react-redux'
  7. import apiObj from '@api/index';
  8. import utils from '@utils/index'
  9. import backIcon from "@images/back.png";
  10. import del from '@images/icon-del.png'
  11. import DoctorList from "./doctorList"
  12. import Item from 'antd/lib/list/Item';
  13. const { post, api, xPost } = apiObj;
  14. const { SHOW_PARENT } = TreeSelect;
  15. const { organizationData } = utils;
  16. const { Step } = Steps;
  17. const { TabPane } = Tabs;
  18. function AddData(props) {
  19. useEffect(() => {
  20. getHospitalTree()
  21. getOrgList()
  22. if (type == 3) {
  23. setValue(val)
  24. }
  25. }, []);
  26. const { back, } = props;
  27. const [form] = Form.useForm();
  28. const [isChange, setIsChange] = useState(false);
  29. const [visible, setVisible] = useState(false);
  30. const [value, setValue] = useState([]);
  31. const [key, setKey] = useState();
  32. const [index, setIndex] = useState('0');
  33. const [treeRloe, setTreeRloe] = useState([]);
  34. const [tags, setTags] = useState([[]]);
  35. const [treeData, setTreeData] = useState([]);
  36. const [selectedKeys, setSelectedKeys] = useState([]);
  37. const [orgList, setOrgList] = useState([]);
  38. const [selectedRowKeys, setSelectedRowKeys] = useState([]);
  39. const [softwareId, setSoftwareId] = useState([]);
  40. const [autoExpandParent, setAutoExpandParent] = useState(true);
  41. const { save, formData, type, val, tag } = useContext(DataContext);
  42. const staticInfo = useSelector(state => {
  43. return state.staticInfo;
  44. });
  45. const { dataList } = staticInfo;
  46. const initialValues = formData
  47. const validateMessages = {
  48. required: '${label}不能为空',
  49. };
  50. function handleOk() {
  51. back()
  52. }
  53. function handleCancel() {
  54. setVisible(false)
  55. }
  56. const goback = () => {
  57. if ((form.getFieldsValue().name != undefined || isChange) && type != 3) {
  58. setVisible(true)
  59. } else {
  60. back()
  61. }
  62. };
  63. //获取当前用于所属角色
  64. function getCreateRoles(softwareId) {
  65. const params = {
  66. softwareId: softwareId
  67. }
  68. xPost(api.getCreateRoles, params).then((res) => {
  69. if (res.data.code === 200) {
  70. const data = res.data.data;
  71. let arr = JSON.parse(JSON.stringify(data).replace(/name/g, 'title').replace(/id/g, 'value'))
  72. setTreeRloe(arr)
  73. }
  74. })
  75. }
  76. //获取当前用户组织
  77. function getHospitalTree() {
  78. post(api.getHospitalTree).then((res) => {
  79. if (res.data.code === 200) {
  80. const data = res.data.data
  81. let arr = structureTreeData(data)
  82. setTreeData(arr)
  83. }
  84. })
  85. }
  86. //数据转换为树形结构所需字段
  87. function structureTreeData(arr) {
  88. arr.forEach(item => {
  89. item.key = item.hospitalId + '-' + item.hospitalName
  90. item.title = item.hospitalName
  91. if (!item.children && item.depts) {
  92. item.depts.forEach(it => {
  93. it.key = item.hospitalId + '-' + it.deptId + '-' + it.deptName
  94. })
  95. item.children = JSON.parse(JSON.stringify(item.depts).replace(/deptName/g, 'title').replace(/deptId/g, 'key'))
  96. return
  97. }
  98. if (item.children) {
  99. structureTreeData(item.children)
  100. }
  101. })
  102. return arr
  103. // let list = []
  104. // arr.forEach(it => {
  105. // it.key = it.hospitalId
  106. // it.title = it.hospitalName
  107. // list.push({
  108. // children: it.depts,
  109. // title: it.hospitalName,
  110. // key: it.parentId + '-' + it.hospitalId + '-' + it.hospitalName
  111. // })
  112. // it.depts.forEach(its => {
  113. // its.key = it.parentId + '-' + it.hospitalId + '-' + its.deptId + '-' + its.deptName
  114. // })
  115. // })
  116. // arr = JSON.parse(JSON.stringify(list).replaceAll(/deptName/g, 'title').replaceAll(/deptId/g, 'key'))
  117. // return arr
  118. }
  119. //获取组织列表
  120. function getOrgList() {
  121. xPost(api.getUserHospitals).then((res) => {
  122. if (res.data.code === 200) {
  123. const data = res.data.data;
  124. const { software } = data;
  125. setOrgList(software);
  126. setKey(software[0].id)
  127. getCreateRoles(software[0].id)
  128. if (type == 3) {
  129. software.forEach((it, index) => {
  130. tag.forEach((item, i) => {
  131. tags[index] = []
  132. if(i == index){
  133. tags[index] = tag[i]
  134. }
  135. })
  136. setTags([...tags])
  137. })
  138. } else {
  139. software.forEach((it, index) => {
  140. tags[index] = []
  141. setTags([...tags])
  142. })
  143. }
  144. } else {
  145. message.warning(res.data.msg || '获取医院列表失败');
  146. }
  147. }).catch(() => {
  148. message.error("接口出错");
  149. });
  150. }
  151. const onChange = (e, i) => {
  152. let val = value
  153. const formData = form.getFieldsValue();
  154. let arr = formData.softwareVOS;
  155. arr[index].id = key
  156. arr[index].softwareMenuIds = []
  157. arr[index].dataAuthDetails = []
  158. arr[index].selectedRowKeys = []
  159. if (e.target.value != 7) {
  160. arr[index].dataAuthDetails = [{
  161. dataType: e.target.value
  162. }]
  163. }
  164. tags[index] = []
  165. val[i] = e.target.value
  166. selectedRowKeys[index] = []
  167. form.setFieldsValue({
  168. softwareVOS: arr
  169. });
  170. setTags([...tags])
  171. setValue([...val])
  172. setSelectedRowKeys([...selectedRowKeys])
  173. setIsChange(true)
  174. };
  175. // 删除选择标签
  176. function delTag(type, id, i) {
  177. const formData = form.getFieldsValue();
  178. const softwareVOS = formData.softwareVOS[index]
  179. if (type == 3) {
  180. softwareVOS.selectedRowKeys.forEach((item, inx) => {
  181. if (item.split('-')[0] == id) {
  182. softwareVOS.selectedRowKeys.splice(inx)
  183. }
  184. })
  185. softwareVOS.dataAuthDetails.forEach((item, inx) => {
  186. if (item.detailId == id) {
  187. softwareVOS.dataAuthDetails.splice(inx)
  188. }
  189. })
  190. } else if (type == 1) {
  191. softwareVOS.softwareMenuIds.forEach((item, inx) => {
  192. if (item.split('-')[0] == id) {
  193. softwareVOS.softwareMenuIds.splice(inx)
  194. }
  195. })
  196. softwareVOS.dataAuthDetails.forEach((item, inx) => {
  197. if (item.detailId == id) {
  198. softwareVOS.dataAuthDetails.splice(inx)
  199. }
  200. })
  201. } else if (type == 2) {
  202. softwareVOS.softwareMenuIds.forEach((item, inx) => {
  203. if (item.split('-')[1] == id) {
  204. softwareVOS.softwareMenuIds.splice(inx)
  205. }
  206. })
  207. softwareVOS.dataAuthDetails.forEach((item, inx) => {
  208. if (item.detailId == id) {
  209. softwareVOS.dataAuthDetails.splice(inx)
  210. }
  211. })
  212. }
  213. form.setFieldsValue({
  214. softwareVOS: formData.softwareVOS
  215. });
  216. tags[index].splice(i)
  217. setTags([...tags])
  218. }
  219. function callback(key) {
  220. setKey(key.split('-')[0])
  221. setIndex(key.split('-')[1])
  222. getCreateRoles(key.split('-')[0])
  223. }
  224. function treeChange(value) {
  225. const formData = form.getFieldsValue();
  226. let arr = formData.softwareVOS;
  227. arr[index].roles = value
  228. form.setFieldsValue({
  229. softwareVOS: arr
  230. });
  231. setIsChange(true)
  232. }
  233. // 去重
  234. function unique(arr) {
  235. let result = {};
  236. let finalResult = [];
  237. for (let i = 0; i < arr.length; i++) {
  238. result[arr[i].detailId] = arr[i];
  239. }
  240. for (let item in result) {
  241. finalResult.push(result[item]);
  242. }
  243. return finalResult;
  244. }
  245. //医生选中
  246. function checkDoctEvent(selectedRowKeys) {
  247. const formData = form.getFieldsValue();
  248. let arr = formData.softwareVOS[index].dataAuthDetails ? formData.softwareVOS[index].dataAuthDetails : []
  249. selectedRowKeys.forEach(it => {
  250. arr.push({
  251. dataType: 7,
  252. detailId: it.split('-')[0],
  253. detailType: 3
  254. })
  255. });
  256. formData.softwareVOS[index].dataAuthDetails = unique(arr)
  257. formData.softwareVOS[index].selectedRowKeys = selectedRowKeys
  258. form.setFieldsValue({
  259. softwareVOS: formData.softwareVOS
  260. });
  261. getTags()
  262. }
  263. //树形结构选中事件
  264. function checkTreeEvent(idsArr) {
  265. const formData = form.getFieldsValue();
  266. let arr = formData.softwareVOS[index].dataAuthDetails ? formData.softwareVOS[index].dataAuthDetails : []
  267. let result = idsArr.filter(ele => {
  268. return ele.split('-').length == 2
  269. })
  270. if (result) {
  271. result.forEach(it => {
  272. arr.push({
  273. dataType: 7,
  274. detailId: it.split('-')[0],
  275. detailType: 1
  276. })
  277. })
  278. } else {
  279. idsArr.forEach(it => {
  280. arr.push({
  281. dataType: 7,
  282. detailId: it.split('-')[1],
  283. detailType: 2
  284. })
  285. })
  286. }
  287. formData.softwareVOS[index].dataAuthDetails = unique(arr)
  288. formData.softwareVOS[index].softwareMenuIds = idsArr
  289. form.setFieldsValue({
  290. softwareVOS: formData.softwareVOS
  291. });
  292. getTags()
  293. }
  294. //获取已选中标签
  295. function getTags() {
  296. const formData = form.getFieldsValue();
  297. let tag = []
  298. let softwareMenuIds = formData.softwareVOS[index].softwareMenuIds
  299. let selectedRowKeys = formData.softwareVOS[index].selectedRowKeys
  300. selectedRowKeys && selectedRowKeys.forEach(it => {
  301. tag.push({
  302. id: it.split('-')[0],
  303. name: it.split('-')[1],
  304. type: 3
  305. })
  306. });
  307. if (softwareMenuIds) {
  308. let result = softwareMenuIds.filter(ele => {
  309. return ele.split('-').length == 2
  310. })
  311. if (result) {
  312. result.forEach(it => {
  313. tag.push({
  314. id: it.split('-')[0],
  315. name: it.split('-')[1],
  316. type: 1
  317. })
  318. })
  319. } else {
  320. softwareMenuIds.forEach(it => {
  321. tag.push({
  322. id: it.split('-')[1],
  323. name: it.split('-')[2],
  324. type: 2
  325. })
  326. })
  327. }
  328. }
  329. tags[index] = tag
  330. setTags([...tags])
  331. }
  332. const onFinish = value => {
  333. save(form.getFieldsValue())
  334. };
  335. function swichChange(val) {
  336. form.setFieldsValue({ status: val ? 1 : 0 })
  337. }
  338. function delAll() {
  339. const formData = form.getFieldsValue();
  340. formData.softwareVOS[index].selectedRowKeys = []
  341. formData.softwareVOS[index].softwareMenuIds = []
  342. formData.softwareVOS[index].dataAuthDetails = []
  343. form.setFieldsValue({
  344. softwareVOS: formData.softwareVOS
  345. });
  346. tags[index] = []
  347. setTags([...tags])
  348. }
  349. return (
  350. <>
  351. <Breadcrumb separator="">
  352. <Breadcrumb.Item><img className='back-icon' src={backIcon} onClick={goback} alt="返回上一页" /></Breadcrumb.Item>
  353. <Breadcrumb.Item>数据权限</Breadcrumb.Item>
  354. <Breadcrumb.Separator />
  355. <Breadcrumb.Item>{type == 3 ? '修改' : '新增'}数据权限</Breadcrumb.Item>
  356. </Breadcrumb>
  357. <div className='form-center'>
  358. <Form labelCol={{ span: 4 }} wrapperCol={{ span: 18 }} form={form} name="nest-messages" onFinish={onFinish} initialValues={initialValues} validateMessages={validateMessages}>
  359. <Form.Item name="name" label="数据权限名称" rules={[{ required: true }]}>
  360. <Input placeholder="请填写数据权限名称" style={{ width: 300 }} />
  361. </Form.Item>
  362. <Form.Item label="权限范围" rules={[{ required: true }]} >
  363. <Tabs type="card" onChange={callback}>
  364. {
  365. orgList.map((it, i) => {
  366. return (
  367. <TabPane tab={it.name} key={it.id + "-" + i} forceRender={type == 3 && form.getFieldValue().softwareVOS[i] ? true : false}>
  368. <Form.Item
  369. key={i}
  370. name={['softwareVOS', i, 'datatype']} noStyle>
  371. <Radio.Group onChange={e => { onChange(e, i) }} className="radio">
  372. <Space direction="vertical">
  373. {dataList.map((Item) => {
  374. return (
  375. <Radio key={i} value={Item.name}>{Item.val}</Radio>
  376. )
  377. })
  378. }
  379. </Space>
  380. </Radio.Group>
  381. </Form.Item>
  382. <Form.Item key={i + "a"} hidden={true} name={['softwareVOS', i, 'id']} noStyle>
  383. <Input />
  384. </Form.Item>
  385. <Form.Item key={i + "b"} hidden={true} name={['softwareVOS', i, 'dataAuthDetails']} noStyle>
  386. <Input />
  387. </Form.Item>
  388. <Form.Item key={i + "e"} hidden={true} name={['softwareVOS', i, 'roles']} noStyle>
  389. <Input />
  390. </Form.Item>
  391. <Form.Item key={i + "c"} style={{ display: value[index] == 7 && it.id == key ? 'block' : 'none' }}>
  392. <Card title="已选中" extra={<span onClick={delAll} className='del-all'><img className='del-icon' src={del} />清空所有</span>} >
  393. {tags[index].map((tag, i) => {
  394. return (
  395. <Tag key={i} closable onClose={e => delTag(tag.type, tag.id, i)}>{tag.name}</Tag>
  396. );
  397. })}
  398. </Card>
  399. </Form.Item>
  400. <Form.Item key={i + "d"} style={{ display: value[index] == 7 && it.id == key ? 'block' : 'none' }}>
  401. <Tabs defaultActiveKey="0">
  402. <TabPane tab="可看医生" key="0" forceRender={type == 3 && form.getFieldValue().softwareVOS[i] ? true : false}>
  403. <Form.Item
  404. name={['softwareVOS', i, 'selectedRowKeys']}
  405. >
  406. <DoctorList checkeds={form.getFieldValue().softwareVOS ? form.getFieldValue().softwareVOS[i] : []} checkDoct={(selectedRowKeys) => checkDoctEvent(selectedRowKeys)} />
  407. </Form.Item>
  408. </TabPane>
  409. <TabPane tab="可看科室" key="1" forceRender={type == 3 && form.getFieldValue().softwareVOS[i] ? true : false}>
  410. <Form.Item
  411. name={['softwareVOS', i, 'softwareMenuIds']}
  412. >
  413. <MenuTree data={treeData} checkeds={form.getFieldValue().softwareVOS ? form.getFieldValue().softwareVOS[i] : []} checkEv={(checkedKeys) => checkTreeEvent(checkedKeys)} />
  414. </Form.Item>
  415. </TabPane>
  416. </Tabs>
  417. </Form.Item>
  418. </TabPane>
  419. )
  420. })
  421. }
  422. </Tabs>
  423. </Form.Item>
  424. <Form.Item label="所属角色" required >
  425. {
  426. orgList.map((it, i) => {
  427. return (
  428. <Form.Item
  429. key={i}
  430. style={{ display: i == index ? 'block' : 'none' }}
  431. >
  432. {index == i ?
  433. <Form.Item key={i + "b"}
  434. name={['softwareVOS', i, 'roles']}
  435. rules={[
  436. {
  437. required: true,
  438. message: '请选择所属角色',
  439. },
  440. ]}>
  441. <TreeSelect
  442. style={{ width: 300 }}
  443. showSearch={false}
  444. treeData={treeRloe}
  445. onChange={treeChange}
  446. maxTagCount={1}
  447. treeCheckable
  448. showCheckedStrategy={SHOW_PARENT}
  449. placeholder="请选择角色"
  450. />
  451. </Form.Item>
  452. : null}
  453. </Form.Item>
  454. )
  455. })
  456. }
  457. </Form.Item>
  458. <Form.Item
  459. name="status"
  460. valuePropName="checked"
  461. label="当前状态"
  462. rules={[{ required: true, message: '请选择状态' }]}
  463. >
  464. <Switch onChange={swichChange} />
  465. </Form.Item>
  466. <Form.Item wrapperCol={{ span: 6, offset: 20 }}>
  467. <Button className='but' onClick={goback}>
  468. 取消
  469. </Button>
  470. <Button type="primary" htmlType="submit">
  471. 保存
  472. </Button>
  473. </Form.Item>
  474. </Form>
  475. <Modal
  476. title="提示"
  477. okText='确定'
  478. cancelText='取消'
  479. width={400}
  480. visible={visible}
  481. onOk={handleOk}
  482. onCancel={handleCancel}
  483. >
  484. <p>您还有内容未保存,确定要退出?</p>
  485. </Modal>
  486. </div>
  487. </>
  488. )
  489. }
  490. export default AddData;