feat: 路由调整

This commit is contained in:
Mozzie 2023-09-07 16:42:34 +08:00
parent c522de39ae
commit 098f90d746
16 changed files with 134 additions and 99 deletions

View File

@ -21,7 +21,8 @@
"@tavi/i18n": "^1.5.0",
"@tavi/util": "1.0.0",
"js-cookie": "3.0.5",
"three": "0.156.1"
"three": "0.156.1",
"path-to-regexp": "6.2.1"
},
"devDependencies": {
"@babel/core": "^7.21.8",

View File

@ -1,13 +1,14 @@
import { Outlet } from "react-router";
import { Outlet, useLocation } from "react-router";
interface LayoutProps {
children?: JSX.Element;
}
export const Layout = (props: LayoutProps) => {
const location = useLocation();
return (
<div>
<header>12222</header>
<header> {location.pathname}</header>
<Outlet />
</div>
);

View File

@ -25,3 +25,5 @@ export const theme: ThemeConfig = {
* @enum "zh-CN" | 'en' | 'en-US' | 'zh'
*/
export const defaultLang = "zh-CN";

View File

@ -4,8 +4,6 @@ import { FormFields, LoginForm } from "./LoginForm";
import "./index.less";
import { useDomain } from "@/hook/useDomain";
import { useTranslation } from "@tavi/i18n";
import { Observer, observer } from "mobx-react-lite";
import { UserService } from "@@/domain/User/UserService";
import { useNavigate } from "react-router";
import { message } from "antd";
@ -13,14 +11,6 @@ interface LoginProps {
children?: JSX.Element;
}
// const TestComponent: React.FC<{ domainService: UserService }> = observer(
// ({ domainService }) => (
// <div style={{ color: "#fff" }}>
// <p>name: {domainService.user.isLoggedIn ? "登录" : "未登录"}</p>
// </div>
// )
// );
export const Login = (props: LoginProps) => {
const { t } = useTranslation();
const navigate = useNavigate();
@ -55,7 +45,6 @@ export const Login = (props: LoginProps) => {
<Logo isClicked={false} />
<LanguageSelect />
</header>
{/* <TestComponent domainService={userDomainService} /> */}
<LoginForm
styles={{ width: "100%" }}
onFormChange={(v) => userDomainService.updateLoginForm(v)}

View File

@ -1,47 +1,29 @@
import { AuthFailedReplacePath } from "@/constant";
import { useLocation, useNavigate } from "react-router-dom";
import { useEffect } from "react";
import { pathToRegexp } from "path-to-regexp";
import { useDomain } from "@/hook/useDomain";
import { message } from "antd";
interface GuardProps {
element: JSX.Element;
auth?: boolean;
title?: string;
interface RouteGuardProps {
children?: React.ReactNode;
ignorePaths: string[];
}
/**
*
*/
export const Guard = (props: GuardProps) => {
export const RouteGuard = (props: RouteGuardProps) => {
const { children, ignorePaths } = props;
const { userDomainService } = useDomain();
const { user } = userDomainService;
const location = useLocation();
const navigate = useNavigate();
const { userDomainService } = useDomain();
const [messageApi, contextHolder] = message.useMessage();
const { isLoggedIn } = userDomainService.user;
useEffect(() => {
if (props.auth && !isLoggedIn) {
userDomainService.userAuth().then((result: any) => {
const { success, msg } = result;
if (!success) {
messageApi.error(msg);
navigate(AuthFailedReplacePath);
}
});
}
return () => {};
}, [navigate]);
useEffect(() => {
if (props?.title) document.title = props?.title;
return () => {};
}, [location.pathname]);
return (
<>
{contextHolder}
{props.element}
</>
const ignore = ignorePaths.some((p) =>
pathToRegexp(p).test(location.pathname)
);
if (!ignore && !user.isLoggedIn) {
userDomainService.userAuth().then(({ success }) => {
if (!success) navigate(AuthFailedReplacePath);
});
}
return children;
};

View File

@ -1,4 +1,44 @@
import { routesConfig } from "./router.config";
import { useRoutes } from "react-router";
import { baseRoutes } from "./router.config";
import { Route, RouteObject, Routes, useLocation } from "react-router-dom";
import { RouteGuard } from "./AuthGuard";
import { pathToRegexp } from "path-to-regexp";
import { defaultTitle } from "@/constant";
export const RouterElements = () => useRoutes(routesConfig);
// export const RouterElements = () => useRoutes(routesConfig);
export type ExpandRouteProps = {
title?: string;
};
export const RouterElements = () => {
const location = useLocation();
console.log(location.pathname);
/**
* document.title
*/
const currentRoute = [...baseRoutes].find((r) =>
pathToRegexp(location.pathname).test(r.path!)
);
document.title = currentRoute?.title ?? defaultTitle;
/**
* children
*/
const generateRoutes = (routes: (RouteObject & ExpandRouteProps)[]) =>
routes.map((r) => (
<Route key={r.path} path={r.path} element={r.element}>
{r.children && generateRoutes(r.children)}
</Route>
));
return (
<RouteGuard ignorePaths={[]}>
<Routes>
{generateRoutes(baseRoutes)}
<Route key="notfound" path="*" element={<span>404</span>} />
</Routes>
</RouteGuard>
);
};

View File

@ -5,17 +5,22 @@ import { RootViewer } from "../modules/Root/Viewer/Root";
import { PeripheralViewer } from "../modules/Peripheral";
import { Dashboard } from "@/modules/Dashboard";
import { ReportFullVersion } from "@/modules/Report/Full";
import { Guard } from "./AuthGuard";
import { Layout } from "@/components/Layout";
import { ExpandRouteProps } from ".";
export const routesConfig: RouteObject[] = [
/**
*
*/
export const baseRoutes: (RouteObject & ExpandRouteProps)[] = [
{
path: "login",
element: <Guard element={<Login />} title="CVPILOT Viewer" />,
path: "/login",
element: <Login />,
title: "登录 - CVPILOT Viewer",
},
{
path: "/",
element: <Guard element={<Layout />} auth />,
element: <Layout />,
title: "CVPILOT Viewer",
children: [
{
path: "/",
@ -23,28 +28,24 @@ export const routesConfig: RouteObject[] = [
},
{
path: "dash",
element: <Guard element={<Dashboard />} title="仪表盘" />,
element: <Dashboard />,
},
{
path: "list",
element: <Guard element={<PatientList />} title="患者列表" />,
element: <PatientList />,
},
{
path: "root/viewer",
element: <Guard element={<RootViewer />} title="根部分析" />,
element: <RootViewer />,
},
{
path: "root/report/full",
element: <Guard element={<ReportFullVersion />} title="完整报告" />,
element: <ReportFullVersion />,
},
{
path: "peripheral/viewer",
element: <Guard element={<PeripheralViewer />} title="外周分析" />,
element: <PeripheralViewer />,
},
],
},
{
path: "*",
element: <span>404</span>,
},
];

View File

@ -5,8 +5,7 @@ import { User } from "./entities/User";
export class RbacRepository {
async saveRole(role: Role) {
const { code } = await Apis.saveRole(role);
return code === "ok";
return await Apis.saveRole(role);
}
async updateRole(role: Role) {
@ -43,8 +42,8 @@ export class RbacRepository {
}
async saveUser(user: User) {
const { code } = await Apis.saveUser(user);
return code === "ok";
const { code, data, msg } = await Apis.saveUser(user);
return { code, data, msg };
}
async updateUser(user: Omit<User, "roles"> & { roles: number[] }) {

View File

@ -37,11 +37,14 @@ export class RbacService {
*
*/
async addRole(role: Role) {
this.roleList = [
...this.roleList,
{ ...role, isEnabled: true, permissions: [] },
];
return await this.rbacRepository.saveRole(role);
const { code, msg } = await this.rbacRepository.saveRole(role);
if (code === 0) {
this.roleList = [
...this.roleList,
{ ...role, isEnabled: true, permissions: [] },
];
}
return { code, msg };
}
/**
@ -115,8 +118,14 @@ export class RbacService {
phoneNumber,
createTime: new Date().toLocaleString(),
};
this.userList = [...this.userList, user];
return await this.rbacRepository.saveUser({ ...user, password });
const { code, data, msg } = await this.rbacRepository.saveUser({
...user,
password,
});
if (code === 0) {
this.userList = [...this.userList, data as User];
}
return { data, msg, code };
}
/**

View File

@ -26,8 +26,9 @@ export const Role = (props: RoleProps) => {
const onModalConfirm = async (fields: fieldsType) => {
setModalVisible(false);
const ok = await rbacDomainService.addRole({ ...fields });
messageApi.info(ok ? "ok" : "failed");
const { code, msg } = await rbacDomainService.addRole({ ...fields });
code === 0 ? messageApi.success(msg) : messageApi.error(msg);
rbacDomainService.findAllRoleWithPermissions();
};
const RoleListComponent: React.FC<{ domainService: RbacService }> = observer(

View File

@ -25,13 +25,18 @@ export const CreateUserForm = (props: CreateUserFormProps) => {
const onConfirmCreateUser = async (fields: CreateUserFormFields) => {
const { roleIds, username, password, phoneNumber } = fields;
const success = await rbacDomainService.saveUser({
const { code, data, msg } = await rbacDomainService.saveUser({
roleIds,
username,
password,
phoneNumber,
});
if (success) messageApi.success(`用户: ${username} 创建成功`);
if (code === 0) {
messageApi.success(msg);
rbacDomainService.findAllRoleWithPermissions();
} else {
messageApi.error(msg);
}
};
return (

View File

@ -36,7 +36,7 @@ export const RouterElements = observer(() => {
const currentRoute = [...currentRoutes, ...baseRoutes].find((r) =>
pathToRegexp(r.path!).test(location.pathname)
);
if (currentRoute) document.title = currentRoute.title || defaultDocumentTitle;
document.title = currentRoute?.title ?? defaultDocumentTitle;
/**
* children

View File

@ -53,10 +53,10 @@ export class RbacService {
async createRole(payload: Role) {
const { name, alias, description } = payload;
const exsit = await this.roleRepository.findOne({ where: { name } });
if (exsit) return { message: '用户已存在' };
const exist = await this.roleRepository.findOne({ where: { name } });
if (exist) return { message: '角色已存在', success: false };
const result = await this.roleRepository.save({ name, alias, description });
return result;
return { success: true, result, message: '角色创建成功' };
}
async findAllRole() {

View File

@ -43,14 +43,15 @@ export class UserService {
},
});
// 如果username存在
if (user) return false;
if (user) return { success: false, msg: '用户名已存在' };
const cipher = await this.bcryptService.hashPassword(password);
return await this.userRepository.save({
const userCreated = await this.userRepository.save({
username,
password: cipher,
phoneNumber,
roles,
});
return { success: true, msg: '用户创建成功', data: userCreated };
}
async update(fields: User) {

View File

@ -24,11 +24,12 @@ export class AdminController {
@Post('role/create')
async createRole(@Body() createRoleDto: CreateRoleDto) {
const pattern = { cmd: 'cert.create.role' };
const result = await firstValueFrom(
this.client.send(pattern, createRoleDto),
const { success, result, message } = await firstValueFrom(
this.client.send({ cmd: 'cert.create.role' }, createRoleDto),
);
return { code: 'ok', data: result };
return success
? { code: 0, data: result, msg: message }
: { code: 1, msg: message };
}
@Post('role/remove')
@ -87,17 +88,17 @@ export class AdminController {
@Post('user/create')
async createUser(@Body() createUserDto: CreateUserDto) {
const pattern = { cmd: 'cert.user.create' };
const payload = createUserDto;
const result = await firstValueFrom(this.client.send(pattern, payload));
return { code: 'ok', data: result };
const { success, msg, data } = await firstValueFrom(
this.client.send({ cmd: 'cert.user.create' }, createUserDto),
);
return success ? { code: 0, data, msg } : { code: 1, msg };
}
@Get('user/find/all')
async userSelect() {
const pattern = { cmd: 'cert.find.all.user' };
const payload = [];
const result = await firstValueFrom(this.client.send(pattern, payload));
const result = await firstValueFrom(
this.client.send({ cmd: 'cert.find.all.user' }, []),
);
return { code: 'ok', data: result };
}

View File

@ -34,6 +34,9 @@ importers:
mobx-react-lite:
specifier: 3.4.3
version: 3.4.3(mobx@6.9.0)(react-dom@18.2.0)(react@18.2.0)
path-to-regexp:
specifier: 6.2.1
version: 6.2.1
react:
specifier: 18.2.0
version: 18.2.0