Commit 5f10a8db authored by 张烨's avatar 张烨
parents 5cef5fc3 4fa7c8e8
...@@ -501,7 +501,7 @@ const InitDataBase = props => { ...@@ -501,7 +501,7 @@ const InitDataBase = props => {
))} ))}
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item> <Form.Item wrapperCol={{ offset: 3 }}>
<div className={styles.tCenter}> <div className={styles.tCenter}>
<Space size="large" className={styles.btnBox}> <Space size="large" className={styles.btnBox}>
<Space> <Space>
......
...@@ -13,5 +13,5 @@ ...@@ -13,5 +13,5 @@
} }
.btnBox { .btnBox {
display: flex !important; display: flex !important;
justify-content: space-around; justify-content: space-between;
} }
\ No newline at end of file
import React from 'react'; import React, { useState, useEffect } from 'react';
import { Form, DatePicker, Table, Row, Col, Button } from 'antd'; import {
DatePicker,
Table,
Row,
Col,
Button,
notification,
message,
Spin,
} from 'antd';
import { SwapRightOutlined } from '@ant-design/icons';
import { Chart, Interval, Tooltip, Axis } from 'bizcharts'; import { Chart, Interval, Tooltip, Axis } from 'bizcharts';
import { DataSet } from '@antv/data-set'; import { DataSet } from '@antv/data-set';
import moment from 'moment';
import { post, PUBLISH_SERVICE } from '@/services/index';
const data = [ // const data = [
{ value: 251, name: '接口名称一', subName: '子事例一' }, // { value: 251, name: '接口名称一', subName: '子事例一' },
{ value: 1041, name: '接口名称三', subName: '子事例二' }, // { value: 1041, name: '接口名称三', subName: '子事例二' },
{ value: 610, name: '接口名称二', subName: '子事例二' }, // { value: 610, name: '接口名称二', subName: '子事例二' },
{ value: 434, name: '接口名称二', subName: '子事例四' }, // { value: 434, name: '接口名称二', subName: '子事例四' },
{ value: 335, name: '接口名称二', subName: '子事例五' }, // { value: 335, name: '接口名称二', subName: '子事例五' },
{ value: 250, name: '接口名称三', subName: '子事例二' }, // { value: 250, name: '接口名称三', subName: '子事例二' },
]; // ];
const columns = Object.keys(data[0]).map(key => ({ // const data = [];
const Demo = () => {
const [loading, setLoading] = useState(false); // 源数据
const [data0, setData0] = useState([]); // 源数据
const [pathCount, setPathCount] = useState([]); // 接口调用次数,统计数据
const [reponseTime, setReponseTime] = useState([]); // 接口调用时长,统计数据
const [scale, setScale] = useState({}); // 坐标轴别名
const [startTime, setStartTime] = useState(moment().startOf('day')); // 默认值当天0点
const [endTime, setEndTime] = useState(
moment(new Date(), 'YYYY-MM-DD HH:mm:ss'), // 默认值当前时间
);
const [tableColumns, setTableColumns] = useState([]); // 源数据
console.log(startTime.format('HH:mm:ss'));
console.log(endTime.format('HH:mm:ss'));
// 在起止时间任意一个变化后获取数据
useEffect(() => {
if (startTime && endTime) {
setLoading(true);
getData();
}
}, [startTime, endTime]);
const getData = () => {
post(`${PUBLISH_SERVICE}/LogCenter/GetOMSLog`, {
PageIndex: 0,
PageSize: 0,
DateFrom: startTime.format('YYYY-MM-DD'),
DateTo: endTime.format('YYYY-MM-DD'),
HourFrom: startTime.format('HH:mm:ss'),
HourTo: endTime.format('HH:mm:ss'),
IP: '',
Module: '',
LogType: 0,
Description: '',
LoginName: '',
UserName: '',
})
.then(res => {
if (res.code === 0) {
setData0(res.data);
dataTransforrm(res.data);
console.log(res.data);
} else {
notification.error({
message: '数据获取失败',
description: res.message,
});
}
setLoading(false);
})
.catch(err => {
message.error(err);
setLoading(false);
});
};
const dataTransforrm = data => {
data.map((item, index) => {
item.key = index;
return item;
});
const columns = Object.keys(data[0]).map(key => ({
title: key, title: key,
dataIndex: key, dataIndex: key,
key, key,
})); }));
// console.log(Object.keys(data[0])); setTableColumns(columns);
const scale = { // console.log(Object.keys(data[0]));
name: { const scale1 = {
Path: {
alias: '接口名称', // 别名 alias: '接口名称', // 别名
}, },
subName: { 响应时长: {
alias: '名称', // 别名 alias: '响应时长/ms', // 别名
}, },
}; };
const dv1 = new DataSet.View().source(data); setScale(scale1);
dv1
const dv1 = new DataSet.View().source(data);
dv1
.transform({ .transform({
type: 'aggregate', // 别名summary type: 'aggregate', // 别名summary
fields: ['name'], // 统计字段集 fields: ['Path'], // 统计字段集
operations: ['count'], // 统计操作集 operations: ['count'], // 统计操作集
as: ['计数'], // 存储字段集 as: ['计数'], // 存储字段集
groupBy: ['name'], // 分组字段集 groupBy: ['Path'], // 分组字段集
}) })
.transform({ .transform({
type: 'sort-by', type: 'sort-by',
fields: ['计数'], // 根据指定的字段集进行排序,与lodash的sortBy行为一致 fields: ['计数'], // 根据指定的字段集进行排序,与lodash的sortBy行为一致
order: 'DESC', // 默认为 ASC,DESC 则为逆序 order: 'DESC', // 默认为 ASC,DESC 则为逆序
}); });
console.log(dv1.rows); console.log(dv1.rows);
setPathCount(dv1.rows.slice(0, 20));
const dv2 = new DataSet.View().source(data); const dv2 = new DataSet.View().source(data);
dv2 dv2
.transform({ .transform({
type: 'aggregate', // 别名summary type: 'aggregate', // 别名summary
fields: ['value'], // 统计字段集 fields: ['ConsumerTime'], // 统计字段集
operations: ['mean'], // 统计操作集 operations: ['mean'], // 统计操作集
as: ['平均值'], // 存储字段集 as: ['响应时长'], // 存储字段集
groupBy: ['subName'], // 分组字段集 groupBy: ['Path'], // 分组字段集
}) })
.transform({ .transform({
type: 'sort-by', type: 'sort-by',
fields: ['平均值'], // 根据指定的字段集进行排序,与lodash的sortBy行为一致 fields: ['响应时长'], // 根据指定的字段集进行排序,与lodash的sortBy行为一致
order: 'DESC', // 默认为 ASC,DESC 则为逆序 order: 'DESC', // 默认为 ASC,DESC 则为逆序
}); });
console.log(dv2.rows); console.log(dv2.rows);
setReponseTime(dv2.rows.slice(0, 20));
};
// DatePicker改变点击确定时
const changeStartTime = time => {
setStartTime(time);
};
const changeEndTime = time => {
setEndTime(time);
};
// 近1/6/12/24小时
const setTime = time => {
setEndTime(moment(new Date(), 'YYYY-MM-DD HH:mm:ss'));
setStartTime(
moment(
new Date(new Date().getTime() - time * 60 * 60 * 1000),
'YYYY-MM-DD HH:mm:ss',
),
);
};
function Demo() {
const [timeForm] = Form.useForm();
return ( return (
<> <>
<Form style={{ padding: '0px 6px' }} form={timeForm}>
<Row> <Row>
<Col span={4}> <div style={{ lineHeight: 2 }}>时间:</div>
<Form.Item name="startTime" label="起始时间"> <DatePicker
<DatePicker showTime format="YYYY-MM-DD HH:mm:ss" /> showTime
</Form.Item> format="YYYY-MM-DD HH:mm:ss"
</Col> placeholder="起始时间"
<Col span={4}> value={startTime}
<Form.Item name="endTime" label="结束时间"> onChange={changeStartTime}
<DatePicker showTime format="YYYY-MM-DD HH:mm:ss" /> allowClear={false}
</Form.Item> />
</Col> <SwapRightOutlined style={{ lineHeight: 2 }} />
<DatePicker
showTime
format="YYYY-MM-DD HH:mm:ss"
placeholder="结束时间"
value={endTime}
onChange={changeEndTime}
style={{ marginRight: '10px' }}
allowClear={false}
/>
<Col span={12}> <Col span={12}>
<Button <Button onClick={() => setTime(1)}>1小时</Button>
onClick={() => { <Button onClick={() => setTime(6)}>6小时</Button>
// timeForm.setFieldsValue({ startTime: '2020-11-12 12:12:12' }); <Button onClick={() => setTime(12)}>12小时</Button>
}} <Button onClick={() => setTime(24)}>1</Button>
> <Button onClick={() => setTime(24 * 7)}>1</Button>
1小时
</Button>
<Button>6小时</Button>
<Button>12小时</Button>
<Button>1</Button>
<Button>1</Button>
</Col> </Col>
{/* <div style={{ lineHeight: 2 }}>类型:</div> */}
</Row> </Row>
</Form> <Spin spinning={loading} tip="loading">
<Row style={{ padding: '10px' }}> <Row style={{ padding: '10px' }}>
<Col span={8}> <Col span={12}>
<Chart <Chart
height={300} height={340}
width={400} width={400}
autoFit autoFit
data={dv1.rows} data={pathCount}
interactions={['active-region']} interactions={['active-region']}
padding="auto" padding="auto"
scale={scale} scale={scale}
> >
<Axis name="name" title /> <Axis
name="Path"
label="null"
title={{ offset: 20, position: 'end' }}
/>
<Axis name="计数" title /> <Axis name="计数" title />
<Interval position="name*计数" /> <Interval position="Path*计数" />
<Tooltip shared /> <Tooltip shared />
</Chart> </Chart>
</Col> </Col>
<Col span={8}> <Col span={12}>
<Chart <Chart
height={300} height={340}
width={400} width={400}
autoFit autoFit
data={dv2.rows} data={reponseTime}
interactions={['active-region']} interactions={['active-region']}
padding="auto" padding="auto"
scale={scale} scale={scale}
> >
<Axis name="subName" title /> <Axis
<Axis name="平均值" title /> name="Path"
<Interval position="subName*平均值" /> label="null"
title={{ offset: 20, position: 'end' }}
/>
<Axis name="响应时长" title />
<Interval position="Path*响应时长" />
<Tooltip shared /> <Tooltip shared />
</Chart> </Chart>
</Col> </Col>
...@@ -125,22 +232,23 @@ function Demo() { ...@@ -125,22 +232,23 @@ function Demo() {
<Table <Table
size="small" size="small"
bordered bordered
columns={columns || []} columns={tableColumns || []}
dataSource={data} dataSource={data0}
// loading={tableLoading} // loading={tableLoading}
scroll={{ x: 'max-content' }} scroll={{ x: 'max-content' }}
pagination={{ pagination={{
showTotal: (total, range) => showTotal: (total, range) =>
`第${range[0]}-${range[1]} 条/共 ${total} 条`, `第${range[0]}-${range[1]} 条/共 ${total} 条`,
pageSizeOptions: [10, 20, 50, 100], pageSizeOptions: [10, 20, 50, 100],
defaultPageSize: 20, defaultPageSize: 10,
showQuickJumper: true, showQuickJumper: true,
showSizeChanger: true, showSizeChanger: true,
}} }}
/> />
</Spin>
</> </>
); );
} };
export default Demo; export default Demo;
// dv.transform({ // dv.transform({
// type: 'aggregate', // 别名summary // type: 'aggregate', // 别名summary
......
...@@ -22,7 +22,7 @@ const SiteConfig = props => { ...@@ -22,7 +22,7 @@ const SiteConfig = props => {
const layout = { const layout = {
layout: 'horizontal', layout: 'horizontal',
labelCol: { span: 7 }, labelCol: { span: 7 },
wrapperCol: { span: 6 }, wrapperCol: { span: 8 },
}; };
useEffect(() => { useEffect(() => {
console.log(miniTitle, 'miniTitle'); console.log(miniTitle, 'miniTitle');
...@@ -37,8 +37,9 @@ const SiteConfig = props => { ...@@ -37,8 +37,9 @@ const SiteConfig = props => {
}) })
.then(res => { .then(res => {
setLoading(false); setLoading(false);
let obj = { ...form.getFieldsValue() }; console.log(res.shortcutIcon);
let arr = Object.keys({ ...form.getFieldsValue() }); let obj = {};
let arr = Object.keys(form.getFieldsValue());
arr.map(k => { arr.map(k => {
obj[k] = res[k]; obj[k] = res[k];
}); });
...@@ -88,7 +89,7 @@ const SiteConfig = props => { ...@@ -88,7 +89,7 @@ const SiteConfig = props => {
}; };
return ( return (
<Spin spinning={loading} tip="loading..."> <Spin spinning={loading} tip="loading...">
<div style={{ minHeight: 'calc(100vh - 172px)', marginTop: '20px' }}> <div style={{ minHeight: 'calc(100vh - 192px)', marginTop: '20px' }}>
<Form form={form} {...layout}> <Form form={form} {...layout}>
<Item <Item
label="应用名称:" label="应用名称:"
...@@ -102,7 +103,6 @@ const SiteConfig = props => { ...@@ -102,7 +103,6 @@ const SiteConfig = props => {
> >
<Input placeholder="请输入应用名称" allowClear /> <Input placeholder="请输入应用名称" allowClear />
</Item> </Item>
<Item <Item
label="系统图标:" label="系统图标:"
name="shortcutIcon" name="shortcutIcon"
...@@ -115,10 +115,10 @@ const SiteConfig = props => { ...@@ -115,10 +115,10 @@ const SiteConfig = props => {
> >
<Input placeholder="请输入系统图标名称" allowClear /> <Input placeholder="请输入系统图标名称" allowClear />
</Item> </Item>
<Item label="系统图标预览:" name="shortcutIcon">
<Item label="系统图标预览:">
<PicturesWall /> <PicturesWall />
</Item> </Item>
<Item <Item
label="登陆页面:" label="登陆页面:"
name="loginTemplate" name="loginTemplate"
......
...@@ -29,11 +29,11 @@ const MobileConfigPage = props => { ...@@ -29,11 +29,11 @@ const MobileConfigPage = props => {
}); });
}, [flag]); }, [flag]);
useEffect(() => { useEffect(() => {
getMiniAppModuleTree({ // getMiniAppModuleTree({
userMode: 'super', // userMode: 'super',
}).then(res => { // }).then(res => {
console.log(res); // console.log(res);
}); // });
}, []); }, []);
// 修改选中的tab // 修改选中的tab
const handleChange = key => { const handleChange = key => {
......
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Form, Input } from 'antd'; import { Form, Input, Button, Row, Col } from 'antd';
import styles from './addForm.less';
import PicturesWall from '@/components/Upload/index';
const { Item } = Form; const { Item } = Form;
const AddForm = props => { const AddForm = props => {
const {} = props; const { submitCallback, nodeType, nodeObj, addType } = props;
// const [type, setType] = useState(2);
const [form] = Form.useForm(); const [form] = Form.useForm();
const [otherForm] = Form.useForm();
const layout = { const layout = {
layout: '', layout: 'horizontal',
labelCol: { span: 4, offset: 1 },
wrapperCol: { span: 16 },
};
const submit = () => {
if (addType === 1 || addType === 2) {
let obj = form.getFieldsValue();
submitCallback(obj, nodeObj);
}
if (addType === 3 || addType === 4) {
let obj = otherForm.getFieldsValue();
submitCallback(obj, nodeObj);
}
}; };
return ( return (
<Form form={form} {...layout}> <div>
<Item label="分组名称"> {(addType === 1 || addType === 2) && (
<Form form={form} {...layout} className={styles.formStyle}>
<Item label="分组名称" name="menuName">
<Input /> <Input />
</Item> </Item>
<Item label="分组别名"> <Item label="分组别名" name="shortName">
<Input /> <Input />
</Item> </Item>
<Item label="在线图标"> {addType === 1 && (
<Item label="在线图标" name="imageUrl">
<PicturesWall />
</Item>
)}
{addType === 1 && (
<Item label="离线图标" name="offlineImgUrl">
<PicturesWall />
</Item>
)}
{addType === 2 && (
<Item label="分组图标" name="imageUrl">
<PicturesWall />
</Item>
)}
<Item label="功能参数" name="funParam">
<Input /> <Input />
</Item> </Item>
<Item label="离线图标"> <Item wrapperCol={{ offset: 5 }} style={{ marginTop: '40px' }}>
<Button type="primary" onClick={() => submit()}>
提交
</Button>
</Item>
</Form>
)}
{(addType === 3 || addType === 4) && (
<Form form={otherForm} {...layout} className={styles.formStyle}>
<Item label="菜单名称" name="menuName">
<Input /> <Input />
</Item> </Item>
<Item label="功能参数"> <Item label="菜单别名" name="shortName">
<Input /> <Input />
</Item> </Item>
{addType === 3 && (
<Item label="在线图标" name="imageUrl">
<PicturesWall />
</Item>
)}
{addType === 3 && (
<Item label="离线图标" name="offlineImgUrl">
{/* {otherForm.getFieldsValue().offlineImgUrl && <PicturesWall />} */}
<PicturesWall />
</Item>
)}
{addType === 4 && (
<Item label="菜单图标" name="imageUrl">
<PicturesWall />
</Item>
)}
<Item label="功能路径" name="pageUrl">
<Input />
</Item>
<Item label="功能参数" name="funParam">
<Input />
</Item>
<Item wrapperCol={{ offset: 5 }} style={{ marginTop: '40px' }}>
<Button type="primary" onClick={() => submit()}>
提交
</Button>
</Item>
</Form> </Form>
)}
</div>
); );
}; };
export default AddForm; export default AddForm;
import React, { useState, useEffect, useCallback } from 'react';
import {
message,
notification,
Form,
Spin,
Tree,
Tooltip,
Modal,
Input,
Button,
} from 'antd';
import {
FileAddTwoTone,
FolderAddTwoTone,
EditTwoTone,
DeleteTwoTone,
FolderOpenOutlined,
FileOutlined,
} from '@ant-design/icons';
import {
getTree,
addMenuApi,
addMenuGroupApi,
submitMenuInfo,
getRoleList,
getMenuInfo,
deleteMenuApi,
} from '@/services/appConfig/api';
import ListCardItem from '@/pages/orgnazation/listCardItem';
import styles from './LeftPart.less';
import PicturesWall from '@/components/Upload/index';
const AppMenu = () => {
const [treeLoading, setTreeLoading] = useState(true);
const [treeData, setTreeData] = useState([]); // 菜单树
const [treeState, setTreeState] = useState(true);
const [nodeType, setNodeType] = useState(1); // 根据节点类型渲染不同的编辑表单item,0-0一级菜单,0-0-0二级,0-0-0-0三级
const [rolelist, setRolelist] = useState([]);
const [roleValueList, setRoleValueList] = useState({});
const [menuID, setMenuID] = useState('');
const [menuTitle, setMenuTitle] = useState('菜单管理');
const [menuLabel, setMenuLabel] = useState('在线图标');
const [addMenuVisible, setAddMenuVisible] = useState(false);
const [addMenuGroupVisible, setAddMenuGroupVisible] = useState(false);
const [tipVisible, setTipVisible] = useState(false);
const [deleteMenuVisible, setDeleteMenuVisible] = useState(false);
const [addMenuForm] = Form.useForm();
const [editMenuForm] = Form.useForm();
const [addMenuGroupForm] = Form.useForm();
const getRoleValueCallback = useCallback((value, index) => {
roleValueList[index] = value;
setRoleValueList({ ...roleValueList });
}, []);
const [flag, setFlag] = useState(1); // 刷新标记
const [saveid, setSaveid] = useState(''); // 保存选择的ID
const [submitLoading, setSubmitLoading] = useState(false);
// 获取菜单树
useEffect(() => {
updateTrees();
}, [flag]);
const updateTrees = () => {
setTreeLoading(true);
getTree()
.then(res => {
if (res.length > 0) {
setTreeLoading(false);
const result = res[0].children[0].children[2].children;
setTreeData(result);
console.log(result);
// 第一次加载,默认选择第一个组织
if (treeState) {
onSelect([result[0].menuID], false);
setTreeState(false);
}
}
})
.catch(err => {
setTreeLoading(false);
message.error(err);
});
};
// 获取角色列表
useEffect(() => {
getRoleList()
.then(res => {
if (res && res.list) {
setRolelist(res.list);
} else {
notification.error({
message: '获取失败',
description: res.message,
});
}
})
.catch(err => {
message.error(err);
});
}, []);
// 渲染菜单树
const mapTree = menu => {
const haveChildren =
Array.isArray(menu.children) && menu.children.length > 0;
return {
title: (
<>
<span>{menu.text}</span>
<div className={styles.iconWraper1}>
{menu.menuType === 'MiniAppMenuGroup' && (
<>
<Tooltip title="添加菜单组">
<FolderAddTwoTone
onClick={() => addMenuGroup(menu, '分组图标')}
/>
</Tooltip>
</>
)}
{menu.menuType === 'MiniAppMenuGroupTwo' && (
<>
<Tooltip title="添加菜单">
<FileAddTwoTone onClick={() => addMenu(menu)} />
</Tooltip>
</>
)}
<Tooltip title="删除菜单">
<DeleteTwoTone onClick={() => deleteMenu(menu)} />
</Tooltip>
</div>
</>
),
key: menu.menuID,
// icon: menu.leaf ? <FileOutlined /> : <FolderOpenOutlined />,
// 判断它是否存在子集,若果存在就进行再次进行遍历操作,知道不存在子集便对其他的元素进行操作
children: haveChildren ? menu.children.map(i => mapTree(i)) : [],
};
};
// 获取当前菜单详细
const onSelect = (props, e) => {
// e.node.pos节点类型,根据这个渲染不同的编辑表单item,0-x一级菜单,0-0-x二级,0-0-0-x三级
console.log(props, e);
if (e) {
if (e.node.pos.lastIndexOf('-') === 1) {
setNodeType(1);
} else if (e.node.pos.lastIndexOf('-') === 3) {
setNodeType(2);
} else {
setNodeType(3);
}
}
if (props[0]) {
setMenuID(props[0]);
setSaveid(props[0]);
} else {
setMenuID(saveid);
}
// setMenuID(props[0]);
getMenuInfo(props[0])
.then(res => {
if (res.success) {
editMenuForm.setFieldsValue({
menuName: res.menuName,
shortName: res.menuShortName,
imageUrl: res.imageUrl,
pageUrl: res.pageUrl,
offlineImgUrl: res.offlineImgUrl,
funParam: res.funParam,
relatedRoleList: res.relatedRoleList || '',
});
}
})
.catch(err => {
message.error(err);
});
};
// 左侧目录树相关操作
const addMenu = menu => {
setAddMenuVisible(true);
setMenuTitle(`在${menu.text}下添加功能菜单`);
console.log(menu, 'enu');
setMenuID(menu.menuID);
addMenuForm.setFieldsValue({
menuName: '',
shortName: '',
imageUrl: '',
pageUrl: '',
funParam: '',
});
};
const addMenuGroup = (menu, label) => {
setAddMenuGroupVisible(true);
setMenuTitle(`在${menu.text}下添加菜单组`);
setMenuLabel(label);
addMenuGroupForm.setFieldsValue({
menuName: '',
shortName: '',
imageUrl: '',
offlineImgUrl: '',
funParam: '',
});
};
const editMenu = menu => {
setAddMenuVisible(true);
setMenuTitle(`编辑${menu.text}`);
setMenuID(menu.menuID);
getMenuInfo(menu.menuID)
.then(res => {
if (res.success) {
addMenuForm.setFieldsValue({
menuName: res.menuName,
shortName: res.menuShortName,
imageUrl: res.imageUrl,
pageUrl: res.pageUrl,
funParam: res.funParam,
relatedRoleList: res.relatedRoleList || [],
});
} else {
notification.error({
message: '获取失败',
description: res.message,
});
}
})
.catch(err => {
message.error(err);
});
};
// const editMenuGroup = (menu, label) => {
// setAddMenuGroupVisible(true);
// setMenuTitle(`编辑${menu.text}`);
// setMenuID(menu.menuID);
// setMenuLabel(label);
// getMenuInfo(menu.menuID)
// .then(res => {
// if (res.success) {
// addMenuGroupForm.setFieldsValue({
// menuName: res.menuName,
// shortName: res.menuShortName,
// imageUrl: res.imageUrl,
// pageUrl: res.pageUrl,
// offlineImgUrl: res.offlineImgUrl,
// funParam: res.funParam,
// relatedRoleList: res.relatedRoleList || [],
// });
// } else {
// notification.error({
// message: '获取失败',
// description: res.message,
// });
// }
// })
// .catch(err => {
// message.error(err);
// });
// };
const deleteMenu = menu => {
setDeleteMenuVisible(true);
setMenuTitle(`删除菜单${menu.text}`);
setMenuID(menu.menuID);
};
// 提交添加菜单
const submitAddMenu = () => {
console.log(menuID);
let menuName = addMenuForm.getFieldValue('menuName');
let shortName = addMenuForm.getFieldValue('shortName');
let imageUrl = addMenuForm.getFieldValue('imageUrl');
let pageUrl = addMenuForm.getFieldValue('pageUrl');
let funParam = addMenuForm.getFieldValue('funParam');
if (menuName && shortName && imageUrl && pageUrl) {
addMenuApi(menuID, menuName, shortName, imageUrl, pageUrl, funParam)
.then(res => {
if (res.success) {
setAddMenuVisible(false);
notification.success({
message: '提交成功',
});
updateTrees();
} else {
notification.error({
message: '提交失败',
description: res.message,
});
}
})
.catch(err => {
message.error(err);
});
} else {
setTipVisible(true);
}
};
// 提交添加菜单组
const submitAddMenuGroup = () => {
let menuName = addMenuGroupForm.getFieldValue('menuName');
let shortName = addMenuGroupForm.getFieldValue('shortName');
let imageUrl = addMenuGroupForm.getFieldValue('imageUrl');
let offlineImgUrl = addMenuGroupForm.getFieldValue('offlineImgUrl');
let funParam = addMenuGroupForm.getFieldValue('funParam');
if (menuName && shortName && imageUrl && offlineImgUrl) {
addMenuGroupApi(
menuID,
menuName,
shortName,
imageUrl,
offlineImgUrl,
funParam,
)
.then(res => {
if (res.success) {
setAddMenuGroupVisible(false);
notification.success({
message: '提交成功',
});
updateTrees();
} else {
notification.error({
message: '提交失败',
description: res.message,
});
}
})
.catch(err => {
message.error(err);
});
} else {
setTipVisible(true);
}
};
// 提交-编辑菜单
const submitEditMenu = () => {
let menuName = editMenuForm.getFieldValue('menuName');
let shortName = editMenuForm.getFieldValue('shortName');
let imageUrl = editMenuForm.getFieldValue('imageUrl');
let offlineImgUrl = editMenuForm.getFieldValue('offlineImgUrl') || '';
let pageUrl = editMenuForm.getFieldValue('pageUrl') || '';
let funParam = editMenuForm.getFieldValue('funParam') || '';
let relatedRoleList = editMenuForm.getFieldValue('funParam') || '';
const params = {
menuID,
menuName,
shortName,
imageUrl,
offlineImgUrl,
pageUrl,
funParam,
relatedRoleList,
};
// 根据节点类型,加一层判断,必填项全部不为空时才能提交
if (nodeType === 1) {
if (menuName && shortName && imageUrl && offlineImgUrl) {
submitMenu(params);
} else {
setTipVisible(true);
}
} else if (nodeType === 2) {
if (menuName && shortName && imageUrl) {
submitMenu(params);
} else {
setTipVisible(true);
}
} else if (nodeType === 3) {
if (menuName && shortName && imageUrl && pageUrl) {
submitMenu(params);
} else {
setTipVisible(true);
}
}
};
const submitMenu = params => {
setSubmitLoading(true);
submitMenuInfo(params)
.then(res => {
setSubmitLoading(false);
if (res.success) {
setFlag(flag + 1);
notification.success({
message: '提交成功',
});
} else {
notification.error({
message: '获取失败',
description: res.message,
});
}
})
.catch(err => {
setSubmitLoading(false);
message.error(err);
});
};
// 提交删除菜单
const submitDeleteMenu = () => {
deleteMenuApi(menuID)
.then(res => {
if (res.success) {
setDeleteMenuVisible(false);
notification.success({
message: '删除成功',
});
updateTrees();
} else {
notification.error({
message: '删除失败',
description: res.message,
});
}
})
.catch(err => {
setTreeLoading(false);
message.error(err);
});
};
return (
<div className={styles.contentContainer}>
<div className={styles.menuContainer}>
<div style={{ padding: '10px 10px 0 16px' }}>
菜单列表
<Tooltip title="添加功能菜单">
<FileAddTwoTone
style={{
fontSize: '18px',
float: 'right',
margin: '4px 4px 0px 12px',
color: '#1890FF',
}}
onClick={() => addMenu({ text: '根目录', menuID: -1 })}
/>
</Tooltip>
<Tooltip title="添加菜单组">
<FolderAddTwoTone
style={{
fontSize: '18px',
float: 'right',
marginTop: '4px',
}}
onClick={() =>
addMenuGroup({ text: '根目录', menuID: -1 }, '在线图标')
}
/>
</Tooltip>
</div>
{treeData.length > 0 && (
<Spin spinning={treeLoading} tip="loading...">
<Tree
showIcon="true"
showLine={{ showLeafIcon: false }}
defaultExpandAll="true"
selectedKeys={[menuID]}
onSelect={onSelect}
autoExpandParent
expandedKeys={[menuID]}
treeData={treeData.map(t => mapTree(t))}
/>
</Spin>
)}
</div>
<div className={styles.editContainer}>
<Form
form={editMenuForm}
labelCol={{ span: 4 }}
wrapperCol={{ span: 19 }}
>
<Form.Item
name="menuName"
label="菜单名称"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入菜单名称" />
</Form.Item>
<Form.Item
name="shortName"
label="菜单别名"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入菜单别名" />
</Form.Item>
<Form.Item
name="imageUrl"
label="菜单图标"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入菜单图标" />
</Form.Item>
<Form.Item label="图标预览">
<PicturesWall maxLen={1} />
</Form.Item>
{nodeType === 1 && (
<>
<Form.Item
name="offlineImgUrl"
label="离线图标"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入离线图标" />
</Form.Item>
<Form.Item label="图标预览">
<PicturesWall maxLen={1} />
</Form.Item>
</>
)}
{nodeType === 3 && (
<>
<Form.Item
name="pageUrl"
label="功能路径"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入功能路径" />
</Form.Item>
</>
)}
<Form.Item name="funParam" label="功能参数">
<Input placeholder="请输入功能参数" />
</Form.Item>
<Form.Item wrapperCol={{ offset: 12 }}>
<Button
key="back"
type="primary"
onClick={() => submitEditMenu()}
loading={submitLoading}
>
提交
</Button>
</Form.Item>
</Form>
</div>
<div className={styles.previewContainer}>关联角色</div>
{/* 必填项提示 */}
<Modal
title="提示"
visible={tipVisible}
onCancel={() => setTipVisible(false)}
width="300px"
styles={{ zIndex: 999999 }}
centered
footer={[
<Button
key="back"
type="primary"
onClick={() => setTipVisible(false)}
>
关闭
</Button>,
]}
>
<p>
标记<span className={styles.redText}>*</span>的为必填项
</p>
</Modal>
{/* 添加菜单 */}
<Modal
title={menuTitle}
visible={addMenuVisible}
onOk={submitAddMenu}
onCancel={() => setAddMenuVisible(false)}
okText="确认"
cancelText="取消"
centered
>
<Form form={addMenuForm} labelCol={{ span: 4 }}>
<Form.Item
name="menuName"
label="菜单名称"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入菜单名称" />
</Form.Item>
<Form.Item
name="shortName"
label="菜单别名"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入菜单别名" />
</Form.Item>
<Form.Item
name="imageUrl"
label="菜单图标"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入菜单图标" />
</Form.Item>
<Form.Item
name="pageUrl"
label="功能路径"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入菜单图标" />
</Form.Item>
<Form.Item label="图标预览">
<PicturesWall maxLen={1} />
</Form.Item>
<Form.Item name="funParam" label="功能参数">
<Input placeholder="请输入功能参数" />
</Form.Item>
</Form>
</Modal>
{/* 添加菜单组 */}
<Modal
title={menuTitle}
visible={addMenuGroupVisible}
onOk={submitAddMenuGroup}
onCancel={() => setAddMenuGroupVisible(false)}
okText="确认"
cancelText="取消"
centered
>
<Form form={addMenuGroupForm} labelCol={{ span: 4 }}>
<Form.Item
name="menuName"
label="分组名称"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入分组名称" />
</Form.Item>
<Form.Item
name="shortName"
label="分组别名"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入分组别名" />
</Form.Item>
<Form.Item
name="imageUrl"
label={menuLabel}
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入菜单图标" />
</Form.Item>
<Form.Item label="图标预览">
<PicturesWall maxLen={1} />
</Form.Item>
{/* 添加菜单组,label名称为在线图标才有离线图标 */}
{menuLabel === '在线图标' && (
<Form.Item
name="offlineImgUrl"
label="离线图标"
rules={[{ required: true, message: '不能为空' }]}
>
<Input placeholder="请输入离线图标" />
</Form.Item>
)}
<Form.Item label="图标预览">
<PicturesWall maxLen={1} />
</Form.Item>
<Form.Item name="funParam" label="功能参数">
<Input placeholder="请输入功能参数" />
</Form.Item>
</Form>
</Modal>
{/* 删除菜单 */}
<Modal
title={menuTitle}
visible={deleteMenuVisible}
onOk={submitDeleteMenu}
onCancel={() => setDeleteMenuVisible(false)}
okText="确认"
cancelText="取消"
centered
>
<span>确定删除?</span>
</Modal>
</div>
);
};
export default AppMenu;
.contentContainer{
// min-height: calc(100vh - 48px);
overflow-x: auto;
display: flex;
.menuContainer{
min-width: 300px;
border:2px solid #eee;
min-height:calc(100vh - 172px);
overflow-y:auto;
.ant-tree-list{
padding: 10px;
height:calc(100vh - 330px);
.ant-tree-switcher{
line-height: 1;
color:#1890FF;
}
.ant-tree-iconEle{
line-height: 1.2;
color:#1890FF;
}
}
}
.editContainer{
margin-left: 12px;
flex: 1;
padding: 16px;
float: left;
min-width: 500px;
border:2px solid #eee;
.ant-table-pagination-right{
padding-right: 12px;
}
}
.previewContainer{
margin-left: 12px;
// flex: 1;
float: left;
min-width: 700px;
border:2px solid #eee;
.ant-table-pagination-right{
padding-right: 12px;
}
}
.ant-tree-treenode{
width: 100% !important;
.ant-tree-node-content-wrapper{
display: inline-block;
width: 100%;
}
.iconWraper1{
float: right;
span{
display: none;
}
}
}
.ant-tree-treenode:hover{
.iconWraper1>span{
margin-left: 12px;
font-size: 18px;
display: inline-block;
}
}
}
.redText{
color: red;
cursor: pointer;
}
\ No newline at end of file
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import ProCard from '@ant-design/pro-card'; import ProCard from '@ant-design/pro-card';
import AddForm from './AddForm'; import MiniMenu from './miniMenu';
import LeftPart from './LeftPart';
const MenuConfig = props => { const MenuConfig = props => {
const [flag, setFlag] = useState(1); const [flag, setFlag] = useState(1);
return ( return (
<div split="vertical"> <div split="vertical">
<LeftPart /> <MiniMenu />
{/* <ProCard><AddForm /></ProCard> */}
</div> </div>
); );
}; };
......
.formStyle{
margin-bottom: 40px;
}
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { Form, Input, Button, Row, Col } from 'antd';
import styles from './addForm.less';
import PicturesWall from '@/components/Upload/index';
const { Item } = Form;
const EditForm = props => {
const { submitCallback, nodeType, info } = props;
const [form] = Form.useForm();
const [otherForm] = Form.useForm();
console.log(info);
const layout = {
layout: 'horizontal',
labelCol: { span: 4, offset: 1 },
wrapperCol: { span: 16 },
};
// 回显表单
useEffect(() => {
form.resetFields();
otherForm.resetFields();
}, [info]);
useEffect(() => {
if (nodeType === 1 || nodeType === 2) {
let arr = Object.keys(form.getFieldsValue());
let obj = {};
arr.map(i => {
obj[i] = info[i];
});
form.setFieldsValue({ ...obj, shortName: info.menuShortName });
}
if (nodeType === 3 || nodeType === 4) {
let arr = Object.keys(otherForm.getFieldsValue());
let obj = {};
arr.map(i => {
obj[i] = info[i];
});
otherForm.setFieldsValue({ ...obj, shortName: info.menuShortName });
}
}, [info]);
const submit = () => {
if (nodeType === 1 || nodeType === 2) {
let obj = form.getFieldsValue();
console.log(obj, '1,2');
submitCallback(obj);
}
if (nodeType === 3 || nodeType === 4) {
let obj = otherForm.getFieldsValue();
console.log(obj, '3,4');
submitCallback(obj);
}
};
return (
<div>
{(nodeType === 1 || nodeType === 2) && (
<Form form={form} {...layout} className={styles.formStyle}>
<Item label="分组名称" name="menuName">
<Input />
</Item>
<Item label="分组别名" name="shortName">
<Input />
</Item>
{nodeType === 1 && (
<Item label="在线图标" name="imageUrl">
<PicturesWall />
</Item>
)}
{nodeType === 1 && (
<Item label="离线图标" name="offlineImgUrl">
<PicturesWall />
</Item>
)}
{nodeType === 2 && (
<Item label="分组图标" name="imageUrl">
<PicturesWall />
</Item>
)}
<Item label="功能参数" name="funParam">
<Input />
</Item>
<Item wrapperCol={{ offset: 5 }} style={{ marginTop: '40px' }}>
<Button type="primary" onClick={() => submit()}>
提交
</Button>
</Item>
</Form>
)}
{(nodeType === 3 || nodeType === 4) && (
<Form form={otherForm} {...layout} className={styles.formStyle}>
<Item label="菜单名称" name="menuName">
<Input />
</Item>
<Item label="菜单别名" name="shortName">
<Input />
</Item>
{nodeType === 3 && (
<Item label="在线图标" name="imageUrl">
<PicturesWall />
</Item>
)}
{nodeType === 3 && (
<Item label="离线图标" name="offlineImgUrl">
{/* {otherForm.getFieldsValue().offlineImgUrl && <PicturesWall />} */}
<PicturesWall />
</Item>
)}
{nodeType === 4 && (
<Item label="菜单图标" name="imageUrl">
<PicturesWall />
</Item>
)}
<Item label="功能路径" name="pageUrl">
<Input />
</Item>
<Item label="功能参数" name="funParam">
<Input />
</Item>
<Item wrapperCol={{ offset: 5 }} style={{ marginTop: '40px' }}>
<Button type="primary" onClick={() => submit()}>
提交
</Button>
</Item>
</Form>
)}
</div>
);
};
export default EditForm;
import React, { useEffect, useState } from 'react';
import {
message,
notification,
Popconfirm,
Form,
Tree,
Tooltip,
Modal,
Input,
Button,
Spin,
} from 'antd';
import {
FileAddTwoTone,
FolderAddTwoTone,
FolderFilled,
FileOutlined,
DeleteTwoTone,
} from '@ant-design/icons';
import PicturesWall from '@/components/Upload/index';
import classnames from 'classnames';
import {
miniAppSiteTree,
getMiniAppModuleTree,
addMenu,
getMenuInfo,
deleteMenu,
editMenu,
} from '@/services/mobileConfig/api';
import styles from './miniMenu.less';
import AddForm from './AddForm';
import EditForm from './editForm';
const MiniMenu = props => {
const [flag, setFlag] = useState(1); // 刷新标志
const [treeFlage, setTreeFlag] = useState(true);
const [treeData, setTreeData] = useState([]); // 树的数据
const [loading, setLoading] = useState(false); // 加载
const [menuID, setMenuID] = useState(''); // 选中的树ID
const [saveID, setSaveID] = useState(''); // 保存选择的树id
const [nodeType, setNodeType] = useState(''); // 选中的节点类型
const [info, setInfo] = useState({});
const [addVisible, setAddVisible] = useState(false); // 新增弹窗
const [addTwoVisible, setAddTwoVisible] = useState(false); // 编辑弹窗
const [addFlag, setAddFlag] = useState('root'); // 设置新增标志
const [nodeObj, setNodeObj] = useState({});
const [addType, setAddType] = useState(''); // 添加下级类型
// 获取菜单树
useEffect(() => {
updateTrees();
}, [flag]);
// 获取菜单信息
useEffect(() => {
getInfo();
}, [menuID]);
// 更新树
const updateTrees = () => {
setLoading(true);
miniAppSiteTree({
_version: 9999,
_dc: new Date().getTime(),
node: -2,
userMode: 'super',
select: '',
})
.then(res => {
if (res.length > 0) {
setLoading(false);
const result = res[0].children[0].children[2].children;
setTreeData(result);
console.log(result);
// 第一次加载,默认选择第一个组织
if (treeFlage) {
handleSelect([result[0].menuID], false);
setTreeFlag(false);
}
}
})
.catch(err => {
setLoading(false);
message.error(err);
});
};
// 处理数据
const mapTree = val => {
const obj = { ...val };
const hasChild = obj.children.length > 0;
return {
title: (
<div className={styles.title}>
<div>{obj.text}</div>
<div className={styles.tip}>
{obj.menuType === 'MiniAppMenuGroup' && (
<Tooltip title="新增菜单组" className={styles.fs}>
<FolderAddTwoTone onClick={() => addMenuGroupTip(obj)} />
</Tooltip>
)}
{obj.menuType === 'MiniAppMenuGroupTwo' && (
<Tooltip title="新增功能菜单" className={styles.fs}>
<FileAddTwoTone onClick={() => addMenuTip(obj)} />
</Tooltip>
)}
<Popconfirm
cancelText="取消"
okText="确定"
title={`确定删除${obj.text}?`}
onConfirm={() => deleteMenuTip(obj)}
placement="right"
>
<Tooltip title="删除菜单" className={styles.fs}>
<DeleteTwoTone />
</Tooltip>
</Popconfirm>
</div>
</div>
),
key: obj.menuID,
icon:
obj.menuType !== 'MiniAppMenuThree' &&
obj.menuType !== 'MiniAppMenu' ? (
<FolderFilled />
) : (
<FileOutlined />
),
menuType: obj.menuType,
children: hasChild ? obj.children.map(i => mapTree(i)) : [],
};
};
// 树的点击事件
const handleSelect = (prop, treeNode) => {
console.log(prop, treeNode);
if (treeNode) {
const {
node,
node: { menuType },
} = treeNode;
console.log(menuType);
switch (menuType) {
case 'MiniAppMenuGroup':
setNodeType(1);
setAddType(2);
break;
case 'MiniAppMenuGroupTwo':
setNodeType(2);
setAddType(4);
break;
case 'MiniAppMenu':
setNodeType(3);
setAddType(3);
break;
case 'MiniAppMenuThree':
setNodeType(4);
setAddType(4);
break;
default:
break;
}
}
if (prop[0]) {
setMenuID(prop[0]);
setSaveID(prop[0]);
} else {
setMenuID(saveID);
}
};
const getInfo = id => {
if (!menuID) {
return;
}
setLoading(true);
getMenuInfo({
menuID,
_version: 9999,
_dc: Date.now(),
})
.then(res => {
setLoading(false);
if (res.success) {
setInfo({ ...res });
} else {
notification.error({
message: '提示',
duration: 10,
description: res.message || '获取失败',
});
}
console.log(res, 'resss');
})
.catch(err => {
setLoading(false);
console.error(err);
});
};
// 删除的回调
const deleteMenuTip = val => {
console.log(val, 'val');
deleteMenu({
menuID: val.menuID,
_dc: Date.now(),
_version: 9999,
}).then(res => {
if (res.success) {
setFlag(flag + 1);
notification.success({
message: '提示',
duration: 3,
description: '删除成功',
});
} else {
notification.error({
message: '提示',
duration: 10,
description: res.message || '删除成功',
});
}
});
};
// 新增菜单组
const addMenuGroupTip = val => {
console.log(val, 'addgroup');
setNodeObj(val);
setAddVisible(true);
};
const rootAddGroup = () => {
setNodeObj('');
setNodeType(1);
setAddType(1);
setAddVisible(true);
};
// 新增功能菜单
const addMenuTip = val => {
console.log(val, 'add');
setNodeObj(val);
setAddTwoVisible(true);
};
const rootAdd = () => {
setNodeObj('');
setNodeType(3);
setAddType(3);
setAddTwoVisible(true);
};
// 提交的回调
const submitCallback = (prop, item) => {
console.log(prop, item);
let obj = { ...prop };
const parentID = item.menuID ? item.menuID : -1;
addMenu({
_dc: Date.now(),
parentID,
subSystemValue: 'miniapp',
_version: 9999,
...obj,
})
.then(res => {
if (res.success) {
setAddVisible(false);
setAddTwoVisible(false);
setFlag(flag + 1);
notification.success({
message: '提示',
description: '新增成功',
duration: 3,
});
} else {
notification.error({
message: '提示',
description: res.message || '新增失败',
duration: 10,
});
}
console.log(res, 'resadd');
})
.catch(err => {
console.error(err);
});
};
// 编辑的回调
const editSubmitCallback = prop => {
setLoading(true);
console.log(prop);
let obj = { ...prop };
editMenu({
_dc: Date.now(),
menuID,
subSystemValue: 'miniapp',
_version: 9999,
...obj,
})
.then(res => {
setLoading(false);
if (res.success) {
setFlag(flag + 1);
notification.success({
message: '提示',
duration: 3,
description: '编辑成功',
});
} else {
notification.error({
message: '提示',
duration: 3,
description: res.message || '编辑失败',
});
}
console.log(res, 'resres');
})
.catch(err => {
console.error(err);
setLoading(false);
});
};
return (
<Spin spinning={loading} tip="loading...">
<div
className={classnames({
[styles.box]: true,
})}
>
<div
className={classnames({
[styles.left]: true,
})}
>
<div
className={classnames({
[styles.leftTop]: true,
})}
>
菜单列表
<div
className={classnames({
[styles.tRight]: true,
})}
>
<Tooltip title="新增菜单组">
<FolderAddTwoTone
className={`${styles.icon1} ${styles.icon}`}
onClick={() => rootAddGroup()}
/>
</Tooltip>
<Tooltip title="新增功能菜单">
<FileAddTwoTone
onClick={() => rootAdd()}
className={`${styles.icon2} ${styles.icon}`}
/>
</Tooltip>
</div>
</div>
{treeData.length > 0 && (
<Tree
showIcon
onSelect={handleSelect}
treeData={treeData.map(item => mapTree(item))}
blockNode
autoExpandParent
selectedKeys={[menuID]}
expandedKeys={[menuID]}
/>
)}
</div>
<Modal
visible={addVisible}
title="新增菜单组"
bodyStyle={{ width: '100%', minHeight: '100px' }}
style={{ top: 20 }}
width="600px"
destroyOnClose
footer={null}
cancelText="取消"
okText="确认"
onCancel={() => setAddVisible(false)}
onConfirm={() => {
submitCallback();
}}
>
<AddForm
nodeType={nodeType}
nodeObj={nodeObj}
addType={addType}
submitCallback={submitCallback}
/>
</Modal>
<Modal
visible={addTwoVisible}
title="新增功能菜单"
bodyStyle={{ width: '100%', minHeight: '100px' }}
style={{ top: 20 }}
width="600px"
destroyOnClose
footer={null}
cancelText="取消"
okText="确认"
onCancel={() => setAddTwoVisible(false)}
>
<AddForm
nodeType={nodeType}
nodeObj={nodeObj}
addType={addType}
submitCallback={submitCallback}
/>
</Modal>
<div
className={classnames({
[styles.middle]: true,
})}
>
{nodeType && (
<EditForm
nodeType={nodeType}
info={info}
submitCallback={editSubmitCallback}
/>
)}
</div>
</div>
</Spin>
);
};
export default MiniMenu;
.box{
min-height: calc( 100vh - 172px);
display: flex;
}
.left{
min-width: 300px;
width: 300px;
min-height: 100%;
border: 1px solid #eee;
padding: 10px;
.ant-tree-node-content-wrapper{
display: flex;
align-items: center;
.ant-tree-iconEle{
display: flex;
align-items: center;
}
.ant-tree-title{
width: 100%;
}
}
.leftTop{
display: flex;
align-items: center;
margin-bottom: 10px;
justify-content: space-between;
.tRight{
display: flex;
align-items: center;
.icon1{
font-size: 20px;
margin-right: 10px;
}
.icon2{
font-size: 18px;
margin-right: 5px;
}
.icon:hover{
cursor: pointer;
}
}
}
}
.middle{
min-width: 500px;
width: 500px;
min-height: 100%;
border: 1px solid #eee;
padding: 10px;
margin: 0 10px;
}
.title{
display: flex;
align-items: center;
width: 100%;
}
.tip{
display: none;
}
.title:hover{
.tip{
display: flex;
align-items: center;
justify-content: flex-end;
width: 100%;
}
}
.fs{
font-size: 18px;
margin-left: 10px;
}
\ No newline at end of file
...@@ -81,7 +81,7 @@ const UserManage = () => { ...@@ -81,7 +81,7 @@ const UserManage = () => {
const [addOrgVisible, setAddOrgVisible] = useState(false); // 添加机构 const [addOrgVisible, setAddOrgVisible] = useState(false); // 添加机构
const [editOrgVisible, setEditOrgVisible] = useState(false); // 编辑机构 const [editOrgVisible, setEditOrgVisible] = useState(false); // 编辑机构
const [deleteOrgVisible, setDeleteOrgVisible] = useState(false); // 删除机构 const [deleteOrgVisible, setDeleteOrgVisible] = useState(false); // 删除机构
const [roleVisible, setRoleVisible] = useState(false); // 用户关联 const [roleVisible, setRoleVisible] = useState(false); // 关联角色
const [changeOrgVisible, setChangeOrgVisible] = useState(false); // 更改机构 const [changeOrgVisible, setChangeOrgVisible] = useState(false); // 更改机构
const [passwordVisible, setPasswordVisible] = useState(false); // 修改密码 const [passwordVisible, setPasswordVisible] = useState(false); // 修改密码
const [editUserVisible, setEditUserVisible] = useState(false); // 编辑用户 const [editUserVisible, setEditUserVisible] = useState(false); // 编辑用户
...@@ -466,7 +466,7 @@ const UserManage = () => { ...@@ -466,7 +466,7 @@ const UserManage = () => {
}, [currentUser]); }, [currentUser]);
/** ***用户批量操作****** */ /** ***用户批量操作****** */
// 用户关联 // 关联角色
const relateRoles = () => { const relateRoles = () => {
getEmptyRoleList(); getEmptyRoleList();
setRoleVisible(true); setRoleVisible(true);
...@@ -484,7 +484,7 @@ const UserManage = () => { ...@@ -484,7 +484,7 @@ const UserManage = () => {
}; };
/** ***右侧表格相关操作****** */ /** ***右侧表格相关操作****** */
// 用户关联 // 关联角色
const relateRole = record => { const relateRole = record => {
setRoleVisible(true); setRoleVisible(true);
setCurrentUser(record); setCurrentUser(record);
...@@ -558,7 +558,12 @@ const UserManage = () => { ...@@ -558,7 +558,12 @@ const UserManage = () => {
const phone = addUserForm.getFieldValue('phone') || ''; const phone = addUserForm.getFieldValue('phone') || '';
const email = addUserForm.getFieldValue('email') || ''; const email = addUserForm.getFieldValue('email') || '';
// 正则验证 // 正则验证
if (!noChinese.test(loginName)) { if (loginName === '') {
notification.error({
message: '提交失败',
description: '登录名不能为空!',
});
} else if (!noChinese.test(loginName)) {
notification.error({ notification.error({
message: '提交失败', message: '提交失败',
description: '登录名不支持中文!', description: '登录名不支持中文!',
...@@ -1320,9 +1325,9 @@ const UserManage = () => { ...@@ -1320,9 +1325,9 @@ const UserManage = () => {
> >
<p>即将删除该机构,是否确认删除?</p> <p>即将删除该机构,是否确认删除?</p>
</Modal> </Modal>
{/* 用户关联 */} {/* 关联角色 */}
<Modal <Modal
title="用户关联" title="关联角色"
visible={roleVisible} visible={roleVisible}
onOk={multiRelateRoles ? submitRoles : submitRole} onOk={multiRelateRoles ? submitRoles : submitRole}
onCancel={() => { onCancel={() => {
...@@ -1334,7 +1339,7 @@ const UserManage = () => { ...@@ -1334,7 +1339,7 @@ const UserManage = () => {
width="960px" width="960px"
> >
<Spin spinning={loading} tip="loading"> <Spin spinning={loading} tip="loading">
<Tabs defaultActiveKey="1"> <Tabs defaultActiveKey="1" style={{ marginTop: '-16px' }}>
<TabPane tab="角色" key="1"> <TabPane tab="角色" key="1">
{roleVisible && {roleVisible &&
rolelist.map((role, index) => ( rolelist.map((role, index) => (
......
...@@ -29,6 +29,7 @@ import ListCard, { ...@@ -29,6 +29,7 @@ import ListCard, {
} from '@/components/CheckGroup'; } from '@/components/CheckGroup';
// import ListCard from '@/pages/orgnazation/ListCard'; // import ListCard from '@/pages/orgnazation/ListCard';
import qs from 'qs'; import qs from 'qs';
import classnames from 'classnames';
import styles from '@/pages/userCenter/roleManage/RoleManage.less'; import styles from '@/pages/userCenter/roleManage/RoleManage.less';
import AddModal from './AddModal'; import AddModal from './AddModal';
import DelModal from './DelModal'; import DelModal from './DelModal';
...@@ -38,6 +39,7 @@ import userStyles from '../UserManage.less'; ...@@ -38,6 +39,7 @@ import userStyles from '../UserManage.less';
const { Search } = Input; const { Search } = Input;
const placeholder = '请输入功能名称'; const placeholder = '请输入功能名称';
const SiteManage = () => { const SiteManage = () => {
const [treeData, setTreeData] = useState([]); const [treeData, setTreeData] = useState([]);
const [searchWord, setSearchWord] = useState(''); const [searchWord, setSearchWord] = useState('');
...@@ -313,9 +315,19 @@ const SiteManage = () => { ...@@ -313,9 +315,19 @@ const SiteManage = () => {
}; };
return ( return (
<PageContainer> <PageContainer>
<Row gutter={0}> {/* <Row gutter={0}>
<Col span={mulu ? 4 : 0}> <Col span={mulu ? 4 : 0}> */}
<Card className={styles.cardBox}> <div
className={classnames({
[styles.content]: true,
})}
>
<Card
className={classnames({
[styles.cardBox]: true,
[styles.hideBox]: !mulu,
})}
>
<Spin <Spin
tip="loading...." tip="loading...."
spinning={spinLoading} spinning={spinLoading}
...@@ -361,6 +373,18 @@ const SiteManage = () => { ...@@ -361,6 +373,18 @@ const SiteManage = () => {
onCancel={() => setGroupVisible(false)} onCancel={() => setGroupVisible(false)}
confirmModal={groupModal} confirmModal={groupModal}
/> />
<div>
{mulu && (
<Tooltip title="隐藏角色栏" className={styles.hide}>
<DoubleLeftOutlined onClick={() => handleHide()} />
</Tooltip>
)}
{!mulu && (
<Tooltip title="显示角色栏" className={styles.hide}>
<DoubleRightOutlined onClick={() => handleHide()} />
</Tooltip>
)}
</div>
</Card> </Card>
{/* <div> {/* <div>
{mulu && ( {mulu && (
...@@ -369,7 +393,7 @@ const SiteManage = () => { ...@@ -369,7 +393,7 @@ const SiteManage = () => {
</Tooltip> </Tooltip>
)} )}
</div> */} </div> */}
</Col> {/* </Col> */}
{/* <Col span={mulu ? 0 : 1}> {/* <Col span={mulu ? 0 : 1}>
{mulu && ( {mulu && (
<Tooltip title="隐藏角色栏" className={styles.hide}> <Tooltip title="隐藏角色栏" className={styles.hide}>
...@@ -382,8 +406,19 @@ const SiteManage = () => { ...@@ -382,8 +406,19 @@ const SiteManage = () => {
</Tooltip> </Tooltip>
)} )}
</Col> */} </Col> */}
<Col span={mulu ? 20 : 23}> {/* <Col span={mulu ? 20 : 23}> */}
<Card style={{ marginBottom: '10px', minWidth: '870px' }}> <div
className={classnames({
[styles.boxR]: true,
[styles.boxH]: mulu,
})}
>
<Card
className={classnames({
[styles.cardBoxTop]: true,
[styles.boxH]: mulu,
})}
>
<Row align="middle"> <Row align="middle">
<Col span={1}>搜索</Col> <Col span={1}>搜索</Col>
<Col span={8}> <Col span={8}>
...@@ -438,7 +473,12 @@ const SiteManage = () => { ...@@ -438,7 +473,12 @@ const SiteManage = () => {
</Col> </Col>
</Row> </Row>
</Card> </Card>
<Card className={styles.cardBoxR}> <Card
className={classnames({
[styles.boxH]: mulu,
[styles.cardBoxR]: true,
})}
>
{roleID && ( {roleID && (
<ListCard <ListCard
loading={loading} loading={loading}
...@@ -451,8 +491,10 @@ const SiteManage = () => { ...@@ -451,8 +491,10 @@ const SiteManage = () => {
/> />
)} )}
</Card> </Card>
</Col> </div>
</Row> {/* </Col>
</Row> */}
</div>
</PageContainer> </PageContainer>
); );
}; };
......
.cardBox{ .cardBox{
min-height: calc(100vh - 74px); min-height: calc(100vh - 74px);
max-height: calc(100vh - 74px); max-height: calc(100vh - 74px);
overflow-y: scroll; // overflow-y: scroll;
margin-right: 20px; overflow: auto;
width: 260px;
left: 0;
top: 0;
margin-right: 10px;
position: relative;
// transition: left,width 10s;
transition-property:width,left;
transition-duration: 0.5s;
white-space: nowrap;
.ant-tree-node-content-wrapper{ .ant-tree-node-content-wrapper{
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -12,6 +21,15 @@ ...@@ -12,6 +21,15 @@
} }
} }
} }
.hideBox{
left: 0px;
top: 0;
width: 20px;
}
.hideH{
width: 100%;
}
.ant-tree-node-content-wrapper-open{ .ant-tree-node-content-wrapper-open{
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -35,16 +53,16 @@ ...@@ -35,16 +53,16 @@
align-items: center; align-items: center;
} }
.cardBoxR{ .cardBoxR{
min-width: 870px;
min-height: calc(100vh - 158px); min-height: calc(100vh - 158px);
max-height: calc(100vh - 158px); max-height: calc(100vh - 158px);
min-width: 870px;
overflow-y: scroll; overflow-y: scroll;
} }
:global{ :global{
.ant-tree-switcher{ .ant-tree-switcher{
display: flex; display: flex;
align-items: center; align-items: center;
color:#1890FF; // color:#1890FF;
.ant-tree-switcher-line-icon{ .ant-tree-switcher-line-icon{
margin-left: 5px; margin-left: 5px;
} }
...@@ -62,10 +80,18 @@ ...@@ -62,10 +80,18 @@
z-index: 2; z-index: 2;
} }
.anticon-unordered-list{
vertical-align: 0.125em; .boxR{
color:#1890FF; width: 100%;
position: relative;
transition: width 2s;
} }
.ant-card-body { // .anticon-unordered-list{
padding: 20px 10px; // vertical-align: 0.125em;
// color:#1890FF;
// }
.content{
width: 100%;
display: flex;
position: relative;
} }
\ No newline at end of file
...@@ -236,11 +236,13 @@ const SiteManage = () => { ...@@ -236,11 +236,13 @@ const SiteManage = () => {
return ( return (
<PageContainer> <PageContainer>
<Row> {/* <Row>
<Col span={mulu ? 4 : 0}> <Col span={mulu ? 4 : 0}> */}
<div className={styles.content}>
<Card <Card
className={classnames({ className={classnames({
[styles.cardBox]: true, [styles.cardBox]: true,
[styles.hideBox]: !mulu,
})} })}
> >
<Spin <Spin
...@@ -270,6 +272,18 @@ const SiteManage = () => { ...@@ -270,6 +272,18 @@ const SiteManage = () => {
onCancel={() => setEditVisible(false)} onCancel={() => setEditVisible(false)}
confirmModal={editModal} confirmModal={editModal}
/> />
<div>
{mulu && (
<Tooltip title="隐藏站点" className={styles.hide}>
<DoubleLeftOutlined onClick={() => handleHide()} />
</Tooltip>
)}
{!mulu && (
<Tooltip title="显示站点" className={styles.hide}>
<DoubleRightOutlined onClick={() => handleHide()} />
</Tooltip>
)}
</div>
</Card> </Card>
{/* <div> {/* <div>
{mulu && ( {mulu && (
...@@ -283,7 +297,7 @@ const SiteManage = () => { ...@@ -283,7 +297,7 @@ const SiteManage = () => {
</Tooltip> </Tooltip>
)} )}
</div> */} </div> */}
</Col> {/* </Col> */}
{/* <Col span={mulu ? 0 : 1}> {/* <Col span={mulu ? 0 : 1}>
{mulu && ( {mulu && (
<Tooltip title="隐藏站点" className={styles.hide}> <Tooltip title="隐藏站点" className={styles.hide}>
...@@ -296,8 +310,19 @@ const SiteManage = () => { ...@@ -296,8 +310,19 @@ const SiteManage = () => {
</Tooltip> </Tooltip>
)} )}
</Col> */} </Col> */}
<Col span={mulu ? 20 : 23}> {/* <Col span={mulu ? 20 : 23}> */}
<Card style={{ marginBottom: '10px', minWidth: '600px' }}> <div
className={classnames({
[styles.boxR]: true,
[styles.boxH]: mulu,
})}
>
<Card
className={classnames({
[styles.cardBoxTop]: true,
[styles.boxH]: mulu,
})}
>
<Row align="middle"> <Row align="middle">
<Col span={1}>搜索</Col> <Col span={1}>搜索</Col>
<Col span={8}> <Col span={8}>
...@@ -343,7 +368,12 @@ const SiteManage = () => { ...@@ -343,7 +368,12 @@ const SiteManage = () => {
</Col> </Col>
</Row> </Row>
</Card> </Card>
<Card className={styles.cardBoxR}> <Card
className={classnames({
[styles.boxH]: mulu,
[styles.cardBoxR]: true,
})}
>
{currentStation.stationID && ( {currentStation.stationID && (
<ListCard <ListCard
loading={loading} loading={loading}
...@@ -355,8 +385,10 @@ const SiteManage = () => { ...@@ -355,8 +385,10 @@ const SiteManage = () => {
/> />
)} )}
</Card> </Card>
</Col> </div>
</Row> </div>
{/* </Col>
</Row> */}
</PageContainer> </PageContainer>
); );
}; };
......
.cardBox{ .cardBox{
min-height: calc(100vh - 74px); min-height: calc(100vh - 75px);
max-height: calc(100vh - 74px); max-height: calc(100vh - 75px);
overflow: auto; overflow: auto;
width: 260px;
left: 0;
top: 0;
margin-right: 10px; margin-right: 10px;
position: relative;
// transition: left,width 10s;
transition-property:width,left;
transition-duration: 0.5s;
white-space: nowrap
}
.hideBox{
left: 0px;
top: 0;
width: 20px;
}
.hideH{
width: 100%;
} }
.siteTitle{ .siteTitle{
font-size: 16px; font-size: 16px;
...@@ -17,6 +33,11 @@ ...@@ -17,6 +33,11 @@
min-width: 600px; min-width: 600px;
overflow-y: scroll; overflow-y: scroll;
} }
.cardBoxTop{
// max-width: calc( 100% - 450px);
// margin-bottom: 10px;
}
.ant-tree-node-content-wrapper-open{ .ant-tree-node-content-wrapper-open{
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -65,3 +86,13 @@ ...@@ -65,3 +86,13 @@
// .hide{ // .hide{
// left: 0; // left: 0;
// } // }
.content{
width: 100%;
display: flex;
position: relative;
}
.boxR{
width: 100%;
position: relative;
transition: width 2s;
}
\ No newline at end of file
...@@ -46,3 +46,41 @@ export const editWebsite = (params, options) => { ...@@ -46,3 +46,41 @@ export const editWebsite = (params, options) => {
*/ */
export const getMiniAppModuleTree = params => export const getMiniAppModuleTree = params =>
get(`${PUBLISH_SERVICE}/PlatformCenter/MiniAppModuleTree`, params); get(`${PUBLISH_SERVICE}/PlatformCenter/MiniAppModuleTree`, params);
/**
*
* @新增功能菜单组
* @请求参数 {*}{
* version: 9999
_dc: 1606203896370
parentID: -1
subSystemValue: miniapp
menuName: 分组名称
imageUrl: assets/images/appMenu/小程序tab/enterprise_select.png
offlineImgUrl: assets/images/appMenu/小程序tab/enterprise_unselect.png
shortName: 分组别名
pageUrl: //功能路径
funParam: 测试功能参数
relatedRoleList: //角色数组
}
*/
export const addMenu = params =>
get('/Cityinterface/rest/services/OMS.svc/MiniApp_AddMenu', params);
// 获取菜单详情
/**
* {
* menuID:''
* }
*/
export const getMenuInfo = params =>
get('/Cityinterface/rest/services/OMS.svc/Mini_GetMenuInfo', params);
// 编辑菜单
export const editMenu = params =>
get('/Cityinterface/rest/services/OMS.svc/MiniApp_EditMenu', params);
// 删除菜单
export const deleteMenu = params =>
get('/Cityinterface/rest/services/OMS.svc/MiniApp_DeleteMenu', params);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment