权限管理

feature/2.0-sales-trade
尹诚诚 3 years ago
parent ec8b39c08d
commit c88f0118d9

27
package-lock.json generated

@ -10,6 +10,7 @@
"dependencies": { "dependencies": {
"@ant-design/charts": "^1.4.2", "@ant-design/charts": "^1.4.2",
"antd": "^4.22.6", "antd": "^4.22.6",
"dingtalk-jsapi": "^3.0.9",
"mobx": "^6.6.1", "mobx": "^6.6.1",
"mobx-react": "^7.5.2", "mobx-react": "^7.5.2",
"react": "^18.2.0", "react": "^18.2.0",
@ -7378,6 +7379,14 @@
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
} }
}, },
"node_modules/dingtalk-jsapi": {
"version": "3.0.9",
"resolved": "https://registry.npmmirror.com/dingtalk-jsapi/-/dingtalk-jsapi-3.0.9.tgz",
"integrity": "sha512-MbepraXPj4KUkkny7XbJE9amh0oJsRhVK3MVCpxOX0XumzZdIUe+5HbW9j87oaVYseqt/fmeyO6phZtZp6HTdg==",
"dependencies": {
"promise-polyfill": "^7.1.0"
}
},
"node_modules/dir-glob": { "node_modules/dir-glob": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz", "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
@ -14862,6 +14871,11 @@
"asap": "~2.0.6" "asap": "~2.0.6"
} }
}, },
"node_modules/promise-polyfill": {
"version": "7.1.2",
"resolved": "https://registry.npmmirror.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz",
"integrity": "sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ=="
},
"node_modules/prompts": { "node_modules/prompts": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz", "resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz",
@ -24699,6 +24713,14 @@
"resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-27.5.1.tgz", "resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-27.5.1.tgz",
"integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==" "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ=="
}, },
"dingtalk-jsapi": {
"version": "3.0.9",
"resolved": "https://registry.npmmirror.com/dingtalk-jsapi/-/dingtalk-jsapi-3.0.9.tgz",
"integrity": "sha512-MbepraXPj4KUkkny7XbJE9amh0oJsRhVK3MVCpxOX0XumzZdIUe+5HbW9j87oaVYseqt/fmeyO6phZtZp6HTdg==",
"requires": {
"promise-polyfill": "^7.1.0"
}
},
"dir-glob": { "dir-glob": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz", "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
@ -30395,6 +30417,11 @@
"asap": "~2.0.6" "asap": "~2.0.6"
} }
}, },
"promise-polyfill": {
"version": "7.1.2",
"resolved": "https://registry.npmmirror.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz",
"integrity": "sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ=="
},
"prompts": { "prompts": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz", "resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz",

@ -5,6 +5,7 @@
"dependencies": { "dependencies": {
"@ant-design/charts": "^1.4.2", "@ant-design/charts": "^1.4.2",
"antd": "^4.22.6", "antd": "^4.22.6",
"dingtalk-jsapi": "^3.0.9",
"mobx": "^6.6.1", "mobx": "^6.6.1",
"mobx-react": "^7.5.2", "mobx-react": "^7.5.2",
"react": "^18.2.0", "react": "^18.2.0",

@ -25,6 +25,7 @@
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<title>React App</title> <title>React App</title>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>

@ -13,6 +13,7 @@ import Home from "./views/Home"
import Dashboard from "./views/Dashboard" import Dashboard from "./views/Dashboard"
import Orders from "./views/Orders" import Orders from "./views/Orders"
import Orders_sub from "./views/Orders_sub" import Orders_sub from "./views/Orders_sub"
import ProtectedRoute from "./views/ProtectedRoute"
import Customer_care_inchina from "./charts/Customer_care_inchina" import Customer_care_inchina from "./charts/Customer_care_inchina"
import Customer_care_potential from "./charts/Customer_care_potential" import Customer_care_potential from "./charts/Customer_care_potential"
import Customer_care_regular from "./charts/Customer_care_regular" import Customer_care_regular from "./charts/Customer_care_regular"
@ -44,6 +45,7 @@ class App extends Component {
children: [ children: [
{key: 412, label: <NavLink to="/order">损益表</NavLink>}, {key: 412, label: <NavLink to="/order">损益表</NavLink>},
{key: 41, label: <NavLink to="/order">信用卡账单</NavLink>}, {key: 41, label: <NavLink to="/order">信用卡账单</NavLink>},
{key: 42, label: <NavLink to="/auth">测试登陆</NavLink>},
] ]
}, },
@ -60,7 +62,8 @@ class App extends Component {
<Sider collapsible={false} defaultCollapsed={false} breakpoint="lg" <Sider collapsible={false} defaultCollapsed={false} breakpoint="lg"
collapsedWidth="0"> collapsedWidth="0">
<Image src={Logo} preview={false}/> <Image src={Logo} preview={false}/>
<Menu theme="dark" defaultSelectedKeys={['1']} defaultOpenKeys={['3']} mode="inline" items={menu_items}/> <Menu theme="dark" defaultSelectedKeys={['1']} defaultOpenKeys={['3']} mode="inline"
items={menu_items}/>
</Sider> </Sider>
<Layout className="site-layout"> <Layout className="site-layout">
<Content style={{ <Content style={{
@ -68,14 +71,18 @@ class App extends Component {
minHeight: 480, minHeight: 480,
}}> }}>
<Routes> <Routes>
<Route path="/" element={<Home/>}/> <Route element={<ProtectedRoute auth={['admin', 'director_bu']}/>}>
<Route path="/orders" element={<Orders/>}/> <Route path="/" element={<Home/>}/>
<Route path="/orders_sub/:ordertype/:ordertype_sub/:ordertype_title" <Route path="/orders" element={<Orders/>}/>
element={<Orders_sub/>}/> <Route path="/orders_sub/:ordertype/:ordertype_sub/:ordertype_title"
<Route path="/customer_care_inchina" element={<Customer_care_inchina/>}/> element={<Orders_sub/>}/>
<Route path="/customer_care_regular" element={<Customer_care_regular/>}/> <Route path="/dashboard" element={<Dashboard/>}/>
<Route path="/customer_care_potential" element={<Customer_care_potential/>}/> </Route>
<Route path="/dashboard" element={<Dashboard/>}/> <Route element={<ProtectedRoute auth={['admin', 'customer_care']}/>}>
<Route path="/customer_care_inchina" element={<Customer_care_inchina/>}/>
<Route path="/customer_care_regular" element={<Customer_care_regular/>}/>
<Route path="/customer_care_potential" element={<Customer_care_potential/>}/>
</Route>
</Routes> </Routes>
</Content> </Content>
<Footer <Footer

@ -28,20 +28,19 @@ const Customer_care_inchina = () => {
return ( return (
<div> <div>
<Row> <Row>
<Col span={12}> <Col span={8}>
<h2>在华客人</h2> <h2>在华客人</h2>
</Col> </Col>
<Col span={11}> <Col span={15}>
<Row> <Row>
<Col span={6}> <Col span={6}>
<SiteSelect store={inchina_data} show_all={true}/> <SiteSelect store={inchina_data} show_all={true}/>
</Col> </Col>
<Col span={18}> <GroupSelect store={inchina_data}/></Col> <Col span={18}> <GroupSelect store={inchina_data}/></Col>
<Col span={10}> <Col span={24}> <Space>
<DatePickerCharts hide_vs={true}/> <DatePickerCharts hide_vs={true}/>
</Col>
<Col span={14}>
<Space>
<Radio.Group value={inchina_data.date_type} <Radio.Group value={inchina_data.date_type}
onChange={inchina_data.onChange_datetype}> onChange={inchina_data.onChange_datetype}>
<Radio value="applyDate">预定日期</Radio> <Radio value="applyDate">预定日期</Radio>

@ -28,20 +28,18 @@ const Customer_care_potential = () => {
return ( return (
<div> <div>
<Row> <Row>
<Col span={12}> <Col span={8}>
<h2>潜力客户</h2> <h2>潜力客户</h2>
</Col> </Col>
<Col span={11}> <Col span={15}>
<Row> <Row>
<Col span={6}> <Col span={6}>
<SiteSelect store={potential_data} show_all={true}/> <SiteSelect store={potential_data} show_all={true}/>
</Col> </Col>
<Col span={18}> <GroupSelect store={potential_data}/></Col> <Col span={18}> <GroupSelect store={potential_data}/></Col>
<Col span={10}> <Col span={24}> <Space>
<DatePickerCharts hide_vs={true}/> <DatePickerCharts hide_vs={true}/>
</Col>
<Col span={14}>
<Space>
<Radio.Group value={potential_data.date_type} <Radio.Group value={potential_data.date_type}
onChange={potential_data.onChange_datetype}> onChange={potential_data.onChange_datetype}>
<Radio value="applyDate">预定日期</Radio> <Radio value="applyDate">预定日期</Radio>

@ -28,20 +28,18 @@ const Customer_care_regular = () => {
return ( return (
<div> <div>
<Row> <Row>
<Col span={12}> <Col span={8}>
<h2>老客户</h2> <h2>老客户</h2>
</Col> </Col>
<Col span={11}> <Col span={15}>
<Row> <Row>
<Col span={6}> <Col span={6}>
<SiteSelect store={regular_data} show_all={true}/> <SiteSelect store={regular_data} show_all={true}/>
</Col> </Col>
<Col span={18}> <GroupSelect store={regular_data}/></Col> <Col span={18}> <GroupSelect store={regular_data}/></Col>
<Col span={10}> <Col span={24}> <Space>
<DatePickerCharts hide_vs={true}/> <DatePickerCharts hide_vs={true}/>
</Col>
<Col span={14}>
<Space>
<Radio.Group value={regular_data.date_type} <Radio.Group value={regular_data.date_type}
onChange={regular_data.onChange_datetype}> onChange={regular_data.onChange_datetype}>
<Radio value="applyDate">预定日期</Radio> <Radio value="applyDate">预定日期</Radio>

@ -0,0 +1,62 @@
import {makeAutoObservable, runInAction} from "mobx";
import * as dd from 'dingtalk-jsapi';
import * as config from "../config";
import {Outlet, Navigate} from 'react-router-dom';
//权限管理
class AuthStore {
constructor(rootStore) {
this.rootStore = rootStore;
makeAutoObservable(this);
this.get_auth_info();
}
auth = [];
has_permission(requireds) {
if (Object.keys(requireds).length == 0) {
return true;
}
let has_permission = requireds.filter(item => this.auth.includes(item));
if (Object.keys(has_permission).length !== 0) {
return true;
}
return false;
}
get_auth_info() {
if (this.auth == false) { //如果没有权限,则去请求获取
this.auth = ['customer_care'];
}
return;
const CORPID = 'ding48bce8fd3957c96b';//企业的id
dd.runtime.permission.requestAuthCode({
corpId: CORPID,
onSuccess: function (res) {
let code = res.code;
runInAction(() => {
this.auth = ['admin'];
})
let url = '?code=' + code;
//请求获取HT接口获取用户权限和用户信息
fetch(config.HT_HOST + url)
.then((response) => response.json())
.then((json) => {
console.log(json);
})
.catch((error) => {
console.log('fetch data failed', error);
});
},
onFail: function (err) {
console.log(err)
}
});
}
}
export default AuthStore;

@ -66,10 +66,10 @@ class CustomerStore {
loading: false, loading: false,
data: [], data: [],
data_detail: [], data_detail: [],
webcode: 'GHKYHW', webcode: 'GHKYZG',
site_select_mode: false,//站点是否多选 site_select_mode: false,//站点是否多选
group_select_mode: 'multiple',//是否多选分组 group_select_mode: 'multiple',//是否多选分组
groups: ['1', '2', '28', '7'], groups: ['1', '2', '7'],
date_type: 'applyDate', date_type: 'applyDate',
handleChange: this.handleChange_group_select.bind(this), handleChange: this.handleChange_group_select.bind(this),
onChange_datetype: this.onChange_datetype.bind(this), onChange_datetype: this.onChange_datetype.bind(this),

@ -3,6 +3,7 @@ import OrdersStore from "./OrdersStore";
import DashboardStore from "./DashboardStore"; import DashboardStore from "./DashboardStore";
import DatePickerStore from "./DatePickerStore"; import DatePickerStore from "./DatePickerStore";
import CustomerStore from "./CustomerStore"; import CustomerStore from "./CustomerStore";
import AuthStore from "./AuthStore";
class Index { class Index {
@ -11,6 +12,7 @@ class Index {
this.orders_store = new OrdersStore(this); this.orders_store = new OrdersStore(this);
this.date_picker_store = new DatePickerStore(this); this.date_picker_store = new DatePickerStore(this);
this.customer_store = new CustomerStore(this); this.customer_store = new CustomerStore(this);
this.auth_store = new AuthStore(this);
makeAutoObservable(this); makeAutoObservable(this);
} }

@ -1,23 +1,21 @@
import React, {Component} from 'react'; import React, {Component, useContext} from 'react';
import { observer } from 'mobx-react'; import {observer} from 'mobx-react';
import {Row, Col, Button, Tabs, Table} from 'antd';
import {stores_Context} from '../config' import {stores_Context} from '../config'
import {useNavigate} from "react-router-dom";
class Home extends Component { const Home = () => {
static contextType = stores_Context;
constructor(props) { const navigate = useNavigate();
super(props); const {auth_store} = useContext(stores_Context);
}
render() { return (
const {orders_store} = this.context; <div>
这就是一个主页,什么也没写
<Button onClick={() => navigate('/auth')}>跳转</Button>
</div>
);
return (
<div>
这就是一个主页,什么也没写
</div>
);
}
} }
export default observer(Home); export default observer(Home);

@ -0,0 +1,36 @@
import React, {useContext, useEffect} from 'react';
import {Row, Col, Button, Tabs, Table, Result, Space} from 'antd';
import {
ContainerOutlined,
SearchOutlined,
} from '@ant-design/icons';
import {stores_Context} from '../config'
import {Line} from "@ant-design/charts";
import {observer} from 'mobx-react';
import DatePickerCharts from '../charts/DatePickerCharts'
import {NavLink, useParams} from "react-router-dom";
import * as comm from "../utils/commons";
import * as config from "../config";
import {Outlet, useOutlet, useLocation, useNavigate} from 'react-router-dom';
const ProtectedRoute = ({auth}) => {
const {auth_store} = useContext(stores_Context);
if (auth_store.has_permission(auth)) {
return <Outlet/>
}
return (
<div>
<Result
status="403"
title="403 权限不足"
subTitle={"试着联系一下技术 " + auth_store.code}
extra={<Button type="primary" onClick={() => auth_store.get_auth_info()}>测试免登 </Button>}
/>
</div>
);
}
export default observer(ProtectedRoute);
Loading…
Cancel
Save