Commit 02708f8a authored by duanledexianxianxian's avatar duanledexianxianxian

sync code

parent a5fdbf8e
import { IConfig, IPlugin } from 'umi-types'; import { IConfig, IPlugin } from 'umi-types';
import defaultSettings from './defaultSettings'; // https://umijs.org/config/
import defaultSettings from './defaultSettings';
// https://umijs.org/config/
import slash from 'slash2'; import slash from 'slash2';
import webpackPlugin from './plugin.config'; import webpackPlugin from './plugin.config';
import theme from './theme.config';
const path = require('path');
const { pwa, primaryColor } = defaultSettings; const { pwa } = defaultSettings; // preview.pro.ant.design only do not use in your production ;
// preview.pro.ant.design only do not use in your production ;
// preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 // preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION } = process.env; const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION } = process.env;
...@@ -91,15 +89,232 @@ export default { ...@@ -91,15 +89,232 @@ export default {
routes: [ routes: [
{ {
path: '/', path: '/',
component: '../layouts/BasicLayout', component: '../layouts/BlankLayout',
Routes: ['src/pages/Authorized'],
authority: ['admin', 'user'],
routes: [ routes: [
{
path: '/404',
component: './404',
},
{
path: '/user',
component: '../layouts/UserLayout',
routes: [
{
path: '/user',
redirect: '/user/login',
},
{
name: 'login',
path: '/user/login',
component: './user/login',
},
],
},
{ {
path: '/', path: '/',
name: 'welcome', component: '../layouts/BasicLayout',
icon: 'smile', Routes: ['src/pages/Authorized'],
component: './Welcome', authority: ['user'],
routes: [
{
path: '/',
redirect: '/dashboard/analysis',
},
{
path: '/dashboard',
name: 'dashboard',
icon: 'dashboard',
routes: [
{
name: 'analysis',
path: '/dashboard/analysis',
component: './dashboard/analysis',
},
{
name: 'monitor',
path: '/dashboard/monitor',
component: './dashboard/monitor',
},
{
name: 'workplace',
path: '/dashboard/workplace',
component: './dashboard/workplace',
},
],
},
{
path: '/form',
icon: 'form',
name: 'form',
routes: [
{
name: 'basic-form',
path: '/form/basic-form',
component: './form/basic-form',
},
{
name: 'step-form',
path: '/form/step-form',
component: './form/step-form',
},
{
name: 'advanced-form',
path: '/form/advanced-form',
component: './form/advanced-form',
},
],
},
{
path: '/list',
icon: 'table',
name: 'list',
routes: [
{
path: '/list/search',
name: 'search-list',
component: './list/search',
routes: [
{
path: '/list/search',
redirect: '/list/search/articles',
},
{
name: 'articles',
path: '/list/search/articles',
component: './list/search/articles',
},
{
name: 'projects',
path: '/list/search/projects',
component: './list/search/projects',
},
{
name: 'applications',
path: '/list/search/applications',
component: './list/search/applications',
},
],
},
{
name: 'table-list',
path: '/list/table-list',
component: './list/table-list',
},
{
name: 'basic-list',
path: '/list/basic-list',
component: './list/basic-list',
},
{
name: 'card-list',
path: '/list/card-list',
component: './list/card-list',
},
],
},
{
path: '/profile',
name: 'profile',
icon: 'profile',
routes: [
{
name: 'basic',
path: '/profile/basic',
component: './profile/basic',
},
{
name: 'advanced',
path: '/profile/advanced',
component: './profile/advanced',
},
],
},
{
name: 'result',
icon: 'check-circle-o',
path: '/result',
routes: [
{
name: 'success',
path: '/result/success',
component: './result/success',
},
{
name: 'fail',
path: '/result/fail',
component: './result/fail',
},
],
},
{
name: 'exception',
icon: 'warning',
path: '/exception',
routes: [
{
name: '403',
path: '/exception/403',
component: './exception/403',
},
{
name: '404',
path: '/exception/404',
component: './exception/404',
},
{
name: '500',
path: '/exception/500',
component: './exception/500',
},
],
},
{
name: 'account',
icon: 'user',
path: '/account',
routes: [
{
name: 'center',
path: '/account/center',
component: './account/center',
},
{
name: 'settings',
path: '/account/settings',
component: './account/settings',
},
],
},
{
name: 'editor',
icon: 'highlight',
path: '/editor',
routes: [
{
name: 'flow',
path: '/editor/flow',
component: './editor/flow',
},
{
name: 'mind',
path: '/editor/mind',
component: './editor/mind',
},
{
name: 'koni',
path: '/editor/koni',
component: './editor/koni',
},
],
},
{
name: 'parameter',
icon: 'highlight',
path: '/parameter',
component: './system/parameter',
authority: ['user'],
},
],
}, },
{ {
component: './404', component: './404',
...@@ -110,10 +325,9 @@ export default { ...@@ -110,10 +325,9 @@ export default {
component: './404', component: './404',
}, },
], ],
// Theme for antd: https://ant.design/docs/react/customize-theme-cn // Theme for antd
theme: { // https://ant.design/docs/react/customize-theme-cn
'primary-color': primaryColor, theme,
},
define: { define: {
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION:
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION || '', // preview.pro.ant.design only do not use in your production ; preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION || '', // preview.pro.ant.design only do not use in your production ; preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
...@@ -158,6 +372,16 @@ export default { ...@@ -158,6 +372,16 @@ export default {
basePath: '/', basePath: '/',
}, },
chainWebpack: webpackPlugin, chainWebpack: webpackPlugin,
// 配置 webpack 的 resolve.alias 属性 默认src=>@
alias: {
src: path.join(__dirname, '../src'),
components: path.join(__dirname, '../src', 'components'),
utils: path.join(__dirname, '../src', 'utils'),
assets: path.join(__dirname, '../src', 'assets'),
themes: path.join(__dirname, '../src', 'themes'),
config: path.join(__dirname, '../src', '../config'),
public: path.join(__dirname, '../public'),
},
/* /*
proxy: { proxy: {
'/server/api/': { '/server/api/': {
......
...@@ -57,9 +57,9 @@ export default { ...@@ -57,9 +57,9 @@ export default {
primaryColor: '#43cec4', primaryColor: '#43cec4',
layout: 'sidemenu', layout: 'sidemenu',
contentWidth: 'Fluid', contentWidth: 'Fluid',
fixedHeader: false, fixedHeader: true,
autoHideHeader: false, autoHideHeader: false,
fixSiderbar: false, fixSiderbar: true,
colorWeak: false, colorWeak: false,
menu: { menu: {
locale: true, locale: true,
......
export const dva = { export const dva = {
config: { config: {
onError(e) { onError(e) {
console.error(e);
e.preventDefault(); e.preventDefault();
}, },
}, },
......
...@@ -20,7 +20,6 @@ const Authorized: React.FunctionComponent<AuthorizedProps> = ({ ...@@ -20,7 +20,6 @@ const Authorized: React.FunctionComponent<AuthorizedProps> = ({
authority, authority,
noMatch = null, noMatch = null,
}) => { }) => {
console.log('noMatch1', noMatch);
const childrenRender: React.ReactNode = typeof children === 'undefined' ? null : children; const childrenRender: React.ReactNode = typeof children === 'undefined' ? null : children;
const dom = check(authority, childrenRender, noMatch); const dom = check(authority, childrenRender, noMatch);
return <>{dom}</>; return <>{dom}</>;
......
...@@ -24,10 +24,6 @@ const checkPermissions = <T, K>( ...@@ -24,10 +24,6 @@ const checkPermissions = <T, K>(
target: T, target: T,
Exception: K, Exception: K,
): T | K | React.ReactNode => { ): T | K | React.ReactNode => {
console.log('authority:', authority);
console.log('currentAuthority:', currentAuthority);
console.log('target:', target);
console.log('noMatch2', Exception);
// 没有判定权限.默认查看所有 // 没有判定权限.默认查看所有
// Retirement authority, return target; // Retirement authority, return target;
if (!authority) { if (!authority) {
......
...@@ -10,8 +10,6 @@ type CurrentAuthorityType = string | string[] | (() => typeof CURRENT); ...@@ -10,8 +10,6 @@ type CurrentAuthorityType = string | string[] | (() => typeof CURRENT);
const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthorityType) => T) => ( const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthorityType) => T) => (
currentAuthority: CurrentAuthorityType, currentAuthority: CurrentAuthorityType,
): T => { ): T => {
console.log('currentAuthoritycurrentAuthority', currentAuthority);
if (currentAuthority) { if (currentAuthority) {
if (typeof currentAuthority === 'function') { if (typeof currentAuthority === 'function') {
CURRENT = currentAuthority(); CURRENT = currentAuthority();
...@@ -25,7 +23,6 @@ const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthority ...@@ -25,7 +23,6 @@ const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthority
} else { } else {
CURRENT = 'NULL'; CURRENT = 'NULL';
} }
console.log('CURRENT', CURRENT);
return Authorized; return Authorized;
}; };
......
...@@ -32,13 +32,17 @@ class AvatarDropdown extends React.Component<GlobalHeaderRightProps> { ...@@ -32,13 +32,17 @@ class AvatarDropdown extends React.Component<GlobalHeaderRightProps> {
router.push(`/account/${key}`); router.push(`/account/${key}`);
}; };
getUserName = (userName: string) => {
return userName.length > 10 ? `${userName.substr(0, 10)}...` : userName;
};
render(): React.ReactNode { render(): React.ReactNode {
const { currentUser = {}, menu } = this.props; const { currentUser = {}, menu } = this.props;
if (!menu) { if (!menu) {
return ( return (
<span className={`${styles.action} ${styles.account}`}> <span className={`${styles.action} ${styles.account}`}>
<Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" /> <Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
<span className={styles.name}>{currentUser.name}</span> <span className={styles.name}>{this.getUserName(currentUser.userName || '')}</span>
</span> </span>
); );
} }
...@@ -60,11 +64,14 @@ class AvatarDropdown extends React.Component<GlobalHeaderRightProps> { ...@@ -60,11 +64,14 @@ class AvatarDropdown extends React.Component<GlobalHeaderRightProps> {
</Menu> </Menu>
); );
return currentUser && currentUser.name ? ( console.log(currentUser.avatar);
return currentUser && currentUser.userName ? (
<HeaderDropdown overlay={menuHeaderDropdown}> <HeaderDropdown overlay={menuHeaderDropdown}>
<span className={`${styles.action} ${styles.account}`}> <span className={`${styles.action} ${styles.account}`}>
<Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" /> <Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
<span className={styles.name}>{currentUser.name}</span> <span className={styles.name} title={currentUser.userName}>
{this.getUserName(currentUser.userName || '')}
</span>
</span> </span>
</HeaderDropdown> </HeaderDropdown>
) : ( ) : (
......
import { ConnectProps, ConnectState } from '@/models/connect'; import { ConnectProps, ConnectState } from '@/models/connect';
import { Icon, Tooltip } from 'antd'; import { Icon, Tooltip, message } from 'antd';
import Avatar from './AvatarDropdown'; import Avatar from './AvatarDropdown';
import HeaderSearch from '../HeaderSearch'; import HeaderSearch from '../HeaderSearch';
import React from 'react'; import React from 'react';
...@@ -16,6 +16,11 @@ export interface GlobalHeaderRightProps extends ConnectProps { ...@@ -16,6 +16,11 @@ export interface GlobalHeaderRightProps extends ConnectProps {
layout: 'sidemenu' | 'topmenu'; layout: 'sidemenu' | 'topmenu';
} }
const goHelpPage = (e: React.MouseEvent) => {
e.preventDefault();
message.info('go go go! help page.');
};
const GlobalHeaderRight: React.SFC<GlobalHeaderRightProps> = props => { const GlobalHeaderRight: React.SFC<GlobalHeaderRightProps> = props => {
const { theme, layout } = props; const { theme, layout } = props;
let className = styles.right; let className = styles.right;
...@@ -26,40 +31,12 @@ const GlobalHeaderRight: React.SFC<GlobalHeaderRightProps> = props => { ...@@ -26,40 +31,12 @@ const GlobalHeaderRight: React.SFC<GlobalHeaderRightProps> = props => {
return ( return (
<div className={className}> <div className={className}>
<HeaderSearch
className={`${styles.action} ${styles.search}`}
placeholder={formatMessage({
id: 'component.globalHeader.search',
})}
dataSource={[
formatMessage({
id: 'component.globalHeader.search.example1',
}),
formatMessage({
id: 'component.globalHeader.search.example2',
}),
formatMessage({
id: 'component.globalHeader.search.example3',
}),
]}
onSearch={value => {
console.log('input', value);
}}
onPressEnter={value => {
console.log('enter', value);
}}
/>
<Tooltip <Tooltip
title={formatMessage({ title={formatMessage({
id: 'component.globalHeader.help', id: 'component.globalHeader.help',
})} })}
> >
<a <a href="#" className={styles.action} onClick={goHelpPage}>
target="_blank"
href="https://pro.ant.design/docs/getting-started"
rel="noopener noreferrer"
className={styles.action}
>
<Icon type="question-circle-o" /> <Icon type="question-circle-o" />
</a> </a>
</Tooltip> </Tooltip>
......
// import store from './utils/store';
export default { export default {
baseUrl: 'http://platform.kuopu.net:9080',
storeNameSpace: 'kim', storeNameSpace: 'kim',
headers: () => ({ request: {
Authorization: apiPrefix: '',
'eyJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjMzLCJ1c24iOiLmrKfpmLPljZrlrofmrKfpmLPljZrlrofmrKfpmLPljZrlrofmrKfpmLPljZrlrofmrKfpmLPljZrlrofmrKfpmLPljZrlrofmrKfpmLPljZrlrociLCJzdGEiOjE1NjE2MDE3ODA3NDksImxpZCI6Im91eWFuZ2JveXUifQ.PY2oCcc9ESRVw2UmAnvZddgrl6Ycn2462L7xvI4FCLY', baseUrl: 'http://platform.kuopu.net:9080',
}), resCodeKey: 'code', // 后台正常返回错误编码
resCodeKey: 'code', // 后台正常返回错误编码 resMessageKey: 'message', // 后台正常返回错误编码
resMessageKey: 'message', // 后台正常返回错误编码 successCode: 'sys.success', // 后台正常返回错误编码
successCode: 'sys.success', // 后台正常返回错误编码 isThrowError: true, // 默认为true
isThrowError: true, // 默认为true },
copyright: `${new Date().getFullYear()} KIM3.0技术中台部出品`, copyright: `${new Date().getFullYear()} KIM3.0技术中台部出品`,
homePage: '/dashboard/analysis', homePage: '/dashboard/analysis',
fileServerUrl: 'http://platform.kuopu.net:9008',
defaultAvatar: '/images/default-avatar.png',
}; };
@import '~antd/es/style/themes/default.less'; @import '~@/themes/vars.less';
html, html,
body, body,
...@@ -49,6 +49,40 @@ ol { ...@@ -49,6 +49,40 @@ ol {
// 覆盖antd design pro样式 // 覆盖antd design pro样式
:global { :global {
::-webkit-scrollbar {
width: 6px;
height: 6px;
margin-right: 10px;
/*background-color: #ddd;*/
}
/*滑块*/
::-webkit-scrollbar-thumb {
//background-color: #43cec4;
width: 6px;
height: 6px;
border-radius: 10px;
cursor: default;
margin-left: -10px;
background-color: rgba(170, 170, 170, 0.8);
transition: background-color 0.2s linear, width 0.2s ease-in-out;
-webkit-transition: background-color 0.2s linear, width 0.2s ease-in-out;
}
::-webkit-scrollbar-thumb:hover {
//background-color: #aaa;
background-color: #aaa;
}
/*滑道*/
::-webkit-scrollbar-track {
margin-right: 20px;
// box-shadow: inset 0 0 6px #333;
background-color: rgba(201, 201, 201, 0.8);
border-radius: 10px;
width: 6px;
}
.kim-layout { .kim-layout {
.ant-pro-sider-menu-logo { .ant-pro-sider-menu-logo {
padding-left: 8px; padding-left: 8px;
...@@ -60,5 +94,8 @@ ol { ...@@ -60,5 +94,8 @@ ol {
.ant-pro-global-header { .ant-pro-global-header {
// background: #43cec4; // background: #43cec4;
} }
.ant-pro-basicLayout-content {
margin: @space-sm;
}
} }
} }
...@@ -10,7 +10,7 @@ import ProLayout, { ...@@ -10,7 +10,7 @@ import ProLayout, {
Settings, Settings,
SettingDrawer, SettingDrawer,
} from '@ant-design/pro-layout'; } from '@ant-design/pro-layout';
import React, { useState } from 'react'; import React, { useState, useEffect } from 'react';
import Authorized from '@/utils/Authorized'; import Authorized from '@/utils/Authorized';
import Link from 'umi/link'; import Link from 'umi/link';
import router from 'umi/router'; import router from 'umi/router';
...@@ -21,7 +21,7 @@ import { formatMessage } from 'umi-plugin-react/locale'; ...@@ -21,7 +21,7 @@ import { formatMessage } from 'umi-plugin-react/locale';
import { isAntDesignPro } from '@/utils/utils'; import { isAntDesignPro } from '@/utils/utils';
import { message } from 'antd'; import { message } from 'antd';
import store from '@/utils/store'; import store from '@/utils/store';
import user from 'mock/user'; import { async } from 'q';
export interface BasicLayoutProps extends ProLayoutProps, Omit<ConnectProps, 'location'> { export interface BasicLayoutProps extends ProLayoutProps, Omit<ConnectProps, 'location'> {
breadcrumbNameMap: { breadcrumbNameMap: {
[path: string]: MenuDataItem; [path: string]: MenuDataItem;
...@@ -73,7 +73,10 @@ const footerRender: BasicLayoutProps['footerRender'] = (_, defaultDom) => { ...@@ -73,7 +73,10 @@ const footerRender: BasicLayoutProps['footerRender'] = (_, defaultDom) => {
}; };
const loadInitData = (dispatch: Dispatch) => { const loadInitData = (dispatch: Dispatch) => {
Promise.all([dispatch({ type: 'public/getUserInfo' }), dispatch({ type: 'public/getUserInfo' })]); return Promise.all([
dispatch({ type: 'user/getCurrent' }),
dispatch({ type: 'settings/getSettings' }),
]);
}; };
const BasicLayout: React.FC<BasicLayoutProps> = props => { const BasicLayout: React.FC<BasicLayoutProps> = props => {
...@@ -81,19 +84,19 @@ const BasicLayout: React.FC<BasicLayoutProps> = props => { ...@@ -81,19 +84,19 @@ const BasicLayout: React.FC<BasicLayoutProps> = props => {
/** /**
* constructor * constructor
*/ */
const [loaded, setLoaded] = useState(false); const [loaded, setLoaded] = useState(false);
useState(() => {
useEffect(() => {
if (dispatch) { if (dispatch) {
// 查看当前用户是否在登录状态 // 查看当前用户是否在登录状态
dispatch({ dispatch({
type: 'user/checkUserLoginStatus', type: 'user/checkLoginStatus',
}).then(({ code, data = false }: { code: string; data: boolean }) => { }).then(async ({ code, data = false }: { code: string; data: boolean }) => {
setLoaded(true);
if (code === 'sys.success') { if (code === 'sys.success') {
// 登录成功 // 登录成功
if (data) { if (data) {
loadInitData(dispatch); await loadInitData(dispatch);
setLoaded(true);
} else if (store.get('userId')) { } else if (store.get('userId')) {
store.set('token', ''); store.set('token', '');
store.set('userId', ''); store.set('userId', '');
...@@ -106,12 +109,8 @@ const BasicLayout: React.FC<BasicLayoutProps> = props => { ...@@ -106,12 +109,8 @@ const BasicLayout: React.FC<BasicLayoutProps> = props => {
} }
} }
}); });
// dispatch({
// type: 'settings/getSetting',
// });
} }
}); }, []);
/** /**
* init variables * init variables
*/ */
......
import { Reducer } from 'redux'; import { Reducer } from 'redux';
import { Subscription } from 'dva';
import { Effect } from './connect.d'; import { Effect } from './connect.d';
import { Subscription } from 'dva';
import { routerRedux } from 'dva/router';
import store from '@/utils/store';
import { getPageQuery } from '@/utils';
import { setAuthority } from '@/utils/authority';
import { reloadAuthorized } from '@/utils/Authorized';
import { NoticeIconData } from '@/components/NoticeIcon'; import { NoticeIconData } from '@/components/NoticeIcon';
import { queryNotices } from '@/services/user'; import { queryNotices } from '@/services/user';
import { login, logout } from '@/services/global';
export interface NoticeItem extends NoticeIconData { export interface NoticeItem extends NoticeIconData {
id: string; id: string;
...@@ -23,12 +28,13 @@ export interface GlobalModelType { ...@@ -23,12 +28,13 @@ export interface GlobalModelType {
fetchNotices: Effect; fetchNotices: Effect;
clearNotices: Effect; clearNotices: Effect;
changeNoticeReadState: Effect; changeNoticeReadState: Effect;
checkUserLoginStatus: Effect; login: Effect;
}; };
reducers: { reducers: {
changeLayoutCollapsed: Reducer<GlobalModelState>; changeLayoutCollapsed: Reducer<GlobalModelState>;
saveNotices: Reducer<GlobalModelState>; saveNotices: Reducer<GlobalModelState>;
saveClearedNotices: Reducer<GlobalModelState>; saveClearedNotices: Reducer<GlobalModelState>;
changeLoginStatus: Reducer<GlobalModelState>;
}; };
subscriptions: { setup: Subscription }; subscriptions: { setup: Subscription };
} }
...@@ -42,6 +48,41 @@ const GlobalModel: GlobalModelType = { ...@@ -42,6 +48,41 @@ const GlobalModel: GlobalModelType = {
}, },
effects: { effects: {
*login({ payload }, { call, put }) {
const { code, data } = yield call(login, payload);
if (code === 'sys.success') {
yield put({
type: 'changeLoginStatus',
payload: {},
});
reloadAuthorized();
const { token, userId } = data;
store.set('token', token);
store.set('userId', userId);
const urlParams = new URL(window.location.href);
const params = getPageQuery();
// 是否需要重定向
let { redirect } = params;
if (redirect) {
const redirectUrlParams = new URL(redirect);
// origin相同
if (redirectUrlParams.origin === urlParams.origin) {
redirect = redirect.substr(urlParams.origin.length);
if (redirect.match(/^\/.*#/)) {
redirect = redirect.substr(redirect.indexOf('#') + 1);
}
} else {
window.location.href = redirect;
return;
}
}
// else {
// redirect = config.homePage;
// }
yield put(routerRedux.replace(redirect || '/'));
}
},
*fetchNotices(_, { call, put, select }) { *fetchNotices(_, { call, put, select }) {
const data = yield call(queryNotices); const data = yield call(queryNotices);
yield put({ yield put({
...@@ -103,6 +144,12 @@ const GlobalModel: GlobalModelType = { ...@@ -103,6 +144,12 @@ const GlobalModel: GlobalModelType = {
}, },
reducers: { reducers: {
changeLoginStatus(state, { payload }) {
setAuthority('user');
return {
...state,
};
},
changeLayoutCollapsed(state = { notices: [], collapsed: true }, { payload }): GlobalModelState { changeLayoutCollapsed(state = { notices: [], collapsed: true }, { payload }): GlobalModelState {
return { return {
...state, ...state,
......
...@@ -2,11 +2,17 @@ import { Reducer } from 'redux'; ...@@ -2,11 +2,17 @@ import { Reducer } from 'redux';
import { message } from 'antd'; import { message } from 'antd';
import defaultSettings, { DefaultSettings } from '../../config/defaultSettings'; import defaultSettings, { DefaultSettings } from '../../config/defaultSettings';
import themeColorClient from '../components/SettingDrawer/themeColorClient'; import themeColorClient from '../components/SettingDrawer/themeColorClient';
import { getCurrentUserSetting } from '@/services/user';
import { Effect } from 'dva';
export interface SettingModelType { export interface SettingModelType {
namespace: 'settings'; namespace: 'settings';
state: DefaultSettings; state: DefaultSettings;
effects: {
getSettings: Effect;
};
reducers: { reducers: {
saveSettings: Reducer<DefaultSettings>;
getSetting: Reducer<DefaultSettings>; getSetting: Reducer<DefaultSettings>;
changeSetting: Reducer<DefaultSettings>; changeSetting: Reducer<DefaultSettings>;
}; };
...@@ -95,7 +101,44 @@ const updateColorWeak: (colorWeak: boolean) => void = colorWeak => { ...@@ -95,7 +101,44 @@ const updateColorWeak: (colorWeak: boolean) => void = colorWeak => {
const SettingModel: SettingModelType = { const SettingModel: SettingModelType = {
namespace: 'settings', namespace: 'settings',
state: defaultSettings, state: defaultSettings,
effects: {
*getSettings({ payload }, { call, put }) {
const { data, code } = yield call(getCurrentUserSetting, payload);
let settings = defaultSettings;
if (code === 'sys.success' && data) {
const {
appStyle,
appTheme,
navigatorStyle,
contentWidth,
fixedHead,
fixedSide,
hideHead,
} = data;
settings = {
...settings,
navTheme: appStyle === 0 ? 'light' : 'dark',
primaryColor: appTheme,
layout: navigatorStyle === 0 ? 'sidemenu' : 'topmenu',
contentWidth: contentWidth === 0 ? 'Fluid' : 'Fixed',
fixedHeader: fixedHead,
autoHideHeader: hideHead,
fixSiderbar: fixedSide,
};
}
yield put({
type: 'saveSettings',
payload: settings,
});
},
},
reducers: { reducers: {
saveSettings(state, { payload }) {
return {
...state,
...payload,
};
},
getSetting(state = defaultSettings) { getSetting(state = defaultSettings) {
const setting: Partial<DefaultSettings> = {}; const setting: Partial<DefaultSettings> = {};
const urlParams = new URL(window.location.href); const urlParams = new URL(window.location.href);
......
import { queryCurrent, query as queryUsers, checkUserLoginStatus } from '@/services/user'; import { checkUserLoginStatus, getCurrentUserInfo } from '@/services/user';
import { Effect } from 'dva'; import { Effect } from 'dva';
import { Reducer } from 'redux'; import { Reducer } from 'redux';
import config from '@/config';
export interface CurrentUser { const { fileServerUrl, defaultAvatar } = config;
export interface Role extends BaseModel {
roleId?: number;
roleName?: string;
roleCode?: string;
remark?: string;
roleState?: number;
}
export interface Menu extends BaseModel {
menuId?: number;
pMenuId?: number;
menuName?: string;
menuType?: number;
menuUrl?: string;
menuIcon?: string;
viewIndex?: number;
menuState?: number;
}
export interface Component extends BaseModel {
componentId?: number;
componentName?: string;
componentCode?: string;
menuId?: number;
componentType?: number;
componentState?: number;
}
export interface CurrentUser extends BaseModel {
userId?: string;
loginId?: string;
userPassword?: string;
userName?: string;
effDate?: string;
expDate?: string;
userTitle?: string;
mobilePhone?: string;
fixedPhone?: string;
userEmail?: string;
userState?: string;
lockState?: string;
userPortrait?: string;
avatar?: string; avatar?: string;
name?: string; enabled?: string;
title?: string; accountNonExpired?: string;
group?: string; credentialsNonExpired?: string;
signature?: string; accountNonLocked?: string;
tags?: { roleList?: Role[];
key: string; menuList?: Menu[];
label: string; componentList?: Component[];
}[]; allCount?: number;
unreadCount?: number; unreadCount?: number;
} }
export interface UserSetting {
enabled?: number;
appTheme?: string;
contentWidth?: number;
fixedHead?: number;
fixedSide?: number;
hideHead?: number;
navigatorStyle?: number;
settingId?: number;
userId?: number;
userSetting?: UserSetting;
}
export interface UserModelState { export interface UserModelState {
currentUser?: CurrentUser; currentUser?: CurrentUser;
} }
...@@ -24,9 +81,8 @@ export interface UserModelType { ...@@ -24,9 +81,8 @@ export interface UserModelType {
namespace: 'user'; namespace: 'user';
state: UserModelState; state: UserModelState;
effects: { effects: {
fetch: Effect; getCurrent: Effect;
fetchCurrent: Effect; checkLoginStatus: Effect;
checkUserLoginStatus: Effect;
}; };
reducers: { reducers: {
saveCurrentUser: Reducer<UserModelState>; saveCurrentUser: Reducer<UserModelState>;
...@@ -42,31 +98,29 @@ const UserModel: UserModelType = { ...@@ -42,31 +98,29 @@ const UserModel: UserModelType = {
}, },
effects: { effects: {
*fetch(_, { call, put }) { *checkLoginStatus({ payload }, { call }) {
const response = yield call(queryUsers); return yield call(checkUserLoginStatus, payload);
yield put({
type: 'save',
payload: response,
});
}, },
*fetchCurrent(_, { call, put }) { *getCurrent({ payload }, { call, put }) {
const response = yield call(queryCurrent); const { data, code } = yield call(getCurrentUserInfo, payload);
yield put({ yield put({
type: 'saveCurrentUser', type: 'saveCurrentUser',
payload: response, payload: { ...data },
}); });
}, const result = code === 'sys.success';
*checkUserLoginStatus({ payload }, { call }) { return result;
const res = yield call(checkUserLoginStatus, payload);
return res;
}, },
}, },
reducers: { reducers: {
saveCurrentUser(state, action) { saveCurrentUser(state, { payload }) {
const { userPortrait } = payload;
return { return {
...state, ...state,
currentUser: action.payload || {}, currentUser: {
avatar: userPortrait ? `${fileServerUrl}/${userPortrait}` : defaultAvatar,
...(payload || {}),
},
}; };
}, },
changeNotifyCount( changeNotifyCount(
...@@ -79,7 +133,7 @@ const UserModel: UserModelType = { ...@@ -79,7 +133,7 @@ const UserModel: UserModelType = {
...state, ...state,
currentUser: { currentUser: {
...state.currentUser, ...state.currentUser,
notifyCount: action.payload.totalCount, allCount: action.payload.totalCount,
unreadCount: action.payload.unreadCount, unreadCount: action.payload.unreadCount,
}, },
}; };
......
...@@ -14,11 +14,6 @@ const getRouteAuthority = (path: string, routeData: Route[]) => { ...@@ -14,11 +14,6 @@ const getRouteAuthority = (path: string, routeData: Route[]) => {
routeData.forEach(route => { routeData.forEach(route => {
// match prefix // match prefix
if (pathToRegexp(`${route.path}(.*)`).test(path)) { if (pathToRegexp(`${route.path}(.*)`).test(path)) {
console.log('----------------------');
console.log('route.path:', route.path);
console.log('path:', path);
console.log('route.authority:', route.authority);
authorities = route.authority || authorities; authorities = route.authority || authorities;
// 官方代码好像有问题https://github.com/ant-design/ant-design-pro/commit/4a10734dcf858c6363af719a5886a24ec1115b33#diff-2041540b332693486a24a543b6ba0cc8 // 官方代码好像有问题https://github.com/ant-design/ant-design-pro/commit/4a10734dcf858c6363af719a5886a24ec1115b33#diff-2041540b332693486a24a543b6ba0cc8
// // exact match // // exact match
......
...@@ -27,7 +27,7 @@ class Login extends React.Component { ...@@ -27,7 +27,7 @@ class Login extends React.Component {
const { username, password } = this.state; const { username, password } = this.state;
const { dispatch } = this.props; const { dispatch } = this.props;
dispatch({ dispatch({
type: 'userLogin/login', type: 'global/login',
payload: { userName: username, password }, payload: { userName: username, password },
}); });
}; };
......
import { routerRedux } from 'dva/router';
import { login } from '../services';
import store from '@/utils/store';
import { getPageQuery } from '@/utils';
import config from '@/config';
import { setAuthority } from '@/utils/authority';
import { reloadAuthorized } from '@/utils/Authorized';
const initData = {};
export default {
namespace: 'userLogin',
state: {
...initData,
},
effects: {
*login({ payload }, { call, put }) {
const { code, data } = yield call(login, payload);
if (code === 'sys.success') {
yield put({
type: 'changeLoginStatus',
payload: {},
});
reloadAuthorized();
const { token, userId } = data;
store.set('token', token);
store.set('userId', userId);
const urlParams = new URL(window.location.href);
const params = getPageQuery();
// 是否需要重定向
let { redirect } = params;
if (redirect) {
const redirectUrlParams = new URL(redirect);
// origin相同
if (redirectUrlParams.origin === urlParams.origin) {
redirect = redirect.substr(urlParams.origin.length);
if (redirect.match(/^\/.*#/)) {
redirect = redirect.substr(redirect.indexOf('#') + 1);
}
} else {
window.location.href = redirect;
return;
}
}
// else {
// redirect = config.homePage;
// }
yield put(routerRedux.replace(redirect || '/'));
}
},
},
reducers: {
clearData: () => ({ ...initData }),
changeLoginStatus(state, { payload }) {
setAuthority('user');
return {
...state,
};
},
},
};
import { post } from '@/utils/request';
export const login = data => post('/api/v1/login', data);
import { get, post, put } from '@/utils/request';
/**
* 登录
* @param data
*/
export const login = data => post('/api/v1/login', data);
/**
* 登出
*/
export const logout = () => put('/api/v1/logout');
/**
* 获取静态数据数据
* @param data
*/
export const getStaticData = data =>
get('/api/v1/params/businesses/paramList', { ...data, paramLocale: 'zh_CN' });
...@@ -15,4 +15,12 @@ export async function queryNotices(): Promise<any> { ...@@ -15,4 +15,12 @@ export async function queryNotices(): Promise<any> {
/** /**
* 查看是否已经登录 * 查看是否已经登录
*/ */
export const checkUserLoginStatus = () => get(`/api/v1/login/status`); export const checkUserLoginStatus = async () => get(`/api/v1/login/status`);
/**
* 查看当前用户信息
*/
export const getCurrentUserInfo = async () => get(`/api/v1/detail`);
/**
* 获取用户配置信息
*/
export const getCurrentUserSetting = async () => get(`/api/v1/profile/settings`);
...@@ -32,3 +32,10 @@ declare let ga: Function; ...@@ -32,3 +32,10 @@ declare let ga: Function;
// preview.pro.ant.design only do not use in your production ; // preview.pro.ant.design only do not use in your production ;
// preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 // preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
declare let ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: 'site' | undefined; declare let ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: 'site' | undefined;
declare interface BaseModel {
creatorId?: number;
createdDate?: string;
editorId?: string;
editDate?: number;
}
...@@ -15,10 +15,6 @@ export function getAuthority(str?: string): string | string[] { ...@@ -15,10 +15,6 @@ export function getAuthority(str?: string): string | string[] {
if (typeof authority === 'string') { if (typeof authority === 'string') {
return [authority]; return [authority];
} }
console.log(
'ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION',
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION,
);
// preview.pro.ant.design only do not use in your production. // preview.pro.ant.design only do not use in your production.
// preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 // preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
if (!authority && ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') { if (!authority && ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') {
......
import axios from 'axios'; import axios from 'axios';
import { string } from 'prop-types';
class HttpRequest { class HttpRequest {
constructor(options) { constructor(options) {
...@@ -7,6 +8,12 @@ class HttpRequest { ...@@ -7,6 +8,12 @@ class HttpRequest {
} }
getInsideConfig() { getInsideConfig() {
let headers = {};
if (this.options.headers instanceof Function) {
headers = this.options.headers();
} else {
headers = { ...this.options.headers };
}
const config = { const config = {
baseURL: this.options.baseUrl, // baseURL baseURL: this.options.baseUrl, // baseURL
timeout: 10000, timeout: 10000,
...@@ -17,7 +24,7 @@ class HttpRequest { ...@@ -17,7 +24,7 @@ class HttpRequest {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Accept: 'application/json', Accept: 'application/json',
'X-Requested-With': 'XMLHttpRequest', 'X-Requested-With': 'XMLHttpRequest',
...this.options.headers, ...headers,
}, },
}; };
return config; return config;
......
import { notification } from 'antd'; import { notification } from 'antd';
import HttpRequest from './kim-request'; import HttpRequest from './kim-request';
import config from '@/config'; import config from '@/config';
import store from '@/utils/store';
/** /**
* todo 还需处理国际化 * todo 还需处理国际化
...@@ -24,13 +25,15 @@ const codeMessage = { ...@@ -24,13 +25,15 @@ const codeMessage = {
504: '网关超时。', 504: '网关超时。',
}; };
const { const {
baseUrl, request: {
apiPrefix, baseUrl,
headers, apiPrefix,
resCodeKey, resCodeKey,
resMessageKey, resMessageKey,
successCode, successCode,
isThrowError = true, isThrowError = true,
redirectFunc,
},
} = config; } = config;
/** /**
...@@ -48,9 +51,13 @@ const mergeApi = (url, more) => { ...@@ -48,9 +51,13 @@ const mergeApi = (url, more) => {
return url; return url;
}; };
const headers = () => ({
Authorization: store.get('token'),
});
const axios = new HttpRequest({ const axios = new HttpRequest({
baseUrl, baseUrl,
headers: headers() || {}, headers: headers || {},
}); });
/** /**
......
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