Commit bba774f2 authored by Maofei94's avatar Maofei94

Merge branch 'master' of g.civnet.cn:test/maintenance

parents 84ddf94d e24f991f
# PUBLIC_PATH = reactOMS, 默认转发 /cityinterface # PUBLIC_PATH = reactOMS, 默认转发 /cityinterface
PROXY = http://localhost:8005/ PROXY=/Cityinterface:http://192.168.10.151:8055;/Publish:http://192.168.10.151:8055;/Web4:http://192.168.10.151:8055;/CityTemp:http://192.168.10.151:8055
# 可设置第二个代理,test为转发前缀,后面为代理转发的地址 # 可设置第二个代理,test为转发前缀,后面为代理转发的地址
# PROXY2 = test : http://localhost:8006/ # PROXY2 = test : http://localhost:8006/
......
...@@ -14,6 +14,116 @@ function createWebpackMiddleware(compiler, publicPath) { ...@@ -14,6 +14,116 @@ function createWebpackMiddleware(compiler, publicPath) {
}); });
} }
const setupProxyFeature = (app, webpackConfig) => {
console.log(webpackConfig);
if (!Array.isArray(webpackConfig.proxy)) {
if (Object.prototype.hasOwnProperty.call(webpackConfig.proxy, 'target')) {
webpackConfig.proxy = [webpackConfig.proxy];
} else {
webpackConfig.proxy = Object.keys(webpackConfig.proxy).map(context => {
let proxyOptions;
// For backwards compatibility reasons.
const correctedContext = context
.replace(/^\*$/, '**')
.replace(/\/\*$/, '');
if (typeof webpackConfig.proxy[context] === 'string') {
proxyOptions = {
context: correctedContext,
target: webpackConfig.proxy[context],
};
} else {
proxyOptions = Object.assign({}, webpackConfig.proxy[context]);
proxyOptions.context = correctedContext;
}
proxyOptions.logLevel = proxyOptions.logLevel || 'warn';
return proxyOptions;
});
}
}
// eslint-disable-next-line consistent-return
const getProxyMiddleware = proxyConfig => {
const context = proxyConfig.context || proxyConfig.path;
// It is possible to use the `bypass` method without a `target`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
return createProxyMiddleware(context, proxyConfig);
}
};
/**
* Assume a proxy configuration specified as:
* proxy: [
* {
* context: ...,
* ...options...
* },
* // or:
* function() {
* return {
* context: ...,
* ...options...
* };
* }
* ]
*/
webpackConfig.proxy.forEach(proxyConfigOrCallback => {
let proxyMiddleware;
let proxyConfig =
typeof proxyConfigOrCallback === 'function'
? proxyConfigOrCallback()
: proxyConfigOrCallback;
proxyMiddleware = getProxyMiddleware(proxyConfig);
if (proxyConfig.ws) {
this.websocketProxies.push(proxyMiddleware);
}
// eslint-disable-next-line consistent-return
const handle = (req, res, next) => {
if (typeof proxyConfigOrCallback === 'function') {
const newProxyConfig = proxyConfigOrCallback();
if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware = getProxyMiddleware(proxyConfig);
}
}
// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
const isByPassFuncDefined = typeof proxyConfig.bypass === 'function';
const bypassUrl = isByPassFuncDefined
? proxyConfig.bypass(req, res, proxyConfig)
: null;
if (typeof bypassUrl === 'boolean') {
// skip the proxy
req.url = null;
next();
} else if (typeof bypassUrl === 'string') {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next);
} else {
next();
}
};
app.use(handle);
// Also forward error requests to the proxy so it can handle them.
app.use((error, req, res, next) => handle(req, res, next));
});
};
module.exports = function addDevMiddlewares(app, webpackConfig) { module.exports = function addDevMiddlewares(app, webpackConfig) {
const compiler = webpack(webpackConfig); const compiler = webpack(webpackConfig);
const middleware = createWebpackMiddleware( const middleware = createWebpackMiddleware(
...@@ -27,65 +137,19 @@ module.exports = function addDevMiddlewares(app, webpackConfig) { ...@@ -27,65 +137,19 @@ module.exports = function addDevMiddlewares(app, webpackConfig) {
// Since webpackDevMiddleware uses memory-fs internally to store build // Since webpackDevMiddleware uses memory-fs internally to store build
// artifacts, we use it instead // artifacts, we use it instead
const fs = middleware.fileSystem; const fs = middleware.fileSystem;
let proxyHost = process.env.PROXY; if (process.env.PROXY) {
const proxyPrefix = process.env.PROXY_PREFIX || '/Cityinterface'; const proxies = process.env.PROXY.split(';');
app.get('/setproxy', (req, res) => { // 设置代理
if (req.query && req.query.host) { setupProxyFeature(app, {
proxyHost = req.query.host; proxy: proxies.map(proxyStr => {
res.send(200); const mathes = proxyStr.match(/^\s*([/\w]+)\s*:\s*(.+)\s*$/);
} else { return {
res.send(400); path: mathes[1],
} target: mathes[2],
});
if (
proxyHost &&
(proxyHost.toLowerCase() !== 'origin' ||
proxyHost.toLowerCase() !== 'off' ||
proxyHost !== '0')
) {
logger.info(`using proxy at: ${proxyHost}`);
logger.info(`proxy prefix: ${proxyPrefix}`);
app.use(
proxyPrefix,
createProxyMiddleware({
target: proxyHost,
changeOrigin: true,
// eslint-disable-next-line no-unused-vars
onProxyReq: (_prexyReq, _req, _res) => {
logger.info('onProxyReq');
},
// eslint-disable-next-line no-unused-vars
onProxyRes(_proxyRes, _req, _res) {
logger.info('onProxyRes');
},
}),
);
const proxy2 = process.env.PROXY2;
if (proxy2) {
const reg = /([/\w]+)\s*:\s*([\w:./]*)/;
const match = proxy2.match(reg);
const [, pre, host] = match;
logger.info(`using proxy2 at: ${host}`);
const prefix = `${pre[0] === '/' ? pre : `/${pre}`}`;
logger.info(`proxy2 prefix: ${prefix}`);
app.use(
prefix,
createProxyMiddleware({
target: host,
changeOrigin: true, changeOrigin: true,
// eslint-disable-next-line no-unused-vars };
onProxyReq: (_prexyReq, _req, _res) => { }),
logger.info('onProxyReq2'); });
},
// eslint-disable-next-line no-unused-vars
onProxyRes(_proxyRes, _req, _res) {
logger.info('onProxyRes2');
},
}),
);
}
} }
app.get('*', (_req, res) => { app.get('*', (_req, res) => {
......
...@@ -17,7 +17,7 @@ import zhCN from 'antd/es/locale/zh_CN'; ...@@ -17,7 +17,7 @@ import zhCN from 'antd/es/locale/zh_CN';
import configureStore from './configureStore'; import configureStore from './configureStore';
import App from './containers/App'; import App from './containers/App';
import history from './utils/history'; import history from './utils/history';
import config from './routes/config';
const initialState = Immutable.Map(); const initialState = Immutable.Map();
const store = configureStore(initialState, history); const store = configureStore(initialState, history);
const MOUNT_NODE = document.getElementById('app'); const MOUNT_NODE = document.getElementById('app');
...@@ -27,7 +27,7 @@ const render = () => { ...@@ -27,7 +27,7 @@ const render = () => {
<Provider store={store}> <Provider store={store}>
<ConnectedRouter history={history}> <ConnectedRouter history={history}>
<ConfigProvider locale={zhCN}> <ConfigProvider locale={zhCN}>
<App /> <App routesConfig={config} />
</ConfigProvider> </ConfigProvider>
</ConnectedRouter> </ConnectedRouter>
</Provider>, </Provider>,
......
...@@ -70,6 +70,7 @@ const BaseForm = props => { ...@@ -70,6 +70,7 @@ const BaseForm = props => {
getForm, // 用来获取表单实例 getForm, // 用来获取表单实例
formProps, formProps,
children, children,
...restProps
} = props; } = props;
const [form] = useForm(); const [form] = useForm();
...@@ -81,7 +82,7 @@ const BaseForm = props => { ...@@ -81,7 +82,7 @@ const BaseForm = props => {
}, []); }, []);
return ( return (
<Form size="small" form={form} {...formProps}> <Form size="small" form={form} {...formProps} {...restProps}>
{items && {items &&
items.map(item => { items.map(item => {
const { const {
......
...@@ -4,9 +4,10 @@ import { PlusOutlined, CheckCircleFilled } from '@ant-design/icons'; ...@@ -4,9 +4,10 @@ import { PlusOutlined, CheckCircleFilled } from '@ant-design/icons';
import ImgCrop from 'antd-img-crop'; import ImgCrop from 'antd-img-crop';
import classnames from 'classnames'; import classnames from 'classnames';
import { UploadFile, UploadChangeParam, RcFile } from 'antd/lib/upload/interface'; import { UploadFile, UploadChangeParam, RcFile } from 'antd/lib/upload/interface';
import { isDev, unParams, uuid } from '@/utils/tools'; import { uuid } from '@/utils/tools';
import { get } from '@/services'; import { get, PUBLISH_SERVICE } from '@/services';
import styles from './index.less'; import styles from './index.less';
import { getImageBases } from '@/services/common/api';
const { TabPane } = Tabs; const { TabPane } = Tabs;
...@@ -35,6 +36,7 @@ interface PicturesWallType { ...@@ -35,6 +36,7 @@ interface PicturesWallType {
onChange?: (v: any) => void; onChange?: (v: any) => void;
cropRate?: number | boolean; cropRate?: number | boolean;
isCrop?: boolean; isCrop?: boolean;
type?: 'CityTemp'|'icon'|'androidMenu'|'menuNew'
} }
class PicturesWall extends React.Component<PicturesWallType> { class PicturesWall extends React.Component<PicturesWallType> {
...@@ -43,11 +45,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -43,11 +45,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
previewImage: '', previewImage: '',
wallModalVisible: false, wallModalVisible: false,
previewTitle: '', previewTitle: '',
imgBed: { imgBed: [],
icon: [],
bg: [],
uploaded: [],
},
curSelectedImg: '', curSelectedImg: '',
fileList: this.props.fileList || [], fileList: this.props.fileList || [],
}; };
...@@ -90,9 +88,9 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -90,9 +88,9 @@ class PicturesWall extends React.Component<PicturesWallType> {
const fileList = [ const fileList = [
{ {
uid: uuid(8, 16), uid: uuid(8, 16),
name: 'h5-dooring图片库', name: '熊猫运维中台系统',
status: 'done', status: 'done',
url: this.state.curSelectedImg, url: this.getImageUrl(this.state.curSelectedImg),
}, },
]; ];
this.props.onChange && this.props.onChange(fileList); this.props.onChange && this.props.onChange(fileList);
...@@ -103,11 +101,11 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -103,11 +101,11 @@ class PicturesWall extends React.Component<PicturesWallType> {
this.setState({ fileList }); this.setState({ fileList });
if (file.status === 'done') { if (file.status === 'done') {
const files = fileList.map(item => { const files = fileList.map(item => {
const { uid, name, status } = item; const { status, data, name, thumbUrl } = item;
const url = item.url || item.response.result.url; const url = thumbUrl || this.getImageUrl(data);
return { uid, name, status, url }; return { uid: uuid(8, 16), name, status, url };
}); });
this.props.onChange && this.props.onChange(files); this.props.onChange && this.props.onChange( this.props.maxLen === 1 ? files[0].url : files.map(f => f.url));
} }
}; };
...@@ -128,12 +126,19 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -128,12 +126,19 @@ class PicturesWall extends React.Component<PicturesWallType> {
}; };
componentDidMount() { componentDidMount() {
get(`/visible/bed/get?tid=${unParams(location.search)!.tid}`).then(res => { const { type = ''} = this.props;
// res && getImageBases(type).then(res => {
// this.setState({ if(res.code === 0){
// imgBed: res, this.setState({imgBed: res.data})
// }); }
}); })
}
getImageUrl(path){
if(path.indexOf('http') === 0){
return path
}
return `${window.location.origin}/${path}`.replace(/\\/g, '/')
} }
render() { render() {
...@@ -147,7 +152,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -147,7 +152,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
curSelectedImg, curSelectedImg,
} = this.state; } = this.state;
const { const {
action = isDev ? 'http://192.168.1.8:3000/api/v0/files/upload/free' : '你的服务器地址', action = `${window.location.origin}${PUBLISH_SERVICE}/FileCenter/UploadSingleFile` ,
headers, headers,
withCredentials = true, withCredentials = true,
maxLen = 1, maxLen = 1,
...@@ -162,8 +167,6 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -162,8 +167,6 @@ class PicturesWall extends React.Component<PicturesWallType> {
</div> </div>
); );
const cates = Object.keys(imgBed);
return ( return (
<> <>
{isCrop ? ( {isCrop ? (
...@@ -178,14 +181,14 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -178,14 +181,14 @@ class PicturesWall extends React.Component<PicturesWallType> {
fileList={fileList} fileList={fileList}
onPreview={this.handlePreview} onPreview={this.handlePreview}
onChange={this.handleChange} onChange={this.handleChange}
name="file" name="singleFile"
listType="picture-card" listType="picture-card"
className={styles.avatarUploader} className={styles.avatarUploader}
action={action} action={action}
withCredentials={withCredentials} withCredentials={withCredentials}
headers={{ headers={{
'x-requested-with': localStorage.getItem('user') || '', 'x-requested-with': localStorage.getItem('user') || '',
authorization: localStorage.getItem('token') || '', token: localStorage.getItem('token') || '',
...headers, ...headers,
}} }}
beforeUpload={this.handleBeforeUpload} beforeUpload={this.handleBeforeUpload}
...@@ -198,14 +201,14 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -198,14 +201,14 @@ class PicturesWall extends React.Component<PicturesWallType> {
fileList={fileList} fileList={fileList}
onPreview={this.handlePreview} onPreview={this.handlePreview}
onChange={this.handleChange} onChange={this.handleChange}
name="file" name="singleFile"
listType="picture-card" listType="picture-card"
className={styles.avatarUploader} className={styles.avatarUploader}
action={action} action={action}
withCredentials={withCredentials} withCredentials={withCredentials}
headers={{ headers={{
'x-requested-with': localStorage.getItem('user') || '', 'x-requested-with': localStorage.getItem('user') || '',
authorization: localStorage.getItem('token') || '', token: localStorage.getItem('token') || '',
...headers, ...headers,
}} }}
beforeUpload={this.handleBeforeUpload} beforeUpload={this.handleBeforeUpload}
...@@ -214,7 +217,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -214,7 +217,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
</Upload> </Upload>
)} )}
<div className={styles.wallBtn} onClick={this.handleWallShow}> <div className={styles.wallBtn} onClick={this.handleWallShow}>
图片库 从图片库选择
</div> </div>
<Modal <Modal
visible={previewVisible} visible={previewVisible}
...@@ -222,7 +225,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -222,7 +225,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
footer={null} footer={null}
onCancel={this.handleCancel} onCancel={this.handleCancel}
> >
<img alt="预览图片" style={{ width: '100%' }} src={previewImage} /> <img alt="预览图片" style={{ width: '100%' }} src={this.getImageUrl(previewImage)} />
</Modal> </Modal>
<Modal <Modal
visible={wallModalVisible} visible={wallModalVisible}
...@@ -233,13 +236,12 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -233,13 +236,12 @@ class PicturesWall extends React.Component<PicturesWallType> {
onCancel={this.handleModalCancel} onCancel={this.handleModalCancel}
onOk={this.handleModalOk} onOk={this.handleModalOk}
> >
<Tabs defaultActiveKey={cates[0]} tabPosition="left" style={{ height: 520 }}> <Tabs defaultActiveKey={imgBed[0]?.moduleName} tabPosition="left" style={{ height: 520 }}>
{cates.map((item, i) => { {imgBed.map((item, i) => {
return ( return (
<TabPane tab={wallCateName[item]} key={item}> <TabPane tab={item.moduleName} key={item.moduleName}>
<div className={styles.imgBox}> <div className={styles.imgBox}>
{(imgBed as any)[item] && {item.child?.map(m => m.fileUrls).flat(Infinity).map((item: string, i: number) => {
(imgBed as any)[item].map((item: string, i: number) => {
return ( return (
<div <div
className={classnames( className={classnames(
...@@ -249,7 +251,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -249,7 +251,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
key={i} key={i}
onClick={() => this.handleImgSelected(item)} onClick={() => this.handleImgSelected(item)}
> >
<img src={item} alt="熊猫运维中台系统" /> <img src={this.getImageUrl(item)} alt="熊猫运维中台系统" />
<span className={styles.iconBtn}> <span className={styles.iconBtn}>
<CheckCircleFilled /> <CheckCircleFilled />
</span> </span>
......
...@@ -3,12 +3,12 @@ import { Helmet } from 'react-helmet'; ...@@ -3,12 +3,12 @@ import { Helmet } from 'react-helmet';
import { renderRoutes } from 'react-router-config'; import { renderRoutes } from 'react-router-config';
import { BrowserRouter as Router, Switch } from 'react-router-dom'; import { BrowserRouter as Router, Switch } from 'react-router-dom';
import { appConnector } from './store'; import { appConnector } from './store';
import config from '../../routes/config';
import Authozed from '@/utils/authority'; import Authozed from '@/utils/authority';
import UserLogin from '@/pages/user/login'; import UserLogin from '@/pages/user/login';
import UserLayout from '@/layouts/UserLayout'; import UserLayout from '@/layouts/UserLayout';
import { AUTHORITY, BASENAME } from '@/utils/constants'; import { AUTHORITY, BASENAME } from '@/utils/constants';
export default appConnector(function App(props) { export default appConnector(function App(props) {
const { routesConfig } = props;
return ( return (
<> <>
<Helmet titleTemplate="%s - 运维平台" defaultTitle="运维平台"> <Helmet titleTemplate="%s - 运维平台" defaultTitle="运维平台">
...@@ -23,7 +23,7 @@ export default appConnector(function App(props) { ...@@ -23,7 +23,7 @@ export default appConnector(function App(props) {
} }
authority={[AUTHORITY.LOGIN]} authority={[AUTHORITY.LOGIN]}
> >
<Switch>{renderRoutes(config.routes)}</Switch> <Switch>{renderRoutes(routesConfig.routes)}</Switch>
</Authozed> </Authozed>
</Router> </Router>
</> </>
......
...@@ -7,6 +7,7 @@ import ProLayout, { DefaultFooter } from '@ant-design/pro-layout'; ...@@ -7,6 +7,7 @@ import ProLayout, { DefaultFooter } from '@ant-design/pro-layout';
import logo from '../assets/images/logo/panda-logo.svg'; import logo from '../assets/images/logo/panda-logo.svg';
import RightContent from '../components/GlobalHeader/RightContent'; import RightContent from '../components/GlobalHeader/RightContent';
import { BASENAME } from '@/utils/constants';
// const noMatch = ( // const noMatch = (
// <Result // <Result
...@@ -27,15 +28,16 @@ const defaultFooterDom = ( ...@@ -27,15 +28,16 @@ const defaultFooterDom = (
const BasicLayout = props => { const BasicLayout = props => {
/* eslint-disable no-unused-vars */ /* eslint-disable no-unused-vars */
const [pathname, setPathname] = useState('/welcome'); const [pathname, setPathname] = useState(`/${BASENAME}`);
const filterMenu = menuRoutes => const filterMenu = menuRoutes =>
menuRoutes menuRoutes
.map(route => { .map(route => {
if (route.routes) route.routes = filterMenu(route.routes); const routeCopy = { ...route };
return route.hideMenu || if (routeCopy.routes) routeCopy.routes = filterMenu(routeCopy.routes);
(route.authority && !check(route.authority, true, false)) return routeCopy.hideMenu ||
(routeCopy.authority && !check(routeCopy.authority, true, false))
? null ? null
: route; : routeCopy;
}) })
.filter(Boolean); .filter(Boolean);
const handleMenuCollapse = () => {}; // get children authority const handleMenuCollapse = () => {}; // get children authority
......
...@@ -153,7 +153,7 @@ const AppMenu = () => { ...@@ -153,7 +153,7 @@ const AppMenu = () => {
</> </>
), ),
key: menu.menuID, key: menu.menuID,
icon: menu.leaf ? <FileOutlined /> : <FolderOpenOutlined />, // icon: menu.leaf ? <FileOutlined /> : <FolderOpenOutlined />,
// 判断它是否存在子集,若果存在就进行再次进行遍历操作,知道不存在子集便对其他的元素进行操作 // 判断它是否存在子集,若果存在就进行再次进行遍历操作,知道不存在子集便对其他的元素进行操作
children: haveChildren ? menu.children.map(i => mapTree(i)) : [], children: haveChildren ? menu.children.map(i => mapTree(i)) : [],
}; };
......
...@@ -48,10 +48,13 @@ const Login = props => { ...@@ -48,10 +48,13 @@ const Login = props => {
history.push(`/dbm/dbInit/`); history.push(`/dbm/dbInit/`);
} }
if (userMode === USER_MODE.COMMON) { if (userMode === USER_MODE.COMMON) {
const authority = [AUTHORITY.LOGIN, AUTHORITY.COMMON]; // const authority = [AUTHORITY.LOGIN, AUTHORITY.COMMON];
setAuthority(authority); // setAuthority(authority);
setAuth(authority); // setAuth(authority);
history.push(`/ou/orgList/`); // history.push(`/ou/orgList/`);
notification.warning({
message: msg || '没有权限!',
});
} }
} else { } else {
notification.warning({ notification.warning({
...@@ -60,7 +63,7 @@ const Login = props => { ...@@ -60,7 +63,7 @@ const Login = props => {
} }
setLoading(false); setLoading(false);
}) })
.then(e => { .catch(e => {
setLoading(false); setLoading(false);
notification.error({ notification.error({
message: e.message || '没有权限!', message: e.message || '没有权限!',
......
...@@ -14,10 +14,15 @@ import { ...@@ -14,10 +14,15 @@ import {
Tabs, Tabs,
Button, Button,
Spin, Spin,
Dropdown,
Menu,
} from 'antd'; } from 'antd';
import { import {
UserAddOutlined,
UsergroupAddOutlined, UsergroupAddOutlined,
EditOutlined,
EditTwoTone, EditTwoTone,
DeleteOutlined,
DeleteTwoTone, DeleteTwoTone,
ShareAltOutlined, ShareAltOutlined,
UnlockOutlined, UnlockOutlined,
...@@ -25,12 +30,14 @@ import { ...@@ -25,12 +30,14 @@ import {
StopOutlined, StopOutlined,
DoubleLeftOutlined, DoubleLeftOutlined,
DoubleRightOutlined, DoubleRightOutlined,
DownOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import PageContainer from '@/components/BasePageContainer'; import PageContainer from '@/components/BasePageContainer';
import voca from 'voca'; import voca from 'voca';
import zhCN from 'antd/es/locale/zh_CN'; import zhCN from 'antd/es/locale/zh_CN';
import { import {
addToOrg, addToOrg,
addToOrgs,
editOrgInfo, editOrgInfo,
getOneOUUserListNew, getOneOUUserListNew,
getUserByKey, getUserByKey,
...@@ -44,7 +51,9 @@ import { ...@@ -44,7 +51,9 @@ import {
deleteOrg as postDeleteOrg, deleteOrg as postDeleteOrg,
updateUserPassword, updateUserPassword,
setUserRelation, setUserRelation,
multiDeleteUsers,
} from '@/services/userCenter/userManage/api'; } from '@/services/userCenter/userManage/api';
import classnames from 'classnames';
import ListCardItem from '../orgnazation/listCardItem'; import ListCardItem from '../orgnazation/listCardItem';
import styles from './UserManage.less'; import styles from './UserManage.less';
...@@ -52,12 +61,13 @@ const UserManage = () => { ...@@ -52,12 +61,13 @@ const UserManage = () => {
const [treeLoading, setTreeLoading] = useState(false); const [treeLoading, setTreeLoading] = useState(false);
const [tableLoading, setTableLoading] = useState(false); const [tableLoading, setTableLoading] = useState(false);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [multiOperate, setMultiOperate] = useState(true); // 是否禁用用户批量操作
const [multiOperateButtonType, setMultiOperateButtonType] = useState(''); // 更改批量操作按钮样式
const [treeData, setTreeData] = useState([]); // 用户机构树 const [treeData, setTreeData] = useState([]); // 用户机构树
const [expandedKeys, setExpandedKeys] = useState(['']); // const [expandedKeys, setExpandedKeys] = useState(['']);
const [treeDataCopy, setTreeDataCopy] = useState([]); // 机构树数据备份,用于更改机构 const [treeDataCopy, setTreeDataCopy] = useState([]); // 机构树数据备份,用于更改机构
const [treeState, setTreeState] = useState(true); // 树第一次加载 const [treeState, setTreeState] = useState(true); // 树第一次加载
// const [treeDispaly, setTreeDispaly] = useState(''); // 1
const [treeVisible, setTreeVisible] = useState(true); // 树是否可见 const [treeVisible, setTreeVisible] = useState(true); // 树是否可见
const [tableData, setTableData] = useState([]); // 用户表 const [tableData, setTableData] = useState([]); // 用户表
const [orgFilters, setOrgFilters] = useState([]); // 用户列筛选 const [orgFilters, setOrgFilters] = useState([]); // 用户列筛选
...@@ -77,12 +87,17 @@ const UserManage = () => { ...@@ -77,12 +87,17 @@ const UserManage = () => {
const [freezeUserVisible, setFreezeUserVisible] = useState(false); // 冻结用户 const [freezeUserVisible, setFreezeUserVisible] = useState(false); // 冻结用户
const [deleteUserVisible, setDeleteUserVisible] = useState(false); // 删除用户 const [deleteUserVisible, setDeleteUserVisible] = useState(false); // 删除用户
const [orgTitle, setOrgTitle] = useState('机构'); // 弹框标题 const [orgTitle, setOrgTitle] = useState('当前机构'); // 弹框标题
const [tableLength, setTableLength] = useState(0); // 表格标题 const [tableLength, setTableLength] = useState(0); // 表格标题
const [orgID, setOrgID] = useState(); // 机构ID const [orgID, setOrgID] = useState(); // 机构ID
const [newOrgID, setNewOrgID] = useState(); // 更改机构新选择的ID const [newOrgID, setNewOrgID] = useState(); // 更改机构新选择的ID
const [currentUser, setCurrentUser] = useState({}); // 当前用户 const [currentUser, setCurrentUser] = useState({}); // 当前用户
const [userIDs, setUserIDs] = useState(''); // 批量删除的用户
const [orgIDs, setOrgIDs] = useState(''); // 批量操作的机构
const [multiDelete, setMultiDelete] = useState(false); // 是否批量删除用户
const [multiChangeOrgs, setMultiChangeOrgs] = useState(false); // 是否批量更改机构
const [rolelist, setRolelist] = useState([]); // 角色列表 const [rolelist, setRolelist] = useState([]); // 角色列表
const [stationlist, setStationlist] = useState([]); // 站点列表 const [stationlist, setStationlist] = useState([]); // 站点列表
const [roleValueList, setRoleValueList] = useState({}); // 勾选的角色列表 const [roleValueList, setRoleValueList] = useState({}); // 勾选的角色列表
...@@ -165,20 +180,44 @@ const UserManage = () => { ...@@ -165,20 +180,44 @@ const UserManage = () => {
dataIndex: 'ddid', dataIndex: 'ddid',
key: 'ddid', key: 'ddid',
width: 100, width: 100,
render: record => {
if (record) {
return (
<Tooltip title={record}>
<span style={{ color: '#50aefc', cursor: 'pointer' }}>
已绑定
</span>
</Tooltip>
);
}
return <span>未绑定</span>;
},
}, },
{ {
title: '微信账户', title: '微信账户',
dataIndex: 'wxid', dataIndex: 'wxid',
key: 'wxid', key: 'wxid',
width: 100, width: 100,
render: record => {
if (record) {
return (
<Tooltip title={record}>
<span style={{ color: '#50aefc', cursor: 'pointer' }}>
已绑定
</span>
</Tooltip>
);
}
return <span>未绑定</span>;
},
}, },
{ {
title: '操作', title: '操作',
key: 'action', key: 'action',
fixed: 'right', fixed: 'right',
width: 250, width: 210,
align: 'center', align: 'center',
render: (text, record) => ( render: record => (
<Space size="middle"> <Space size="middle">
<Tooltip title="关联角色"> <Tooltip title="关联角色">
<ShareAltOutlined <ShareAltOutlined
...@@ -238,11 +277,18 @@ const UserManage = () => { ...@@ -238,11 +277,18 @@ const UserManage = () => {
const [selectionType] = useState('checkbox'); const [selectionType] = useState('checkbox');
const rowSelection = { const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => { onChange: (selectedRowKeys, selectedRows) => {
console.log( console.log(selectedRowKeys.toString());
`selectedRowKeys: ${selectedRowKeys}`, console.log(selectedRows.map(item => item.OUID).toString());
'selectedRows: ', setUserIDs(selectedRowKeys.toString());
selectedRows, setOrgIDs(selectedRows.map(item => item.OUID).toString());
); // 选中行数大于1时设置批量操作可行
if (selectedRows.length > 1) {
setMultiOperate(false);
setMultiOperateButtonType('primary');
} else {
setMultiOperate(true);
setMultiOperateButtonType('default');
}
}, },
getCheckboxProps: record => ({ getCheckboxProps: record => ({
name: record.name, name: record.name,
...@@ -322,9 +368,8 @@ const UserManage = () => { ...@@ -322,9 +368,8 @@ const UserManage = () => {
setTableLength(temp.length); setTableLength(temp.length);
const table = temp.map((item, index) => { const table = temp.map((item, index) => {
item.key = index; item.key = index;
item.phoneCopy = item.phone;
item.phone = item.phone || '-'; item.phone = item.phone || '-';
item.ddid = item.ddid ? '已绑定' : '未绑定';
item.wxid = item.wxid ? '已绑定' : '未绑定';
return item; return item;
}); });
setTableData(table); setTableData(table);
...@@ -365,15 +410,22 @@ const UserManage = () => { ...@@ -365,15 +410,22 @@ const UserManage = () => {
const addUser = () => { const addUser = () => {
setUserVisible(true); setUserVisible(true);
}; };
// 在根目录下添加机构 // 添加顶级机构
const addOrg = (title, id) => { const addOrg = () => {
setAddOrgVisible(true); setAddOrgVisible(true);
setOrgTitle(title); setOrgID('-1');
setOrgID(id); addOrgForm.setFieldsValue({
OUName: '',
desrciption: '',
});
}; };
// 添加下级机构 // 添加下级机构
const addSubOrg = () => { const addSubOrg = () => {
setAddOrgVisible(true); setAddOrgVisible(true);
addOrgForm.setFieldsValue({
OUName: '',
desrciption: '',
});
}; };
// 编辑机构 // 编辑机构
const editOrg = () => { const editOrg = () => {
...@@ -396,6 +448,22 @@ const UserManage = () => { ...@@ -396,6 +448,22 @@ const UserManage = () => {
} }
}, [currentUser]); }, [currentUser]);
/** ***用户批量操作****** */
// 用户关联
const relateRoles = () => {
setRoleVisible(true);
};
// 更改机构
const changeOrgs = () => {
setChangeOrgVisible(true);
setMultiChangeOrgs(true);
};
// 删除用户
const deleteUsers = () => {
setDeleteUserVisible(true);
setMultiDelete(true);
};
/** ***右侧表格相关操作****** */ /** ***右侧表格相关操作****** */
// 用户关联 // 用户关联
const relateRole = record => { const relateRole = record => {
...@@ -413,6 +481,8 @@ const UserManage = () => { ...@@ -413,6 +481,8 @@ const UserManage = () => {
setPasswordVisible(true); setPasswordVisible(true);
passwordForm.setFieldsValue({ passwordForm.setFieldsValue({
oldpassword: record.password, oldpassword: record.password,
newPassword: '',
passwordConfirm: '',
}); });
setCurrentUser(record); setCurrentUser(record);
}; };
...@@ -423,7 +493,7 @@ const UserManage = () => { ...@@ -423,7 +493,7 @@ const UserManage = () => {
editUserForm.setFieldsValue({ editUserForm.setFieldsValue({
loginName: voca.stripTags(record.loginName), loginName: voca.stripTags(record.loginName),
userName: voca.stripTags(record.userName), userName: voca.stripTags(record.userName),
phone: record.phone || '', phone: record.phoneCopy || '',
email: record.email || '', email: record.email || '',
}); });
setCurrentUser(record); setCurrentUser(record);
...@@ -504,11 +574,13 @@ const UserManage = () => { ...@@ -504,11 +574,13 @@ const UserManage = () => {
message: '提交成功', message: '提交成功',
}); });
// 重新获取机构树与用户表 // 重新获取机构树与用户表
updateTrees().then(() => { updateTrees();
// 只能是字符串,数字没有选择效果 onSelect([`${res.OUID}`]);
onSelect([`${res.OUID}`]); // updateTrees().then(() => {
setExpandedKeys([`${res.OUID}`]); // // 只能是字符串,数字没有选择效果
}); // onSelect([`${res.OUID}`]);
// // setExpandedKeys([`${res.OUID}`]);
// });
} else { } else {
notification.error({ notification.error({
message: '提交失败', message: '提交失败',
...@@ -538,7 +610,7 @@ const UserManage = () => { ...@@ -538,7 +610,7 @@ const UserManage = () => {
// 重新获取机构树与用户表 // 重新获取机构树与用户表
updateTrees(); updateTrees();
onSelect([orgID]); onSelect([orgID]);
setExpandedKeys([`${orgID}`]); // setExpandedKeys([`${orgID}`]);
} else { } else {
notification.error({ notification.error({
message: '提交失败', message: '提交失败',
...@@ -611,7 +683,7 @@ const UserManage = () => { ...@@ -611,7 +683,7 @@ const UserManage = () => {
setRoleVisible(false); setRoleVisible(false);
// 跳转到新组织机构下的用户表 // 跳转到新组织机构下的用户表
onSelect([`${currentUser.OUID}`]); onSelect([`${currentUser.OUID}`]);
setExpandedKeys([`${currentUser.OUID}`]); // setExpandedKeys([`${currentUser.OUID}`]);
notification.success({ notification.success({
message: '提交成功', message: '提交成功',
}); });
...@@ -634,7 +706,7 @@ const UserManage = () => { ...@@ -634,7 +706,7 @@ const UserManage = () => {
setChangeOrgVisible(false); setChangeOrgVisible(false);
// 跳转到新组织机构下的用户表 // 跳转到新组织机构下的用户表
onSelect([newOrgID]); onSelect([newOrgID]);
setExpandedKeys([`${newOrgID}`]); // setExpandedKeys([`${newOrgID}`]);
notification.success({ notification.success({
message: '提交成功', message: '提交成功',
}); });
...@@ -648,17 +720,14 @@ const UserManage = () => { ...@@ -648,17 +720,14 @@ const UserManage = () => {
.catch(err => { .catch(err => {
message.error(err); message.error(err);
}); });
// 提交-修改密码 // 提交-批量更改机构
const submitChangePassword = () => const submitChangeOrgs = () =>
updateUserPassword( addToOrgs(userIDs, orgIDs, newOrgID)
currentUser.userID,
passwordForm.getFieldValue('password'),
passwordForm.getFieldValue('newPassword'),
passwordForm.getFieldValue('passwordConfirm'),
)
.then(res => { .then(res => {
if (res.success) { if (res.code === 0) {
setPasswordVisible(false); setChangeOrgVisible(false);
// 跳转到新组织机构下的用户表
onSelect([newOrgID]);
notification.success({ notification.success({
message: '提交成功', message: '提交成功',
}); });
...@@ -672,6 +741,46 @@ const UserManage = () => { ...@@ -672,6 +741,46 @@ const UserManage = () => {
.catch(err => { .catch(err => {
message.error(err); message.error(err);
}); });
// 提交-修改密码
const submitChangePassword = () => {
const password = passwordForm.getFieldValue('password');
const newPassword = passwordForm.getFieldValue('newPassword');
const passwordConfirm = passwordForm.getFieldValue('passwordConfirm');
if (newPassword && passwordConfirm && newPassword === passwordConfirm) {
updateUserPassword(
currentUser.userID,
password,
newPassword,
passwordConfirm,
)
.then(res => {
if (res.success) {
setPasswordVisible(false);
notification.success({
message: '提交成功',
});
} else {
notification.error({
message: '提交失败',
description: res.message,
});
}
})
.catch(err => {
message.error(err);
});
} else if (newPassword === '' || passwordConfirm === '') {
notification.error({
message: '提交失败',
description: '带*号为必填项,不能为空',
});
} else {
notification.error({
message: '提交失败',
description: '确认密码不一致!',
});
}
};
// 提交-编辑用户 // 提交-编辑用户
const submitEditUser = () => const submitEditUser = () =>
postEditUser( postEditUser(
...@@ -686,7 +795,7 @@ const UserManage = () => { ...@@ -686,7 +795,7 @@ const UserManage = () => {
setEditUserVisible(false); setEditUserVisible(false);
// 重新获取用户表 // 重新获取用户表
onSelect([`${currentUser.OUID}`]); onSelect([`${currentUser.OUID}`]);
setExpandedKeys([`${currentUser.OUID}`]); // setExpandedKeys([`${currentUser.OUID}`]);
notification.success({ notification.success({
message: '提交成功', message: '提交成功',
}); });
...@@ -715,7 +824,7 @@ const UserManage = () => { ...@@ -715,7 +824,7 @@ const UserManage = () => {
setFreezeUserVisible(false); setFreezeUserVisible(false);
// 重新获取用户表 // 重新获取用户表
onSelect([`${currentUser.OUID}`]); onSelect([`${currentUser.OUID}`]);
setExpandedKeys([`${currentUser.OUID}`]); // setExpandedKeys([`${currentUser.OUID}`]);
notification.success({ notification.success({
message: '提交成功', message: '提交成功',
}); });
...@@ -731,6 +840,7 @@ const UserManage = () => { ...@@ -731,6 +840,7 @@ const UserManage = () => {
message.error(err); message.error(err);
}); });
}; };
// 提交-删除用户
const submitDeleteUser = () => { const submitDeleteUser = () => {
postDeleteUser(currentUser.userID) postDeleteUser(currentUser.userID)
.then(res => { .then(res => {
...@@ -741,7 +851,32 @@ const UserManage = () => { ...@@ -741,7 +851,32 @@ const UserManage = () => {
}); });
// 重新获取用户表 // 重新获取用户表
onSelect([`${currentUser.OUID}`]); onSelect([`${currentUser.OUID}`]);
setExpandedKeys([`${currentUser.OUID}`]); // setExpandedKeys([`${currentUser.OUID}`]);
} else {
notification.error({
message: '提交失败',
description: res.message,
});
}
})
.catch(err => {
setTableLoading(false);
message.error(err);
});
};
// 提交-批量删除用户
const submitDeleteUsers = () => {
const temp = orgIDs.split(',');
const [org] = temp;
multiDeleteUsers(userIDs, org)
.then(res => {
if (res.code === 0) {
setDeleteUserVisible(false);
notification.success({
message: '提交成功',
});
// 重新获取用户表
onSelect([currentSelectOrg]);
} else { } else {
notification.error({ notification.error({
message: '提交失败', message: '提交失败',
...@@ -755,89 +890,117 @@ const UserManage = () => { ...@@ -755,89 +890,117 @@ const UserManage = () => {
}); });
}; };
/** ***操作按钮**** */
// 机构操作
const orgButtonMenu = (
<Menu>
<Menu.Item key="1" onClick={addUser} icon={<UserAddOutlined />}>
添加用户
</Menu.Item>
<hr />
<Menu.Item key="2" onClick={addSubOrg} icon={<UsergroupAddOutlined />}>
添加机构
</Menu.Item>
<Menu.Item key="3" onClick={editOrg} icon={<EditOutlined />}>
编辑机构
</Menu.Item>
<Menu.Item key="4" onClick={deleteOrg} icon={<DeleteOutlined />}>
删除机构
</Menu.Item>
</Menu>
);
// 用户批量操作
const userButtonMenu = (
<Menu>
<Menu.Item key="1" onClick={relateRoles} icon={<ShareAltOutlined />}>
批量关联角色
</Menu.Item>
<Menu.Item key="2" onClick={changeOrgs} icon={<ApartmentOutlined />}>
批量更改机构
</Menu.Item>
<Menu.Item key="3" onClick={deleteUsers} icon={<DeleteOutlined />}>
批量删除用户
</Menu.Item>
</Menu>
);
return ( return (
<PageContainer className={styles.userManageContainer}> <PageContainer className={styles.userManageContainer}>
<div className={styles.contentContainer}> <div className={styles.contentContainer}>
{/* 左侧机构树 */} {/* 左侧机构树 */}
<Spin spinning={treeLoading} tip="loading..."> <Spin spinning={treeLoading} tip="loading...">
<div className={treeVisible ? styles.orgContainer : styles.hide}> <div
{/* <div className={styles.orgContainer} style={{ display: treeDispaly }}> */} className={classnames({
<span style={{ margin: '10px' }}>机构列表</span> [styles.orgContainer]: true,
<Tooltip title="添加机构"> [styles.orgContainerHide]: !treeVisible,
<UsergroupAddOutlined })}
onClick={() => addOrg('根目录', '-1')} >
style={{ <div>
float: 'right', <span style={{ margin: '10px' }}>机构列表</span>
color: '#1890FF', <Tooltip title="添加顶级机构">
fontSize: '18px', <UsergroupAddOutlined
}} onClick={() => addOrg()}
/> style={{
</Tooltip> float: 'right',
{treeData.length > 0 && ( color: '#1890FF',
<Tree fontSize: '18px',
showIcon="true" }}
showLine={{ showLeafIcon: false }} />
// blockNode="true" </Tooltip>
autoExpandParent="true" {treeData.length > 0 && (
expandedKeys={[currentSelectOrg]} <Tree
selectedKeys={[currentSelectOrg]} showIcon="true"
onSelect={onSelect} showLine={{ showLeafIcon: false }}
treeData={treeData.map(t => mapTree(t))} // blockNode="true"
/> autoExpandParent="true"
)} expandedKeys={[currentSelectOrg]}
selectedKeys={[currentSelectOrg]}
onSelect={onSelect}
treeData={treeData.map(t => mapTree(t))}
/>
)}
</div>
<div className={styles.switcher}>
{treeVisible && (
<Tooltip title="隐藏机构列表">
<DoubleLeftOutlined onClick={() => setTreeVisible(false)} />
</Tooltip>
)}
{!treeVisible && (
<Tooltip title="显示机构列表">
<DoubleRightOutlined onClick={() => setTreeVisible(true)} />
</Tooltip>
)}
</div>
</div> </div>
</Spin> </Spin>
<div style={{ color: '#1890FF', marginTop: '35vh', fontSize: '18px' }}>
{treeVisible && (
<Tooltip title="隐藏机构列表">
<DoubleLeftOutlined
onClick={() => {
setTreeVisible(false);
// setTreeDispaly('none');
}}
/>
</Tooltip>
)}
{!treeVisible && (
<Tooltip title="显示机构列表">
<DoubleRightOutlined
onClick={() => {
setTreeVisible(true);
// setTreeDispaly('block');
}}
/>
</Tooltip>
)}
</div>
{/* 右侧用户表 */} {/* 右侧用户表 */}
<div className={styles.userContainer}> <div className={styles.userContainer}>
<div style={{ height: '50px' }}> <div style={{ height: '50px' }}>
<p style={{ margin: '16px 0 10px 16px', display: 'inline-block' }}> <p style={{ margin: '16px 0 10px 16px', display: 'inline-block' }}>
用户数量( {orgTitle}(共{tableLength}人)
<span className={styles.redText}>{tableLength}</span>
</p> </p>
<span style={{ float: 'right', margin: '10px' }}> <span style={{ float: 'right', margin: '10px' }}>
<Search <Search
style={{ width: 266 }} style={{ width: 300 }}
placeholder="搜索登录名称/用户名称/手机号" placeholder="请输入登录名称/用户名称/手机号"
onSearch={submitSearchUser} onSearch={submitSearchUser}
onChange={e => handleSearch(e)} onChange={e => handleSearch(e)}
enterButton enterButton
value={searchWord} value={searchWord}
/> />
<Button type="primary" onClick={addUser}> <Dropdown overlay={orgButtonMenu}>
添加用户 <Button type="primary">
</Button> 机构操作 <DownOutlined />
<Button type="primary" onClick={addSubOrg}> </Button>
添加机构 </Dropdown>
</Button> <Dropdown overlay={userButtonMenu} disabled={multiOperate}>
<Button type="primary" onClick={editOrg}> <Button type={multiOperateButtonType}>
编辑机构 用户批量操作 <DownOutlined />
</Button> </Button>
<Button type="primary" onClick={deleteOrg}> </Dropdown>
删除机构
</Button>
</span> </span>
</div> </div>
<Table <Table
...@@ -854,8 +1017,10 @@ const UserManage = () => { ...@@ -854,8 +1017,10 @@ const UserManage = () => {
loading={tableLoading} loading={tableLoading}
scroll={{ x: 'max-content' }} scroll={{ x: 'max-content' }}
pagination={{ pagination={{
showTotal: () => `共${tableLength}条`, showTotal: (total, range) =>
`第${range[0]}-${range[1]} 条/共 ${total} 条`,
pageSizeOptions: [10, 20, 50, 100], pageSizeOptions: [10, 20, 50, 100],
defaultPageSize: 20,
showQuickJumper: true, showQuickJumper: true,
showSizeChanger: true, showSizeChanger: true,
}} }}
...@@ -877,9 +1042,9 @@ const UserManage = () => { ...@@ -877,9 +1042,9 @@ const UserManage = () => {
<Form.Item <Form.Item
name="loginName" name="loginName"
label="登录名称" label="登录名称"
rules={[{ required: true, message: '不能为空' }]} rules={[{ required: true, message: '不能为空且不支持中文' }]}
> >
<Input placeholder="请输入登录名称" /> <Input placeholder="登录名称不支持中文" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name="password" name="password"
...@@ -895,17 +1060,35 @@ const UserManage = () => { ...@@ -895,17 +1060,35 @@ const UserManage = () => {
> >
<Input placeholder="请输入用户姓名" /> <Input placeholder="请输入用户姓名" />
</Form.Item> </Form.Item>
<Form.Item name="phone" label="手机号码"> <Form.Item
name="phone"
label="手机号码"
rules={[
{
pattern: new RegExp(/^1(3|4|5|6|7|8|9)\d{9}$/),
message: '请输入有效的手机号码!',
},
]}
>
<Input placeholder="请输入手机号码" /> <Input placeholder="请输入手机号码" />
</Form.Item> </Form.Item>
<Form.Item name="email" label="电子邮箱"> <Form.Item
<Input placeholder="请输入电子邮箱" /> name="email"
label="电子邮箱"
rules={[
{
type: 'email',
message: '请输入有效的电子邮箱!',
},
]}
>
<Input placeholder="请输入电子邮箱" autoComplete="off" />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>
{/* 添加下级机构 */} {/* 添加下级机构 */}
<Modal <Modal
title={`在${orgTitle}下添加机构`} title={orgID === '-1' ? '添加顶级机构' : `在${orgTitle}下添加机构`}
visible={addOrgVisible} visible={addOrgVisible}
onOk={submitAddOrg} onOk={submitAddOrg}
onCancel={() => setAddOrgVisible(false)} onCancel={() => setAddOrgVisible(false)}
...@@ -1000,8 +1183,11 @@ const UserManage = () => { ...@@ -1000,8 +1183,11 @@ const UserManage = () => {
<Modal <Modal
title="更改机构" title="更改机构"
visible={changeOrgVisible} visible={changeOrgVisible}
onOk={submitChangeOrg} onOk={multiChangeOrgs ? submitChangeOrgs : submitChangeOrg}
onCancel={() => setChangeOrgVisible(false)} onCancel={() => {
setChangeOrgVisible(false);
setMultiChangeOrgs(false);
}}
okText="确认" okText="确认"
cancelText="取消" cancelText="取消"
width="330px" width="330px"
...@@ -1076,11 +1262,29 @@ const UserManage = () => { ...@@ -1076,11 +1262,29 @@ const UserManage = () => {
> >
<Input placeholder="请输入用户姓名" /> <Input placeholder="请输入用户姓名" />
</Form.Item> </Form.Item>
<Form.Item name="phone" label="手机号码"> <Form.Item
name="phone"
label="手机号码"
rules={[
{
pattern: new RegExp(/^1(3|4|5|6|7|8|9)\d{9}$/),
message: '请输入有效的手机号码!',
},
]}
>
<Input placeholder="请输入手机号码" /> <Input placeholder="请输入手机号码" />
</Form.Item> </Form.Item>
<Form.Item name="email" label="电子邮箱"> <Form.Item
<Input placeholder="请输入电子邮箱" /> name="email"
label="电子邮箱"
rules={[
{
type: 'email',
message: '请输入有效的电子邮箱!',
},
]}
>
<Input placeholder="请输入电子邮箱" autoComplete="off" />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>
...@@ -1104,8 +1308,11 @@ const UserManage = () => { ...@@ -1104,8 +1308,11 @@ const UserManage = () => {
<Modal <Modal
title="确认删除用户" title="确认删除用户"
visible={deleteUserVisible} visible={deleteUserVisible}
onOk={submitDeleteUser} onOk={multiDelete ? submitDeleteUsers : submitDeleteUser}
onCancel={() => setDeleteUserVisible(false)} onCancel={() => {
setDeleteUserVisible(false);
setMultiDelete(false);
}}
okText="确认" okText="确认"
cancelText="取消" cancelText="取消"
> >
......
...@@ -30,7 +30,15 @@ ...@@ -30,7 +30,15 @@
display: block; display: block;
} }
} }
.ant-pagination-prev,.ant-pagination-next{
line-height: 8px !important;
}
.ant-input-search-button{
line-height: 1;
}
.ant-dropdown-menu-item > .anticon:first-child {
vertical-align: 0.15em !important;
}
} }
.redText{ .redText{
color: red; color: red;
...@@ -78,9 +86,13 @@ ...@@ -78,9 +86,13 @@
height: calc(100vh - 74px); height: calc(100vh - 74px);
float: left; float: left;
padding: 10px; padding: 10px;
width: 200px; padding-right: 22px;
width: 240px;
background: white; background: white;
overflow: auto; overflow: auto;
margin-right:10px;
transform: translateX(0px);
transition: transform 0.5s;
.ant-tree{ .ant-tree{
padding-top: 6px; padding-top: 6px;
.ant-tree-switcher{ .ant-tree-switcher{
...@@ -89,16 +101,25 @@ ...@@ -89,16 +101,25 @@
.ant-tree-switcher-line-icon{ .ant-tree-switcher-line-icon{
margin-left: 5px; margin-left: 5px;
} }
} }
}
.switcher{
color: #1890FF;
font-size: 18px;
position: absolute;
left: 220px;
top: 46%;
} }
} }
.hide{
display: none; .orgContainerHide{
transform: translateX(-230px);
} }
.userContainer{ .userContainer{
height: calc(100vh - 168px) !important; height: calc(100vh - 74px) !important;
flex: 1; flex: 1;
min-width: 840px; min-width: 760px;
background: white; background: white;
.ant-table-pagination{ .ant-table-pagination{
padding-right: 12px; padding-right: 12px;
...@@ -106,13 +127,12 @@ ...@@ -106,13 +127,12 @@
margin: 1px 0; margin: 1px 0;
padding:8px; padding:8px;
padding-right: 20px; padding-right: 20px;
.ant-pagination-prev,.ant-pagination-next{
line-height: 8px !important;
}
} }
.ant-btn-primary{ .ant-btn{
margin-left: 20px; margin: 0px 10px;
background: #50aefc; .ant-btn-primary{
background: #50aefc;
}
} }
.ant-input-search-button{ .ant-input-search-button{
margin-left: 0px !important; margin-left: 0px !important;
...@@ -133,6 +153,10 @@ ...@@ -133,6 +153,10 @@
border-right: white; border-right: white;
overflow: auto !important; overflow: auto !important;
} }
.ant-pagination{
z-index: 999;
border-top: 1px solid #f0eded;
}
} }
} }
} }
......
...@@ -193,7 +193,12 @@ export default props => { ...@@ -193,7 +193,12 @@ export default props => {
visible={visible} visible={visible}
maskClosable={false} maskClosable={false}
> >
<BaseForm {...formConfig} /> <BaseForm
{...formConfig}
onFinish={values => {
console.log(values);
}}
/>
</Drawer> </Drawer>
</div> </div>
); );
......
...@@ -33,7 +33,7 @@ const iconStyle = { verticalAlign: '0.125em' }; ...@@ -33,7 +33,7 @@ const iconStyle = { verticalAlign: '0.125em' };
const superAuthority = [USER_MODE.SUPER]; const superAuthority = [USER_MODE.SUPER];
const adminAuthority = [...superAuthority, USER_MODE.ADMIN]; const adminAuthority = [...superAuthority, USER_MODE.ADMIN];
const commonAuthority = [...adminAuthority, USER_MODE.COMMON]; // const commonAuthority = [...adminAuthority, USER_MODE.COMMON];
export default { export default {
routes: [ routes: [
...@@ -102,7 +102,7 @@ export default { ...@@ -102,7 +102,7 @@ export default {
path: '/userCenter', path: '/userCenter',
name: '用户中心', name: '用户中心',
component: BlankLayout, component: BlankLayout,
authority: commonAuthority, authority: adminAuthority,
icon: <UsergroupAddOutlined style={iconStyle} />, icon: <UsergroupAddOutlined style={iconStyle} />,
routes: [ routes: [
{ {
...@@ -133,7 +133,7 @@ export default { ...@@ -133,7 +133,7 @@ export default {
component: BlankLayout, component: BlankLayout,
name: '平台中心', name: '平台中心',
icon: <SettingOutlined style={iconStyle} />, icon: <SettingOutlined style={iconStyle} />,
authority: commonAuthority, authority: adminAuthority,
routes: [ routes: [
{ {
path: '/platformCenter/gis', path: '/platformCenter/gis',
...@@ -188,7 +188,7 @@ export default { ...@@ -188,7 +188,7 @@ export default {
component: BlankLayout, component: BlankLayout,
name: '应用中心', name: '应用中心',
icon: <HomeOutlined style={iconStyle} />, icon: <HomeOutlined style={iconStyle} />,
authority: commonAuthority, authority: adminAuthority,
routes: [ routes: [
{ {
path: '/productCenter/web', path: '/productCenter/web',
...@@ -212,7 +212,7 @@ export default { ...@@ -212,7 +212,7 @@ export default {
component: BlankLayout, component: BlankLayout,
name: '系统日志', name: '系统日志',
icon: <CopyOutlined style={iconStyle} />, icon: <CopyOutlined style={iconStyle} />,
authority: commonAuthority, authority: adminAuthority,
routes: [ routes: [
{ {
path: '/log/common', path: '/log/common',
......
import { post, postForm, get, PUBLISH_SERVICE } from '../index';
export const getImageBases = moduleName =>
get(`${PUBLISH_SERVICE}/FileCenter/GetFileUrls`, { moduleName });
...@@ -100,6 +100,15 @@ export const addToOrg = (userID, orgID, newOrgID) => ...@@ -100,6 +100,15 @@ export const addToOrg = (userID, orgID, newOrgID) =>
oldOUID: orgID, oldOUID: orgID,
newOUID: newOrgID, newOUID: newOrgID,
}); });
// 批量更改机构
export const addToOrgs = (userIDs, orgIDs, newOrgID) =>
get(`${PUBLISH_SERVICE}/UserCenter/ModifyUserRole`, {
_version: 9999,
_dc: Date.now(),
userIds: userIDs,
oldGroupIds: orgIDs,
newGroupId: newOrgID,
});
export const updateUserPassword = ( export const updateUserPassword = (
userID, userID,
...@@ -141,6 +150,14 @@ export const deleteUser = userID => ...@@ -141,6 +150,14 @@ export const deleteUser = userID =>
_dc: Date.now(), _dc: Date.now(),
userID, userID,
}); });
// 批量删除用户
export const multiDeleteUsers = (userIDs, orgIDs) =>
get(`${PUBLISH_SERVICE}/UserCenter/DeleteUsers`, {
_version: 9999,
_dc: Date.now(),
userIds: userIDs,
groupId: orgIDs,
});
export const setUserRelation = (userID, roleList = [], stationList) => export const setUserRelation = (userID, roleList = [], stationList) =>
post( post(
......
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