This commit is contained in:
cclu 2025-02-26 16:08:15 +08:00
parent 8f84f22e95
commit beb008c078
6 changed files with 577 additions and 68 deletions

View File

@ -20,17 +20,12 @@ const handleCommonRes = (data: Record<string, unknown> | Record<string, unknown>
const userApi = { const userApi = {
//登录 //登录
'POST /api/user/login': async (req: Request, res: Response) => { 'POST /api/user/login': async (req: Request, res: Response) => {
console.log('req', req); const { UserPassWord, UserPassport, mobile, captcha } = req.body;
console.log('res', res);
return
const { password, username, mobile, captcha } = req.body;
await waitTime(2000); await waitTime(2000);
switch (true) { switch (true) {
case username === 'admin' && password === 'ant.design': case UserPassport === 'admin' && UserPassWord === 'ant.design':
case username === 'user' && password === 'ant.design': case UserPassport === 'user' && UserPassWord === 'ant.design':
case /^1\d{10}$/.test(mobile) && Boolean(captcha): case /^1\d{10}$/.test(mobile) && Boolean(captcha):
res.send( res.send(
handleCommonRes({ handleCommonRes({

View File

@ -1,7 +1,7 @@
.proLayoutBox{ .pageLayout{
.ant-layout{ .ant-layout{
.ant-layout-sider{ .ant-layout-sider{
background-color: #021529; background-color: #021529!important;
.ant-layout-sider-children{ .ant-layout-sider-children{
padding: 0; padding: 0;
.ant-pro-sider-logo{ .ant-pro-sider-logo{
@ -13,7 +13,7 @@
color: #fff; color: #fff;
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: 18px;
line-height: 32px; // line-height: 32px;
vertical-align: none; vertical-align: none;
margin-left: 12px; margin-left: 12px;
} }
@ -22,9 +22,6 @@
} }
.ant-layout-sider-children{ .ant-layout-sider-children{
.ant-pro-sider-extra{
margin: 0;
.ant-layout{
ul{ ul{
li{ li{
span{ span{
@ -40,8 +37,6 @@
} }
} }
} }
}
}
@ -53,4 +48,165 @@
padding: 0; padding: 0;
} }
} }
.tab-extra {
width: 13px;
height: 15px;
padding: 0 26px 16px 0;
// background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPCAYAAAA/I0V3AAAAAXNSR0IArs4c6QAAANhJREFUOE+9kT1rAlEQRc/MCmLjz7G1tUphKTbpBFs16BpZXkyCuqRLbaFYWqSytc3PSRMC7jxRMMQP5KVxypm5M5dzJXap558ltxN13Vs5skxCHWYa+eDlv0el5yYzRXKhnwy/uSGI2KUZoKH2ANvZawDvgUIDmnt6PTepCzIFrgHZePz9y6A9/0Xef0qr5lkI5E+tevhRoTZ8bC13s6Oc+sm4YqpLgcJB6OFbzarDpLM69M7C7bpxWdEPoAh8GXb3Ouisj8K9RC1ORiU0WmBZ7Tl5+Dzd2QIFbkkh8PpnKgAAAABJRU5ErkJggg==') ;
// background-repeat: no-repeat;
}
.ant-dropdown-open svg {
// color: @primary-color;
// background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPCAYAAAA/I0V3AAAAAXNSR0IArs4c6QAAAMZJREFUOE+9kb0KwkAQhGdUEBtfxpxtWisLS7GxE4Too3gH1hZKSgsrW1vj09iIkGQkghJ/kLPJlrs7u8M3NDYX/ixWKHIKlaX0dch6Q97L5aM0i2wN1hq+n6A8rRBEYPOMQM3XnoCcHasJoaWPsBAInN7pmYVGoFYAfgFJIY6TOTdP5MZpICkm0Hy3KuBKcphE3Bazl5yMVQ9QMWiVhBeAg2TG/aP3Ea5xCiHtALQBnEH2k4iHl3C/UQucupBikMNTxOP7zg3x4U00HiX/gwAAAABJRU5ErkJggg==');
}
.tab-extra:hover {
// background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPCAYAAAA/I0V3AAAAAXNSR0IArs4c6QAAAMZJREFUOE+9kb0KwkAQhGdUEBtfxpxtWisLS7GxE4Too3gH1hZKSgsrW1vj09iIkGQkghJ/kLPJlrs7u8M3NDYX/ixWKHIKlaX0dch6Q97L5aM0i2wN1hq+n6A8rRBEYPOMQM3XnoCcHasJoaWPsBAInN7pmYVGoFYAfgFJIY6TOTdP5MZpICkm0Hy3KuBKcphE3Bazl5yMVQ9QMWiVhBeAg2TG/aP3Ea5xCiHtALQBnEH2k4iHl3C/UQucupBikMNTxOP7zg3x4U00HiX/gwAAAABJRU5ErkJggg==');
}
.ant-modal-header {
background-color: #ecf2f7 !important;
border-bottom: none !important;
}
body *::-webkit-scrollbar {
/* 滚动条整体样式 */
width : 8px; /* 高宽分别对应横竖滚动条的尺寸 */
height: 8px;
}
body *::-webkit-scrollbar-thumb {
/* 滚动条里面小方块 */
background-color: #d1cfcf;
// background-image: -webkit-linear-gradient(
// 45deg,
// rgba(255, 255, 255, 0.2) 25%,
// transparent 25%,
// transparent 50%,
// rgba(255, 255, 255, 0.2) 50%,
// rgba(255, 255, 255, 0.562) 75%,
// transparent 75%,
// transparent
// );
border-radius: 10px;
}
body *::-webkit-scrollbar-track {
/* 滚动条里面轨道 */
background: #ededed;
border-radius: 10px;
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.01);
}
// 列表页左侧多选树
.pageTable-leftnav .ant-tree-list-holder{
height: calc(100vh - 257px);
padding-right: 0;
padding-bottom: 0;
overflow-y: auto;
}
.leftHeight .ant-tree-list-holder{
height: 100%!important;
}
.leftHeight .ant-tree-list{
height: 560px
}
.pageTable-leftnavs .ant-tree-list-holder{
height: 580px;
padding-right: 0;
padding-bottom: 0;
overflow-y: auto;
}
.pageTable-leftnav .ant-pro-card-header.ant-pro-card-header-border {
padding-top: 29px;
}
.pageTable-leftnav .ant-pro-card-title {
font-size: 14px;
}
.pageTable-leftnav .ant-pro-card-split-vertical{
transition: width 0.3s;
}
.pageTable-leftnav .ant-tree .ant-tree-treenode {
padding-bottom: 16px;
}
.pageTable-leftnavs .ant-tree .ant-tree-treenode {
padding-bottom: 16px;
}
.ant-table-tbody > tr.tablerow-no-border > td{
border-bottom: 0;
}
// prolist 卡片类型
.ant-pro-list .ant-pro-card-header {
padding: 0 !important;
}
.ant-pro-list .ant-pro-card.ant-pro-card-border.ant-pro-card-hoverable>.ant-pro-card-body {
margin: 0 !important;
padding: 20px 0 0 0 !important;
}
.ant-pro-list .ant-pro-card.ant-pro-card-border> ul.ant-pro-card-actions {
margin-top: 20px;
}
.ant-pro-list .ant-pro-card.ant-pro-card-border> ul.ant-pro-card-actions >li{
margin:0;
}
.ant-pro-list .ant-pro-card.ant-pro-card-border.ant-pro-card-hoverable> ul.ant-pro-card-actions > li, .ant-pro-list .ant-pro-card .ant-pro-card-actions .ant-space-item {
margin: 10px 0 0 0 !important;
}
} }
.main-tab >.ant-tabs-nav {
margin-bottom: 0 !important;
padding: 2px 15px 0 16px;
background-color: #fff;
}
.main-tab > .ant-tabs-nav .ant-tabs-tab {
background-color: #fafafa;
border-color: #f0f0f0;
border-bottom: 0;
}
.main-tab > .ant-tabs-nav .ant-tabs-tab button svg {
// color: #fff;
transition: all 0.3s;
}
.main-tab > .ant-tabs-nav .ant-tabs-tab:hover {
background-color:#fafafa;
border-color: #f0f0f0;
}
.main-tab > .ant-tabs-nav .ant-tabs-tab:hover button svg {
// color: @link-color;
}
.main-tab.ant-tabs-top > .ant-tabs-nav .ant-tabs-tab-active {
background-color: #f6f9fb;
border-color: #f0f0f0;
box-shadow: 2px 0 6px 0 #e7e7e7;
border-top-color: #3591fe;
}
.main-tab.ant-tabs-top > .ant-tabs-nav .ant-tabs-tab-active::before {
content: '';
position: absolute;
display: block;
background-color: #3591fe;
top: 0;
left: 0;
width: 100%;
height: 1px;
}
.main-tab > .ant-tabs-nav .ant-tabs-tab-active button svg {
// color: @icon-color;
}
.main-tab > .ant-tabs-content-holder {
height: calc(100vh - 86px);
padding-top: 16px;
overflow-y: auto;
}
.main-tab > .ant-tabs-nav .ant-tabs-nav-wrap {
bottom: 1px;
}

View File

@ -2,7 +2,7 @@ import type { FC } from 'react';
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { Dropdown, Layout, Menu, Tabs, Tooltip } from 'antd'; import { Dropdown, Layout, Menu, Tabs, Tooltip } from 'antd';
import type { MenuProps } from 'antd'; import type { MenuProps } from 'antd';
import { Outlet, Link, useLocation, connect } from 'umi'; import { Outlet, Link, useLocation, connect, history } from 'umi';
import PageAccess from '@/components/PageAccess'; import PageAccess from '@/components/PageAccess';
import type { UserConnectedProps, UserModelState } from '@/models/user'; import type { UserConnectedProps, UserModelState } from '@/models/user';
import LayoutWrapper from '@/components/LayoutWrapper'; import LayoutWrapper from '@/components/LayoutWrapper';
@ -18,6 +18,8 @@ import { ProfileModelState } from '@/models/global';
import React from 'react'; import React from 'react';
const { Header, Content } = Layout; const { Header, Content } = Layout;
const { TabPane } = Tabs;
/** /**
* openKeys的方法 * openKeys的方法
* @param currentLocation , handleGetCurrentLocation方法返回 * @param currentLocation , handleGetCurrentLocation方法返回
@ -43,7 +45,7 @@ const handleGetOpenKeys = (currentLocation: API.MenuItem[] | []): string[] => {
}; };
//自定义的layout页面, 顶部导航通栏+侧边栏(菜单)布局, 可根据需要做调整 //自定义的layout页面, 顶部导航通栏+侧边栏(菜单)布局, 可根据需要做调整
const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatch: any }> = (props) => { const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatch: any, location: any }> = (props) => {
const [collapsed, setCollapsed] = useState(false); const [collapsed, setCollapsed] = useState(false);
const [openKeys, setOpenKeys] = useState(['']); const [openKeys, setOpenKeys] = useState(['']);
const { pathname } = useLocation(); const { pathname } = useLocation();
@ -54,11 +56,12 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
indexValidMenuItemByPath indexValidMenuItemByPath
}, },
global: { global: {
tabsRoutes
} }
} = props; } = props;
console.log('props', props); console.log('props', props);
const [activeKey, setActiveKey] = useState<string>('/')
const validMenuItem = indexValidMenuItemByPath[pathname]; const validMenuItem = indexValidMenuItemByPath[pathname];
@ -140,17 +143,103 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
// 改变panes // 改变panes
const handleTabsPanes = (payload: any): void => { const handleTabsPanes = (payload: any): void => {
dispatch({ dispatch({
type: "global/saveTabsRoutes", type: 'global/changeTabsRoutes',
payload: { payload: { data: payload, action: 'add' },
data: payload, });
action: 'add'
}
})
}; };
// 关闭当前标签
const handleEdit = (targetKey: string | React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<Element>, action: "add" | "remove"): void => {
if (action === 'remove' && dispatch) {
const index = tabsRoutes.findIndex((n: { path: string }) => n.path === targetKey)
// 定位关闭当前标签后,需要选中的下一个标签
// eslint-disable-next-line no-nested-ternary
const nextkey = tabsRoutes[index + 1] ? tabsRoutes[index + 1].path : (tabsRoutes[index - 1] ? tabsRoutes[index - 1].path : '')
history.push(nextkey || '/')
setActiveKey(nextkey)
// 缓存路由栈数据
dispatch({
type: 'global/changeTabsRoutes',
payload: { data: [targetKey], action },
})
}
}
// 全部菜单一层的数组
const oneFloorList = [
{
SYSTEMMODULE_DESC: "",
guid: "1",
hideInMenu: false,
name: "首页",
path: "/",
},
{
SYSTEMMODULE_DESC: "",
guid: "2",
hideInMenu: false,
name: "关于你1",
path: "/about/u/1",
},
{
SYSTEMMODULE_DESC: "",
guid: "3",
hideInMenu: false,
name: "关于你2",
path: "/about/u/2",
},
{
SYSTEMMODULE_DESC: "",
guid: "4",
hideInMenu: false,
name: "(页面元素权限)关于我",
path: "/about/m",
},
{
SYSTEMMODULE_DESC: "",
guid: "5",
hideInMenu: false,
name: "关于你和我",
path: "/about/um",
},
{
SYSTEMMODULE_DESC: "",
guid: "5",
hideInMenu: false,
name: "(403)关于你教师",
path: "/teacher/u",
},
{
SYSTEMMODULE_DESC: "",
guid: "6",
hideInMenu: false,
name: "关于我教师",
path: "/teacher/m",
},
{
SYSTEMMODULE_DESC: "",
guid: "7",
hideInMenu: false,
name: "关于你和我教师",
path: "/teacher/um",
},
{
SYSTEMMODULE_DESC: "",
guid: "8",
hideInMenu: false,
name: "(404)学生",
path: "/student",
}
]
return ( return (
<LayoutWrapper> <LayoutWrapper>
<ProLayout <ProLayout
className={"pageLayout"}
logo={logo} logo={logo}
contentWidth={"Fluid"} contentWidth={"Fluid"}
fixedHeader={true} fixedHeader={true}
@ -206,11 +295,19 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
onPageChange={(location) => { onPageChange={(location) => {
console.log('location', location); console.log('location', location);
if (location?.pathname && location?.pathname !== '/') { if (location?.pathname && location?.pathname !== '/') {
const nextModule = consumableMenu.find(n => location?.pathname && n?.path && location?.pathname.match(n?.path)) console.log('oneFloorList', oneFloorList);
console.log('nextModule', nextModule);
// const nextModule = oneFloorList.find(n => location?.pathname && n?.path && location?.pathname.match(n?.path))
const nextModule: any = oneFloorList.filter(n => location?.pathname === n?.path)
console.log('nextModule', nextModule);
let title = ''
if (nextModule && nextModule.length > 0) {
// `${formatMessage({ id: `menu${title.substring(0, title?.indexOf('.detail'))}` })}详情`
title = nextModule[0].name
}
handleTabsPanes({ path: location?.pathname, key: location?.pathname, title: title })
setActiveKey(location?.pathname || '')
} }
handleTabsPanes({ path: location?.pathname, key: location?.pathname })
}} }}
> >
@ -240,12 +337,36 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
<Tabs <Tabs
hideAdd hideAdd
type="editable-card" type="editable-card"
onChange={(value) => {
history.push(value)
setActiveKey(value)
}}
activeKey={activeKey}
onEdit={handleEdit}
size="small" size="small"
className='main-tab' className='main-tab'
tabBarExtraContent={ tabBarExtraContent={
<Tooltip title="关闭选项卡" placement="topRight"> <Tooltip title="关闭选项卡" placement="topRight">
<Dropdown overlay={ <Dropdown overlay={
<Menu onClick={(targetKey) => { <Menu onClick={(targetKey) => {
let closeTabKeys: string[] = []
switch (targetKey.key) {
case 'other':
closeTabKeys = [...tabsRoutes.filter(n => n.path !== activeKey).map(n => n.path)];
break;
case 'now':
handleEdit(activeKey, 'remove')
return;
default:
closeTabKeys = [...tabsRoutes.map(n => n.path)];
history.push('/')
break;
}
dispatch({
type: 'global/changeTabsRoutes',
payload: { data: closeTabKeys, action: 'remove' },
})
}}> }}>
<Menu.Item key="other"></Menu.Item> <Menu.Item key="other"></Menu.Item>
<Menu.Item key="now"></Menu.Item> <Menu.Item key="now"></Menu.Item>
@ -266,7 +387,7 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
} }
moreIcon={<DoubleRightOutlined style={{ color: "#7b828c" }} />} moreIcon={<DoubleRightOutlined style={{ color: "#7b828c" }} />}
> >
{/* {tabsPanes && tabsPanes.map((item: any) => {tabsRoutes && tabsRoutes.map((item: any) =>
<TabPane <TabPane
tab={item.title} key={item?.path} tab={item.title} key={item?.path}
style={{ padding: 24, paddingTop: 0 }}> style={{ padding: 24, paddingTop: 0 }}>
@ -281,7 +402,7 @@ const BasicLayout: FC<{ user: UserModelState, global: ProfileModelState, dispatc
: <Page404 /> : <Page404 />
} }
</TabPane>) </TabPane>)
} */} }
</Tabs> </Tabs>
</Content> </Content>

View File

@ -1,22 +1,17 @@
// models/profile.ts // models/profile.ts
import session from '@/utils/session';
import { Effect, Reducer } from 'umi'; import { Effect, Reducer } from 'umi';
export interface ProfileModelState { export type ConnectState = {
avatar: string; global: GlobalModelState;
bio: string; };
}
export interface ProfileModelType { export type NoticeItem = {
namespace: 'global'; id: string;
state: any; type: string;
reducers: { status: string;
saveTabsRoutes: Reducer<GlobalModelState>; } & NoticeIconData;
};
effects: {
changeTabsRoutes: Effect;
};
}
export type tabsRoute = { export type tabsRoute = {
title: string; title: string;
@ -26,28 +21,161 @@ export type tabsRoute = {
} }
export type GlobalModelState = { export type GlobalModelState = {
collapsed: boolean;
notices: NoticeItem[];
tabsRoutes: tabsRoute[]; tabsRoutes: tabsRoute[];
menuData: MenuDataItem[];
moduleMap: MenuDataItem[];
}; };
const ProfileModel: ProfileModelType = { export type GlobalModelType = {
namespace: 'global', namespace: 'global';
state: { state: GlobalModelState;
tabsRoutes: [], effects: {
}, fetchNotices: Effect;
clearNotices: Effect;
changeNoticeReadState: Effect;
changeTabsRoutes: Effect;
getMenuData: Effect;
};
reducers: { reducers: {
saveTabsRoutes(state = { tabsRoutes: [] }, { payload }): GlobalModelState { changeLayoutCollapsed: Reducer<GlobalModelState>;
return { saveNotices: Reducer<GlobalModelState>;
...state, saveClearedNotices: Reducer<GlobalModelState>;
tabsRoutes: payload saveTabsRoutes: Reducer<GlobalModelState>;
saveMenuData: Reducer<GlobalModelState>;
saveMenuModuleMap: Reducer<GlobalModelState>;
};
};
const GlobalModel: GlobalModelType = {
namespace: 'global',
state: {
collapsed: false,
notices: [],
tabsRoutes: [],
menuData: [],
moduleMap: []
},
effects: {
*getMenuData({ payload, callback }, { put, call }) {
const response = yield call(getUserMenu, payload);
const menuData = menuFormatter(response);
// const menuData = wrapTreeNode(response);
globalState.set('menuData', menuData);
yield put({
type: 'saveMenuData',
payload: menuData,
});
yield put({
type: 'saveMenuModuleMap',
payload: menuFormatter(response),
});
if (callback && typeof callback === 'function') {
callback(response)
} }
}, },
*fetchNotices(_, { call, put, select }) {
const user: CurrentUser = yield select(
(state: ConnectState) => state.user.currentUser
);
const data = yield call(queryNotices, { RECSTAFF_ID: user?.ID });
globalState.set('notices', data);
yield put({
type: 'saveNotices',
payload: data,
});
const unreadCount: number = yield select(
(state: ConnectState) => state.global.notices.filter((item) => item.MESSAGE_STATE === 1).length,
);
yield put({
type: 'user/changeNotifyCount',
payload: {
totalCount: data.length,
unreadCount,
},
});
},
*clearNotices({ payload }, { put, select, call }) {
const user: CurrentUser = yield select(
(state: ConnectState) => state.user.currentUser
);
const notices: NoticeItem[] = yield select(
(state: ConnectState) => state.global.notices
);
const clearNoticeIds = notices.reduce((p: any[], c) => {
if (c.MESSAGE_TYPE === (payload as number)) {
return [...p, c.MESSAGE_ID]
}
return p
}, [])
const success = yield call(setMessageState, {
messageIds: clearNoticeIds.toString(),
recStaffId: user?.ID,
messageState: 2
}
);
if (success) {
yield put({
type: 'saveClearedNotices',
payload,
});
const count: number = yield select((state: ConnectState) => state.global.notices.length);
const unreadCount: number = yield select(
(state: ConnectState) => state.global.notices.filter((item) => item.MESSAGE_STATE === 1).length,
);
yield put({
type: 'user/changeNotifyCount',
payload: {
totalCount: count,
unreadCount,
},
});
}
},
* changeNoticeReadState({ payload }, { call, put, select }) {
const notices: NoticeItem[] = yield select((state: ConnectState) =>
state.global.notices.map((item) => {
const notice = { ...item };
if (notice.MESSAGE_ID === payload) {
notice.MESSAGE_STATE = 2;
}
return notice;
}),
);
const success = yield call(changeNoticesState, notices.find(n => n.MESSAGE_ID === payload));
if (success) {
yield put({
type: 'saveNotices',
payload: notices,
});
yield put({
type: 'user/changeNotifyCount',
payload: {
totalCount: notices.length,
unreadCount: notices.filter((item) => item.MESSAGE_STATE === 1).length,
},
});
}
}, },
effects: {
* changeTabsRoutes({ payload, callback }, { put, select }) { // 缓存路由栈 * changeTabsRoutes({ payload, callback }, { put, select }) { // 缓存路由栈
const tabsRoutes: tabsRoute[] = yield select((state: ConnectState) => { const tabsRoutes: tabsRoute[] = yield select((state: ConnectState) => {
const { data } = payload const { data } = payload
if (payload.action === 'add') { if (payload.action === 'add') {
const index = state.global.tabsRoutes.findIndex(n => n.path === data.path) const index = state.global.tabsRoutes.findIndex(n => n.path === data.path)
if (index === -1) { // 没缓存 则添加 if (index === -1) { // 没缓存 则添加
return [...state.global.tabsRoutes, { ...data, index: state.global.tabsRoutes.length }] return [...state.global.tabsRoutes, { ...data, index: state.global.tabsRoutes.length }]
} }
@ -57,18 +185,86 @@ const ProfileModel: ProfileModelType = {
if (payload.action === 'removeAll') { if (payload.action === 'removeAll') {
return [] return []
} }
if (callback && typeof callback === 'function') { if (callback && typeof callback === 'function') {
callback.call() callback.call()
} }
// 移除单个/多个路由 // 移除单个/多个路由
return state.global.tabsRoutes.filter(n => !data.includes(n.path)) return state.global.tabsRoutes.filter(n => !data.includes(n.path))
}); });
yield put({ yield put({
type: 'saveTabsRoutes', type: 'saveTabsRoutes',
payload: tabsRoutes, payload: tabsRoutes,
}); });
}
},
reducers: {
changeLayoutCollapsed(state = { notices: [], collapsed: true, tabsRoutes: [], menuData: [], moduleMap: [] }, { payload }): GlobalModelState {
return {
...state,
collapsed: payload,
};
},
saveNotices(state, { payload }): GlobalModelState {
return {
collapsed: false,
...state,
notices: payload,
tabsRoutes: state?.tabsRoutes || [],
menuData: state?.menuData || [],
moduleMap: state?.moduleMap || []
};
},
saveClearedNotices(state = { notices: [], collapsed: true, tabsRoutes: [], menuData: [], moduleMap: [] }, { payload }): GlobalModelState {
const type = payload as number
return {
...state,
collapsed: false,
notices: state.notices.filter((item): boolean => item.MESSAGE_TYPE !== type),
};
},
saveTabsRoutes(state = { notices: [], collapsed: true, tabsRoutes: [], menuData: [], moduleMap: [] }, { payload }): GlobalModelState {
return {
...state,
tabsRoutes: payload
}
},
saveMenuData(state = { notices: [], collapsed: true, tabsRoutes: [], menuData: [], moduleMap: [] }, { payload }): GlobalModelState {
return {
...state,
menuData: payload,
}
},
saveMenuModuleMap(state = { notices: [], collapsed: true, tabsRoutes: [], menuData: [], moduleMap: [] }, { payload }): GlobalModelState { // 生成模块
const reduceMenu = (data: any) => {
return data.reduce((p: [], current: Record<string, any>) => {
if (current.children) {
const d = reduceMenu(current.children)
return [...p, ...d]
}
return [...p, current]
}, [])
}
const moduleMap = reduceMenu(payload)
session.set('menu', moduleMap)
return {
...state,
moduleMap,
}
} }
}, },
}; };
export default ProfileModel; export default GlobalModel;

View File

@ -5,7 +5,9 @@ import type { AxiosRequestHeaders } from 'axios/index';
const { UMI_APP_BASEURL } = process.env; const { UMI_APP_BASEURL } = process.env;
const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' }); const instance = axios.create({ baseURL: UMI_APP_BASEURL });
// const instance = axios.create({ baseURL: 'https://api.eshangtech.com/EShangApiMain' });
instance.interceptors.request.use( instance.interceptors.request.use(
(config) => { (config) => {

39
src/utils/session.ts Normal file
View File

@ -0,0 +1,39 @@
const $strorage= window.sessionStorage || sessionStorage
const session = {
get: (key: string) => {
const value = $strorage.getItem(key)
try {
const valueObj = JSON.parse(value);
return valueObj;
} catch (error) {
return value
}
},
set: (key: string, value: any) => {
return $strorage.setItem(key, value ? JSON.stringify(value) : value)
},
remove: (key: string) => {
return $strorage.removeItem(key)
},
clearExcept: (key: string) => {
for (let i = 0; i < $strorage.length; i+=1) {
const itemKey: string | undefined = $strorage.key(i);
if (itemKey && itemKey !== key) {
$strorage.rmoveItem(itemKey);
}
}
},
clearAll: () => {
$strorage.clear()
}
}
export default session;