diff --git a/apps/aorta/package.json b/apps/aorta/package.json index 123e8da..726d789 100644 --- a/apps/aorta/package.json +++ b/apps/aorta/package.json @@ -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", diff --git a/apps/aorta/src/components/Layout/index.tsx b/apps/aorta/src/components/Layout/index.tsx index 83bf2e2..86f3af8 100644 --- a/apps/aorta/src/components/Layout/index.tsx +++ b/apps/aorta/src/components/Layout/index.tsx @@ -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 (
-
12222
+
{location.pathname}
); diff --git a/apps/aorta/src/constant.tsx b/apps/aorta/src/constant.tsx index 8627c8e..902bc5e 100644 --- a/apps/aorta/src/constant.tsx +++ b/apps/aorta/src/constant.tsx @@ -25,3 +25,5 @@ export const theme: ThemeConfig = { * @enum "zh-CN" | 'en' | 'en-US' | 'zh' */ export const defaultLang = "zh-CN"; + + diff --git a/apps/aorta/src/modules/Login/index.tsx b/apps/aorta/src/modules/Login/index.tsx index 645463c..c2966e8 100644 --- a/apps/aorta/src/modules/Login/index.tsx +++ b/apps/aorta/src/modules/Login/index.tsx @@ -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 }) => ( -//
-//

name: {domainService.user.isLoggedIn ? "登录" : "未登录"}

-//
-// ) -// ); - export const Login = (props: LoginProps) => { const { t } = useTranslation(); const navigate = useNavigate(); @@ -55,7 +45,6 @@ export const Login = (props: LoginProps) => { - {/* */} userDomainService.updateLoginForm(v)} diff --git a/apps/aorta/src/router/AuthGuard.tsx b/apps/aorta/src/router/AuthGuard.tsx index a4fc2c0..5069dd4 100644 --- a/apps/aorta/src/router/AuthGuard.tsx +++ b/apps/aorta/src/router/AuthGuard.tsx @@ -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; }; diff --git a/apps/aorta/src/router/index.tsx b/apps/aorta/src/router/index.tsx index bcec807..0b6e4ce 100644 --- a/apps/aorta/src/router/index.tsx +++ b/apps/aorta/src/router/index.tsx @@ -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) => ( + + {r.children && generateRoutes(r.children)} + + )); + + return ( + + + {generateRoutes(baseRoutes)} + 404} /> + + + ); +}; diff --git a/apps/aorta/src/router/router.config.tsx b/apps/aorta/src/router/router.config.tsx index 30ae1bb..dbaf3ba 100644 --- a/apps/aorta/src/router/router.config.tsx +++ b/apps/aorta/src/router/router.config.tsx @@ -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: } title="CVPILOT Viewer" />, + path: "/login", + element: , + title: "登录 - CVPILOT Viewer", }, { path: "/", - element: } auth />, + element: , + title: "CVPILOT Viewer", children: [ { path: "/", @@ -23,28 +28,24 @@ export const routesConfig: RouteObject[] = [ }, { path: "dash", - element: } title="仪表盘" />, + element: , }, { path: "list", - element: } title="患者列表" />, + element: , }, { path: "root/viewer", - element: } title="根部分析" />, + element: , }, { path: "root/report/full", - element: } title="完整报告" />, + element: , }, { path: "peripheral/viewer", - element: } title="外周分析" />, + element: , }, ], }, - { - path: "*", - element: 404, - }, ]; diff --git a/apps/cert/core/domain/Rbac/RbacRepository.ts b/apps/cert/core/domain/Rbac/RbacRepository.ts index f6030c1..5059090 100644 --- a/apps/cert/core/domain/Rbac/RbacRepository.ts +++ b/apps/cert/core/domain/Rbac/RbacRepository.ts @@ -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 & { roles: number[] }) { diff --git a/apps/cert/core/domain/Rbac/RbacService.ts b/apps/cert/core/domain/Rbac/RbacService.ts index 58a72d7..0118ad6 100644 --- a/apps/cert/core/domain/Rbac/RbacService.ts +++ b/apps/cert/core/domain/Rbac/RbacService.ts @@ -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 }; } /** diff --git a/apps/cert/src/modules/Configuration/Role/index.tsx b/apps/cert/src/modules/Configuration/Role/index.tsx index c503fdd..ee3ea4c 100644 --- a/apps/cert/src/modules/Configuration/Role/index.tsx +++ b/apps/cert/src/modules/Configuration/Role/index.tsx @@ -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( diff --git a/apps/cert/src/modules/User/List/CreateUserForm.tsx b/apps/cert/src/modules/User/List/CreateUserForm.tsx index d1bedae..543f4cf 100644 --- a/apps/cert/src/modules/User/List/CreateUserForm.tsx +++ b/apps/cert/src/modules/User/List/CreateUserForm.tsx @@ -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 ( diff --git a/apps/dmp/src/router/index.tsx b/apps/dmp/src/router/index.tsx index 0afa9ed..1ee2f57 100644 --- a/apps/dmp/src/router/index.tsx +++ b/apps/dmp/src/router/index.tsx @@ -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 diff --git a/apps/services/cert/authorize/src/rbac/rbac.service.ts b/apps/services/cert/authorize/src/rbac/rbac.service.ts index ddae464..c146989 100644 --- a/apps/services/cert/authorize/src/rbac/rbac.service.ts +++ b/apps/services/cert/authorize/src/rbac/rbac.service.ts @@ -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() { diff --git a/apps/services/cert/authorize/src/user/user.service.ts b/apps/services/cert/authorize/src/user/user.service.ts index b442b09..0334a9d 100644 --- a/apps/services/cert/authorize/src/user/user.service.ts +++ b/apps/services/cert/authorize/src/user/user.service.ts @@ -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) { diff --git a/apps/services/cert/gateway/src/admin/admin.controller.ts b/apps/services/cert/gateway/src/admin/admin.controller.ts index 0fc8bff..952317c 100644 --- a/apps/services/cert/gateway/src/admin/admin.controller.ts +++ b/apps/services/cert/gateway/src/admin/admin.controller.ts @@ -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 }; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0f04de3..f299b74 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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