AddRole.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. import {useEffect,useState,useContext} from 'react';
  2. import { Form, Input, Checkbox, Button, Select, Tabs, InputNumber, Space, Switch, Breadcrumb, Modal } from 'antd';
  3. import MenuTree from './MenuTree';
  4. import './index.less';
  5. import RoleContext from './role-context';
  6. import apiObj from '@api/index';
  7. import backIcon from "@images/back.png";
  8. const {post,api,xPost} = apiObj;
  9. const { TabPane } = Tabs;
  10. const { Option } = Select;
  11. function AddRole(props){
  12. const [form] = Form.useForm();
  13. const { back } = props;
  14. const [isChange, setIsChange] = useState(false);
  15. const [visible, setVisible] = useState(false);
  16. const { detail } = useContext(RoleContext);
  17. function handleOk() {
  18. back()
  19. }
  20. function handleCancel() {
  21. setVisible(false)
  22. }
  23. const goback = () => {
  24. if (form.isFieldsTouched()) {
  25. setVisible(true)
  26. } else {
  27. back()
  28. }
  29. };
  30. return (
  31. <>
  32. <Breadcrumb separator="">
  33. <Breadcrumb.Item><img className='back-icon' src={backIcon} onClick={goback} alt="返回上一页"/></Breadcrumb.Item>
  34. <Breadcrumb.Item>角色管理</Breadcrumb.Item>
  35. <Breadcrumb.Separator />
  36. <Breadcrumb.Item>新增角色</Breadcrumb.Item>
  37. </Breadcrumb>
  38. <div className="add-container">
  39. <ContentForm back={goback} form={form}></ContentForm>
  40. </div>
  41. <Modal
  42. title="提示"
  43. okText='确定'
  44. cancelText='取消'
  45. width={400}
  46. visible={visible}
  47. onOk={handleOk}
  48. onCancel={handleCancel}
  49. maskClosable={false}
  50. >
  51. <p>您还有内容未保存,确定要退出?</p>
  52. </Modal>
  53. </>
  54. )
  55. }
  56. function ContentForm(props){
  57. const [treeDatas, setTreeDatas] = useState([]);
  58. const [tabDatas, setTabDatas] = useState([]);
  59. const [activeTab, setActiveTab] = useState('');
  60. const { save,detail } = useContext(RoleContext);
  61. const [sysCheckeds, setSysCheckeds] = useState();
  62. const { back, form } = props;
  63. const initialValues=detail||{
  64. status:'1'
  65. };
  66. const vilidateRules = {
  67. required: '${label}不能为空!',
  68. types: {
  69. email: '${label} is not a valid email!',
  70. number: '${label} is not a valid number!',
  71. },
  72. };
  73. //获取菜单数据,type:组织0角色1
  74. function getTreeData(){
  75. xPost(api.getUserMenuResourceTree,{type:1}).then((res)=>{
  76. if(res.data.code===200){
  77. const data = res.data.data;
  78. const treeDatas = structureTreeData(data);
  79. setTreeDatas(treeDatas);
  80. //默认选中第一个tab
  81. setTabDatas([treeDatas[0]]);
  82. setActiveTab(treeDatas[0].key);
  83. setSysCheckeds(treeDatas[0]?[treeDatas[0].key]:[]);
  84. }
  85. })
  86. }
  87. //数据转换为树形结构所需字段
  88. function structureTreeData(data){
  89. const arr = [];
  90. let obj={};
  91. data.relation ==1 || data.map((it,i)=>{
  92. obj =JSON.stringify(it.children).replace(/softwareMenuId/g,"key").replace(/menuName/g,'title');
  93. arr[i]={
  94. title:it.softwareName,
  95. key:it.softwareId,
  96. children:JSON.parse(obj)
  97. }
  98. });
  99. return arr;
  100. }
  101. //数据转换为树形结构所需字段
  102. function structureTreeData2(data) {
  103. const arr = [];
  104. let obj = {};
  105. data.map((it, i) => {
  106. if (it.relation == 1){
  107. obj = JSON.stringify(it.children).replace(/softwareMenuId/g, "key").replace(/menuName/g, 'title');
  108. arr[i] = {
  109. title: it.softwareName,
  110. key: it.softwareId,
  111. children: JSON.parse(obj)
  112. }
  113. }
  114. });
  115. return arr;
  116. }
  117. useEffect(()=>{
  118. if(detail){
  119. //编辑时权限树从详情中获取,tab数据也是
  120. const treeDatas2 = structureTreeData2(detail.loginUserMenuResourceTree);
  121. const treeDatas = structureTreeData(detail.loginUserMenuResourceTree);
  122. setTreeDatas(treeDatas);
  123. setSysCheckeds(detail.sids);
  124. setTabDatas(treeDatas2);
  125. console.log(detail);
  126. console.log(form.getFieldsValue());
  127. }else{
  128. getTreeData();
  129. }
  130. },[]);
  131. function handleSave(){
  132. form.validateFields(['name']).then((res)=>{
  133. save(form.getFieldsValue())
  134. });
  135. }
  136. //树形结构选中事件
  137. function checkTreeEvent(i,idsArr,sourceIds){
  138. const formData=form.getFieldsValue();
  139. let arr=formData.softwares;
  140. arr[i]={
  141. id:activeTab,
  142. softwareMenuIds:idsArr,
  143. softwareResourceIds:sourceIds
  144. };
  145. form.setFieldsValue({
  146. softwares:arr
  147. });
  148. }
  149. function onTabChange(activeTab){
  150. setActiveTab(activeTab.split('-')[0])
  151. }
  152. //开放系统勾选事件
  153. function softwareChange(checkedValue){
  154. let arr = [],item;
  155. setSysCheckeds(checkedValue);
  156. for(let i=0;i<checkedValue.length;i++){
  157. item=treeDatas.find((it)=>it.key===checkedValue[i]);
  158. if(item){
  159. arr.push(item);
  160. }
  161. }
  162. setTabDatas(arr);
  163. }
  164. return (
  165. <>
  166. <Form
  167. labelCol={{ span: 6 }}
  168. wrapperCol={{ span: 16 }}
  169. layout="horizontal"
  170. validateMessages={vilidateRules}
  171. initialValues={initialValues}
  172. form={form}
  173. >
  174. <Form.Item
  175. label="角色名称"
  176. name='name'
  177. required
  178. rules={[({ getFieldValue }) => ({
  179. validator(_, value) {
  180. if(!value){
  181. return Promise.reject(new Error('角色名称不能为空!'));
  182. }else if (value.length<51) {
  183. return Promise.resolve();
  184. }
  185. return Promise.reject(new Error('格式错误!'));
  186. },
  187. }),]}>
  188. <Input placeholder='请输入角色名称' autoComplete='off'/>
  189. </Form.Item>
  190. <Form.Item
  191. label="角色描述"
  192. name='remark'>
  193. <Input placeholder='请输入角色描述' autoComplete='off'/>
  194. </Form.Item>
  195. <Form.Item
  196. label="排序"
  197. name='orderNo'>
  198. <InputNumber placeholder='大于0的整数' min={0}/>
  199. </Form.Item>
  200. <Form.Item
  201. label="开放系统"
  202. rules={[{ required: true}]}>
  203. <Checkbox.Group value={sysCheckeds} onChange={softwareChange}>
  204. {
  205. treeDatas.map((it, i) => {
  206. return (
  207. <Form.Item key={it.key} noStyle>
  208. <Checkbox key={i} value={it.key}>{it.title}</Checkbox>
  209. </Form.Item>
  210. )
  211. })
  212. }
  213. </Checkbox.Group>
  214. </Form.Item>
  215. <Form.Item
  216. label="菜单权限"
  217. required>
  218. <Tabs onChange={onTabChange} type="card">
  219. {
  220. tabDatas.map((it,i)=>{
  221. return (
  222. <TabPane tab={it.title} key={it.key + "-" + i} forceRender={detail ? true : false}>
  223. <Form.Item
  224. key={i}
  225. name={['softwares', i, 'softwareMenuIds']}
  226. valuePropName='checked'
  227. getValueFromEvent={(checked)=>{
  228. return [];
  229. }} noStyle>
  230. <MenuTree data={it} checkeds={form.getFieldValue().softwares?form.getFieldValue().softwares[i]:[]} checkEv={(checkedKeys,sourceIds)=>checkTreeEvent(i,checkedKeys,sourceIds)}/>
  231. </Form.Item>
  232. <Form.Item key={i+"a"} hidden={true} name={['softwares', i, 'id']} noStyle>
  233. <Input/>
  234. </Form.Item>
  235. <Form.Item key={i+"b"} hidden={true} name={['softwares', i, 'softwareResourceIds']} noStyle>
  236. <Input/>
  237. </Form.Item>
  238. </TabPane>
  239. )
  240. })
  241. }
  242. </Tabs>
  243. </Form.Item>
  244. <Form.Item
  245. label="当前状态">
  246. <Space>
  247. <Form.Item
  248. name='status'
  249. valuePropName='checked'
  250. getValueFromEvent={(checked)=>{
  251. return +checked;
  252. }}
  253. noStyle>
  254. <Switch />
  255. </Form.Item>
  256. <span>启用</span>
  257. </Space>
  258. </Form.Item>
  259. </Form>
  260. <div className="button-box">
  261. <Button onClick={back}>取消</Button>
  262. <Button onClick={handleSave} type='primary'>保存</Button>
  263. </div>
  264. </>
  265. )
  266. }
  267. export default AddRole;