Skip to content

Commit

Permalink
feat: 增加页面路径和环境标识
Browse files Browse the repository at this point in the history
  • Loading branch information
JackySoft committed Nov 7, 2024
1 parent 88d3005 commit 66a3b2e
Show file tree
Hide file tree
Showing 32 changed files with 236 additions and 171 deletions.
6 changes: 4 additions & 2 deletions packages/admin/src/components/BreadList/BreadList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useEffect, useState } from 'react';
import { useLocation, useParams } from 'react-router-dom';
import { useShallow } from 'zustand/react/shallow';
import { useProjectStore } from '@/stores/projectStore';
import { getPageId } from '@/utils/util';

export default function BreadList() {
const { pageId } = useParams();
Expand All @@ -11,8 +12,9 @@ export default function BreadList() {
const { pageMap, menuMap } = useProjectStore(useShallow((state) => ({ pageMap: state.pageMap, menuMap: state.menuMap })));
// 生成面包屑
useEffect(() => {
if (!pageId) return;
const menuItem = pageMap[Number(pageId)];
const page_id = getPageId(pageId, pageMap);
if (!page_id) return;
const menuItem = pageMap[Number(page_id)];
if (pathname.endsWith('/welcome')) {
setMenuPath([{ title: '欢迎页' }]);
return;
Expand Down
4 changes: 2 additions & 2 deletions packages/admin/src/components/Logo/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useEffect, useState } from 'react';
function Logo() {
const { collapsed, projectInfo } = useProjectStore();
const navigate = useNavigate();
const { projectId, env } = useParams();
const { projectId } = useParams();
const [style, setStyle] = useState({});
const [nameStyle, setNameStyle] = useState({});
useEffect(() => {
Expand All @@ -30,7 +30,7 @@ function Logo() {
<div
className={styles.logo}
onClick={() => {
navigate(`/project/${env}/${projectId}/welcome`);
navigate(`/project/${projectId}/welcome`);
}}
style={style}
>
Expand Down
8 changes: 4 additions & 4 deletions packages/admin/src/components/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { Menu } from 'antd';
import type { MenuProps, MenuTheme } from 'antd';
import Icon, * as Icons from '@ant-design/icons';
import * as Icons from '@ant-design/icons';
import { useProjectStore } from '@/stores/projectStore';
import { IMenuItem } from '@/types';

Expand All @@ -13,7 +13,7 @@ const MenuComponent: React.FC = () => {
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
const navigate = useNavigate();
const { pathname } = useLocation();
const { env, projectId } = useParams();
const { projectId } = useParams();
const { collapsed, menuTree, projectInfo } = useProjectStore();

useEffect(() => {
Expand All @@ -31,10 +31,10 @@ const MenuComponent: React.FC = () => {
if (item.type === 1 && item.status === 1) {
const iconsList: { [key: string]: any } = Icons;
if (item.buttons?.length || !item.children) {
const path = `/project/${env}/${projectId}/${item.page_id || -item.id}`;
const path = `/project/${projectId}/${item.path.startsWith('/') ? item.path.slice(1) : item.path || item.page_id || -item.id}`;
return treeList.push(getMenuItem(item.name, path, iconsList[item.icon] && React.createElement(iconsList[item.icon])));
}
const path = `/project/${env}/${projectId}/${item.id}`;
const path = `${projectId}-${item.id}`;
treeList.push(
getMenuItem(item.name, path, iconsList[item.icon] && React.createElement(iconsList[item.icon]), getTreeMenu(item.children || [])),
);
Expand Down
4 changes: 3 additions & 1 deletion packages/admin/src/components/Tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useLocation, useParams, useNavigate } from 'react-router-dom';
import { useShallow } from 'zustand/react/shallow';
import { Tabs } from 'antd';
import { useProjectStore } from '@/stores/projectStore';
import { getPageId } from '@/utils/util';
interface TabsItem {
key: string;
label: string;
Expand Down Expand Up @@ -31,7 +32,8 @@ function Tab() {
setActiveKey('welcome');
return;
}
const menuItem = pageMap[Number(pageId)];
const page_id = getPageId(pageId, pageMap);
const menuItem = pageMap[Number(page_id)];
if (!menuItem) return;
if (!tabsList.find((item) => item.key == pathname)) {
tabsList.push({
Expand Down
35 changes: 28 additions & 7 deletions packages/admin/src/layout/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
import { Outlet, useParams, useNavigate, useLoaderData, useLocation } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { Outlet, useParams, useSearchParams, useNavigate, useLoaderData, useLocation } from 'react-router-dom';
import { ConfigProvider, Layout } from 'antd';
import Header from '../components/Header/Header';
import Menu from '../components/Menu/Menu';
Expand All @@ -9,12 +9,20 @@ import { getProjectDetail, getProjectMenu } from '@/api/index';
import Tab from '../components/Tab';
import Logo from '@/components/Logo/Logo';
import BreadList from '@/components/BreadList/BreadList';
import { arrayToTree, isEnv } from '@/utils/util';
import { arrayToTree } from '@/utils/util';
import storage from '@/utils/storage';
import locale from 'antd/locale/zh_CN';
import { styled } from 'styled-components';
import 'dayjs/locale/zh-cn';
import './layout.less';

const EnvMarker = styled.img`
position: fixed;
top: 0;
left: 0;
z-index: 999999;
pointer-events: none;
`;
const AdminLayout = () => {
const { collapsed, setProjectInfo, projectInfo } = useProjectStore((state) => {
return {
Expand All @@ -26,7 +34,9 @@ const AdminLayout = () => {
const saveUserInfo = usePageStore((state) => state.saveUserInfo);
const loaderData = useLoaderData();
const navigate = useNavigate();
const { projectId, env } = useParams();
const [envTag, setEnvTag] = useState('');
const { projectId } = useParams();
const [searchParams] = useSearchParams();
const { pathname } = useLocation();

// 初始化用户信息
Expand All @@ -38,8 +48,18 @@ const AdminLayout = () => {
// 获取项目信息
useEffect(() => {
// 判断项目ID是否合法
if ((projectId && isNaN(+projectId)) || !isEnv(env)) return navigate('/404?type=project');

if (projectId && isNaN(+projectId)) return navigate('/404?type=project');
const env = searchParams.get('env') || storage.get(`${projectId}-env`) || 'prd';
// 保存项目环境
storage.set(`${projectId}-env`, env);
// 设置环境标识
if (env === 'stg') {
setEnvTag('https://imgcloud.cdn.bcebos.com/349626543730cd39bd152e1c6.svg');
} else if (env === 'pre') {
setEnvTag('https://imgcloud.cdn.bcebos.com/349626543730cd39bd152e1c7.svg');
} else {
setEnvTag('');
}
const fetchProjectDetail = async () => {
if (projectId) {
const detail = await getProjectDetail(projectId);
Expand All @@ -53,7 +73,7 @@ const AdminLayout = () => {
if (!menus) return;

// 如果没有页面路径,跳转到欢迎页
if (!/project\/(stg|pre|prd)\/\d+\/\d+/.test(pathname)) navigate(`/project/${env}/${projectId}/welcome`);
if (!/project\/\d+\/\d+/.test(pathname)) navigate(`/project/${projectId}/welcome`);
const { menuTree, buttons, pageMap, menuMap } = arrayToTree(menus.list);
storage.set('buttons', buttons);
storage.set('pageMap', pageMap);
Expand Down Expand Up @@ -96,6 +116,7 @@ const AdminLayout = () => {
hashed: false,
}}
>
{envTag && <EnvMarker src={envTag} />}
<Layout>
{/* 左右布局 */}
{projectInfo.layout === 1 && (
Expand Down
28 changes: 25 additions & 3 deletions packages/admin/src/pages/console/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Card, Col, Layout, Row, Pagination, Spin, Empty, Button } from 'antd';
import { Card, Col, Layout, Row, Pagination, Spin, Empty, Button, Tooltip } from 'antd';
import { UserOutlined } from '@ant-design/icons';
import { getProjectList } from '@/api';
import { ProjectItem } from '@/types';
Expand Down Expand Up @@ -35,9 +35,24 @@ function Console() {
}
};

const getEnvTag = (env: 'stg' | 'pre' | 'prd', name: string, id: number) => {
const title = {
stg: '访问测试环境',
pre: '访问预发布环境',
prd: '访问生产环境',
}[env];
return (
<Tooltip title={title}>
<a href={`/project/${id}?env=${env}`} target="_blank">
{name}
</a>
</Tooltip>
);
};

// 页面操作
const handleAction = async (id: number) => {
navigate(`/project/stg/${id}`);
navigate(`/project/${id}`);
};

// 分页事件
Expand All @@ -54,7 +69,14 @@ function Console() {
{projectList.map((item: ProjectItem) => {
return (
<Col span={6} key={item.id}>
<Card hoverable>
<Card
hoverable
actions={[
item.id ? getEnvTag('stg', 'STG', item.id) : <span style={{ cursor: 'not-allowed' }}>STG</span>,
item.id ? getEnvTag('pre', 'PRE', item.id) : <span style={{ cursor: 'not-allowed' }}>PRE</span>,
item.id ? getEnvTag('prd', 'PRD', item.id) : <span style={{ cursor: 'not-allowed' }}>PRD</span>,
]}
>
<div onClick={() => handleAction(item.id)}>
<Card.Meta
style={{ cursor: 'pointer' }}
Expand Down
31 changes: 28 additions & 3 deletions packages/admin/src/pages/page/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { ConfigProvider } from 'antd';
import { useShallow } from 'zustand/react/shallow';
import Page from '@marsview/materials/Page/Page';
Expand All @@ -9,10 +9,22 @@ import { getPageDetail } from '@/api/index';
import locale from 'antd/locale/zh_CN';
import 'dayjs/locale/zh-cn';
import { ComItemType, ConfigType } from '@materials/types/index';
import storage from '@/utils/storage';
import { styled } from 'styled-components';
import { isEnv } from '@/utils/util';
const EnvMarker = styled.img`
position: fixed;
top: 0;
left: 0;
z-index: 999999;
pointer-events: none;
`;
export default function () {
const [theme, setTheme] = useState('');
const [pageData, setPageData] = useState<{ config: ConfigType; elements: ComItemType[] }>();
const { id, env } = useParams();
const [envTag, setEnvTag] = useState('');
const { id } = useParams();
const [searchParams] = useSearchParams();
const { savePageInfo, clearPageInfo } = usePageStore(
useShallow((state) => {
return {
Expand All @@ -24,7 +36,19 @@ export default function () {
const navigate = useNavigate();
useEffect(() => {
if (id) {
getPageDetail(env as string, Number(id))
let env = searchParams.get('env') || storage.get(`${id}-env`) || 'prd';
// 设置环境标识
if (env === 'stg') {
setEnvTag('https://imgcloud.cdn.bcebos.com/349626543730cd39bd152e1c6.svg');
} else if (env === 'pre') {
setEnvTag('https://imgcloud.cdn.bcebos.com/349626543730cd39bd152e1c7.svg');
} else {
setEnvTag('');
}
if (!isEnv(env)) {
env = 'prd';
}
getPageDetail(env, Number(id))
.then((res: any) => {
if (!res.id) {
return navigate('/404');
Expand Down Expand Up @@ -69,6 +93,7 @@ export default function () {
},
}}
>
{envTag && <EnvMarker src={envTag} />}
<Page config={pageData?.config} elements={pageData?.elements} />
</ConfigProvider>
);
Expand Down
19 changes: 17 additions & 2 deletions packages/admin/src/pages/project/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ import { getPageDetail } from '@/api/index';
import { useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { usePageStore } from '@marsview/materials/stores/pageStore';
import { useProjectStore } from '@/stores/projectStore';
import { message } from '@/utils/AntdGlobal';
import NotFound from './notFound';
import Page from '@marsview/materials/Page/Page';
import { useShallow } from 'zustand/react/shallow';
import { ComItemType, ConfigType } from '@materials/types/index';
import storage from '@/utils/storage';
import { getPageId, isEnv } from '@/utils/util';

export default function () {
const [pageData, setPageData] = useState<{ config: ConfigType; elements: ComItemType[] }>();
const [notFound, setNotFound] = useState(false);
const { projectId, env, pageId } = useParams();

const { projectId, pageId } = useParams();
const { savePageInfo, clearPageInfo } = usePageStore(
useShallow((state) => {
return {
Expand All @@ -20,8 +24,19 @@ export default function () {
};
}),
);
const pageMap = useProjectStore(useShallow((state) => state.pageMap));
useEffect(() => {
getPageDetail(env as string, Number(pageId))
let env = storage.get(`${projectId}-env`) || 'prd';
// 获取页面ID
const page_id = getPageId(pageId, pageMap);
if (!page_id) {
setNotFound(true);
return;
}
if (!isEnv(env)) {
env = 'prd';
}
getPageDetail(env as string, Number(page_id))
.then((res: any) => {
let pageData: any = {};
try {
Expand Down
6 changes: 3 additions & 3 deletions packages/admin/src/pages/project/notFound.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { Result, Button } from 'antd';
import { useNavigate, useParams } from 'react-router-dom';
function NotFound() {
const navigate = useNavigate();
const { projectId, env } = useParams();
const { projectId } = useParams();
const handleBack = () => {
navigate(`/project/${env}/${projectId}/welcome`);
navigate(`/project/${projectId}/welcome`);
};
return (
<Result
status={404}
title="无法找到该页面"
title="页面不存在或未发布"
subTitle="当前页面路径不存在,请检查路由地址是否正确或页面是否发布"
extra={
<Button type="primary" onClick={handleBack}>
Expand Down
4 changes: 2 additions & 2 deletions packages/admin/src/router/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ export const router = [
element: lazyLoad(React.lazy(() => import('@/pages/console'))),
},
{
path: '/page/:env/:id',
path: '/page/:id',
element: lazyLoad(React.lazy(() => import('@/pages/page'))),
},
{
path: '/login',
element: lazyLoad(React.lazy(() => import('@/pages/login/Login'))),
},
{
path: '/project/:env/:projectId',
path: '/project/:projectId',
loader: AuthLoader,
element: lazyLoad(React.lazy(() => import('@/layout/layout'))),
children: [
Expand Down
17 changes: 15 additions & 2 deletions packages/admin/src/utils/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ import { IMenuItem } from '@/types/index';
export function isEnv(env?: string) {
return env && ['stg', 'pre', 'prd'].includes(env);
}
/**
* 获取页面ID
* @param pageId 页面路径或者页面ID
* @param pageMap 菜单映射对象
* @returns
*/
export function getPageId(pageId: string | number | undefined, pageMap: Record<number, any>): number {
if (!pageId || !pageMap) return 0;
const page_id = isNaN(Number(pageId))
? Object.values(pageMap).filter((item) => (item.path.startsWith('/') ? item.path.slice(1) === pageId : item.path === pageId))?.[0]?.page_id
: pageId;
return page_id;
}
/**
* 菜单数据转换
* treeList: 树形菜单
Expand All @@ -16,7 +29,7 @@ export function isEnv(env?: string) {
*/
export function arrayToTree(array: IMenuItem[] = []) {
const buttons: IMenuItem[] = [];
const pageMap: { [key: number]: IMenuItem } = {};
const pageMap: { [key: number]: Pick<IMenuItem, 'id' | 'page_id' | 'parent_id' | 'name' | 'path'> } = {};
const menuMap: { [key: number]: IMenuItem } = {};
// 创建一个映射,将id映射到节点对象
const map: { [key: number]: IMenuItem & { children?: IMenuItem[] } } = {};
Expand All @@ -25,7 +38,7 @@ export function arrayToTree(array: IMenuItem[] = []) {
if (item.type === 2) buttons.push(item);
if (item.type === 1 || item.type === 3) {
if (item.page_id) {
pageMap[item.page_id] = { ...item };
pageMap[item.page_id] = { id: item.id, page_id: item.page_id, parent_id: item.parent_id, name: item.name, path: item.path };
} else {
menuMap[item.id] = { ...item };
}
Expand Down
Loading

0 comments on commit 66a3b2e

Please sign in to comment.