feat: test

This commit is contained in:
mozzie 2023-12-18 16:57:01 +08:00
parent 2ec9c401ba
commit 3d1afd7a18
21 changed files with 3543 additions and 1028 deletions

View File

@ -23,11 +23,13 @@
"js-cookie": "3.0.5", "js-cookie": "3.0.5",
"three": "0.156.1", "three": "0.156.1",
"path-to-regexp": "6.2.1", "path-to-regexp": "6.2.1",
"@cornerstonejs/core": "1.16.5", "cornerstone-core": "2.6.1",
"dicom-parser": "1.8.21", "dicom-parser": "1.8.21",
"cornerstone-wado-image-loader": "4.13.2",
"@msgpack/msgpack": "3.0.0-beta2", "@msgpack/msgpack": "3.0.0-beta2",
"pako": "2.1.0" "pako": "2.1.0",
"@kitware/vtk.js": "29.2.0",
"@cornerstonejs/dicom-image-loader": "1.41.0",
"cornerstone-wado-image-loader": "4.13.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.21.8", "@babel/core": "^7.21.8",

View File

@ -40,11 +40,6 @@ const baseConfig: Configuration = {
"@": path.join(__dirname, "../src"), "@": path.join(__dirname, "../src"),
"@@": path.join(__dirname, "../core"), "@@": path.join(__dirname, "../core"),
}, },
// fallback: {
// crypto: require.resolve('crypto-browserify'),
// buffer: require.resolve("buffer/"),
// http: require.resolve("stream-http"),
// },
}, },
// plugins // plugins
plugins: [ plugins: [

View File

@ -83,8 +83,8 @@ export const LoginForm = (props: LoginFormProps) => {
rules={[ rules={[
{ {
required: true, required: true,
pattern: REG.password, // pattern: REG.password,
min: 6, // min: 6,
max: 20, max: 20,
message: "6-20位包含 大写、小写、字母、特殊字符", message: "6-20位包含 大写、小写、字母、特殊字符",
}, },

View File

@ -14,8 +14,10 @@
position: relative; position: relative;
background-size: cover; background-size: cover;
background-position: center center; background-position: center center;
min-height: 6rem;
cursor: pointer; cursor: pointer;
img{
width: 100%;
}
&.active { &.active {
&::after { &::after {

View File

@ -38,18 +38,20 @@ export const ImageItem = (props: ImageItemProps) => {
const handleFileChange = (event: any) => { const handleFileChange = (event: any) => {
if (event.target.files && event.target.files[0]) { if (event.target.files && event.target.files[0]) {
const fd = new FormData();
fd.append("file", event.target.files[0]);
axios // const fd = new FormData();
.post("/api/report/upload", fd, { // fd.append("file", event.target.files[0]);
headers: { "Content-Type": "multipart/form-data" }, // axios
}) // .post("/api/report/upload", fd, {
.then((res) => { // headers: { "Content-Type": "multipart/form-data" },
const { objectName } = res.data; // })
setImgSrc(`/api/report/img/${objectName}`); // .then((res) => {
}); // const { objectName } = res.data;
// setImgSrc(`/api/report/img/${objectName}`);
// });
//TODO API接口上传THEN //TODO API接口上传THEN
setImgSrc(event.target.result); setImgSrc(URL.createObjectURL(event.target.files[0]));
} }
}; };
@ -63,8 +65,10 @@ export const ImageItem = (props: ImageItemProps) => {
onClick={() => setActionVisible(true)} onClick={() => setActionVisible(true)}
className={`img ${actionVisible ? "active" : ""}`} className={`img ${actionVisible ? "active" : ""}`}
ref={imgRef} ref={imgRef}
style={{ ...props.imgStyle, backgroundImage: `url(${imgSrc})` }} style={{ ...props.imgStyle }}
></div> >
<img src={imgSrc} />
</div>
)} )}
{actionVisible && ( {actionVisible && (
<section ref={actionRef}> <section ref={actionRef}>

View File

@ -1,13 +1,18 @@
.page-head { .page-head {
text-align: right; display: flex;
align-items: center;
justify-content: space-between;
line-height: 1; line-height: 1;
padding-bottom: 0.57rem; padding-bottom: 0.57rem;
border-bottom: 0.07rem solid var(--color-bg-primary); border-bottom: 0.07rem solid var(--color-bg-primary);
margin-bottom: 2rem; margin-bottom: 2rem;
>span{
color: red;
}
.logo-group { .logo-group {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
} }
}
}

View File

@ -7,6 +7,7 @@ interface PaperHeadProps {
export const PaperHead = (props: PaperHeadProps) => { export const PaperHead = (props: PaperHeadProps) => {
return ( return (
<div className="page-head"> <div className="page-head">
<span>demo版本</span>
<div className="logo-group"> <div className="logo-group">
<svg <svg
viewBox="0 0 45 47" viewBox="0 0 45 47"

View File

@ -31,14 +31,14 @@ interface DoctorProps {
} }
export const ReportFullVersion = (props: DoctorProps) => { export const ReportFullVersion = (props: DoctorProps) => {
const [date, totalPageNum] = ["2023-06-14", 21]; const [date, totalPageNum] = ["2023-12-12", 18];
const [completed, setCompleted] = useState(0); const [completed, setCompleted] = useState(0);
useEffect(() => { // useEffect(() => {
axios.get("/api/aorta/report/root").then((res) => { // axios.get("/api/aorta/report/root").then((res) => {
console.log(res); // console.log(res);
}); // });
}, []); // }, []);
/** /**
* pdf * pdf

View File

@ -48,7 +48,6 @@ export const LeftCoronarySinus = (props: LeftCoronarySinusProps) => {
<ImageItem <ImageItem
title="左冠窦瓣叶长度" title="左冠窦瓣叶长度"
src={src} src={src}
imgStyle={{ height: "6.43rem" }}
/> />
<Reference <Reference
style={{ position: "absolute", bottom: "3rem" }} style={{ position: "absolute", bottom: "3rem" }}

View File

@ -31,7 +31,6 @@ export const NoCoronarySinus = (props: NoCoronarySinusProps) => {
<ImageItem <ImageItem
title="无冠窦瓣叶长度" title="无冠窦瓣叶长度"
src={src} src={src}
imgStyle={{ height: "6.43rem" }}
/> />
</div> </div>
); );

View File

@ -32,7 +32,6 @@ export const RightCoronarySinus = (props: RightCoronarySinusProps) => {
<ImageItem <ImageItem
title="左冠窦瓣叶长度" title="左冠窦瓣叶长度"
src={src} src={src}
imgStyle={{ height: "6.43rem" }}
/> />
</div> </div>
); );

View File

@ -0,0 +1,133 @@
import { relative } from "path";
import React, { useEffect, useRef, useState } from "react";
import * as THREE from "three";
import { TrackballControls } from "three/examples/jsm/controls/TrackballControls";
type ThreeJSComponentProps = {
// 你可以在这里添加任何需要的props
};
export const MprViewer: React.FC<ThreeJSComponentProps> = () => {
const mountRef = useRef<HTMLDivElement>(null);
const [imageSrc, setImageSrc] = useState<string>("");
useEffect(() => {
const width = window.innerWidth - 300;
const height = window.innerHeight;
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x808080);
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
// 添加一个可移动和旋转的平面
const planeGeometry = new THREE.PlaneGeometry(200, 200);
const planeMaterial = new THREE.MeshBasicMaterial({
color: 0xffff00,
side: THREE.DoubleSide,
});
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.position.set(0, 0, 0); // 初始位置
scene.add(plane);
// 创建一个与平面对齐的剪裁平面
const clipPlane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
renderer.clippingPlanes = [clipPlane];
// 使剪裁平面跟随你的移动平面
const updateClipPlane = () => {
clipPlane.normal.copy(plane.position).normalize();
};
// 添加多个3D物体
const geometry1 = new THREE.BoxGeometry(100, 100, 100);
const material1 = new THREE.MeshPhongMaterial({
color: 0x00ff00,
transparent: true,
opacity: 0.5,
});
const cube = new THREE.Mesh(geometry1, material1);
cube.position.x = -50; // 调整位置以确保重叠
scene.add(cube);
const geometry2 = new THREE.SphereGeometry(50, 32, 32);
const material2 = new THREE.MeshPhongMaterial({
color: 0xff0000,
transparent: true,
opacity: 0.5,
});
const sphere = new THREE.Mesh(geometry2, material2);
sphere.position.x = 0; // 调整位置以确保重叠
scene.add(sphere);
const geometry3 = new THREE.ConeGeometry(50, 100, 32);
const material3 = new THREE.MeshPhongMaterial({
color: 0x0000ff,
transparent: true,
opacity: 0.5,
});
const cone = new THREE.Mesh(geometry3, material3);
cone.position.x = 50; // 调整位置以确保重叠
scene.add(cone);
camera.position.set(0, 0, 500);
camera.lookAt(scene.position);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const mount = mountRef.current;
if (mount) {
mount.appendChild(renderer.domElement);
}
const controls = new TrackballControls(camera, renderer.domElement);
const animate = () => {
requestAnimationFrame(animate);
controls.update(); // 只有在使用 TrackballControls 时才需要
// camera.position.y += 5;
camera.updateMatrixWorld();
updateClipPlane(); // 更新剪裁平面的位置和方向
renderer.render(scene, camera);
// 从渲染器的 canvas 中获取图像
const canvas = renderer.domElement;
canvas.toBlob((blob) => {
if (blob) {
const imageUrl = URL.createObjectURL(blob);
setImageSrc(imageUrl);
}
}, "image/jpeg");
};
animate();
return () => {
controls.dispose();
mount?.removeChild(renderer.domElement);
URL.revokeObjectURL(imageSrc);
};
}, []);
return (
<div style={{ position: "relative" }}>
<div ref={mountRef} />
<img
style={{
position: "absolute",
right: 0,
top: 0,
width: "200px",
height: "200px",
}}
src={imageSrc}
alt="Rendered Scene"
/>
</div>
);
};

View File

@ -0,0 +1,63 @@
import axios from "axios";
import { useEffect, useRef } from "react";
import * as cornerstone from "cornerstone-core";
import dicomParser from "dicom-parser";
import cornerstoneDICOMImageLoader from "@cornerstonejs/dicom-image-loader";
interface VolumeViewerProps {
children?: JSX.Element;
}
const StudyInstanceUID =
"1.2.840.113619.2.416.200043823236217877797891016883696407563"; // 你的 studyInstanceUID
const SeriesInstanceUID =
"1.2.840.113619.6.80.114374075765625.22940.1553237925965.1"; // 你的 seriesInstanceUID
export const VolumeViewer = (props: VolumeViewerProps) => {
const dicomRef = useRef(null);
const url = `/dicom-web/studies/${StudyInstanceUID}/series/${SeriesInstanceUID}/instances`;
useEffect(() => {
cornerstoneDICOMImageLoader.external.cornerstone = cornerstone;
cornerstoneDICOMImageLoader.external.dicomParser = dicomParser;
// cornerstoneWADOImageLoader.configure({ useWebWorkers: true });
const config = {
maxWebWorkers: navigator.hardwareConcurrency || 1,
startWebWorkersOnDemand: true,
taskConfiguration: {
decodeTask: {
initializeCodecsOnStartup: false,
},
},
};
cornerstoneDICOMImageLoader.webWorkerManager.initialize(config);
}, []);
useEffect(() => {
cornerstone.enable(dicomRef.current!);
axios
.get(url)
.then((response) => {
const objectUIDs = response.data.map(
(i: any) => i["00080018"].Value[0]
);
objectUIDs.forEach((i: any) => {
const imageId = `wadors:/dicom-web/studies/${StudyInstanceUID}/series/${SeriesInstanceUID}/instances/${i}/frames/1`;
cornerstone.loadImage(imageId).then((image: any) => {
cornerstone.displayImage(dicomRef.current!, image);
});
});
})
.catch((error) => {
console.error("Error fetching instances:", error);
});
}, []);
return (
<div>
<div ref={dicomRef} style={{ width: 200, height: 200 }}></div>
</div>
);
};

View File

@ -1,4 +1,6 @@
import { DiffViewer } from "./DiffViewer"; import { DiffViewer } from "./DiffViewer";
import { MprViewer } from "./MprViewer";
import { VolumeViewer } from "./VolumeViewer";
interface RootViewerProps { interface RootViewerProps {
children?: JSX.Element; children?: JSX.Element;
@ -7,7 +9,7 @@ interface RootViewerProps {
export const RootViewer = (props: RootViewerProps) => { export const RootViewer = (props: RootViewerProps) => {
return ( return (
<div> <div>
<DiffViewer /> <VolumeViewer />
</div> </div>
); );
}; };

View File

@ -1,106 +0,0 @@
import React, { useEffect, useRef } from "react";
import * as THREE from "three";
import { STLLoader } from "three/examples/jsm/loaders/STLLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import {
autoScale,
createEnclosedGeometry,
getOffsetTriangles,
getTriangleVertexs,
} from "./util";
export const STLViewer: React.FC = () => {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (containerRef.current) {
const width = containerRef.current.clientWidth;
const height = containerRef.current.clientHeight;
// 创建场景、相机和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
containerRef.current.appendChild(renderer.domElement);
// 加载STL文件
const loader = new STLLoader();
loader.load("/1.stl", (geometry) => {
const s = autoScale(geometry);
// geometry.center();
// const material = new THREE.MeshPhongMaterial({
// color: "lightgrey", // 使用更亮的颜色
// shininess: 100, // 增加亮度
// specular: 0x222222, // 调整镜面高光的颜色
// // side: THREE.DoubleSide,
// // wireframe: true,
// });
// const mesh = new THREE.Mesh(geometry, material);
// mesh.scale.set(scale, scale, scale);
// scene.add(mesh);
// 输出三角形顶点信息
const triangles = getTriangleVertexs(geometry);
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
const newTriangles = getOffsetTriangles(triangles, -2);
console.log("newTriangles", newTriangles);
// 使用上面定义的函数
const enclosedGeometry = createEnclosedGeometry(
triangles,
newTriangles
);
enclosedGeometry.center();
const material = new THREE.MeshBasicMaterial({
color: "lightgrey",
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(enclosedGeometry, material);
mesh.scale.set(s, s, s);
scene.add(mesh);
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
});
// 添加环境光源
const ambientLight = new THREE.AmbientLight(0xffffff, 1); // 第二个参数为强度
scene.add(ambientLight);
// 添加方向光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 2);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
// 添加XYZ轴
const axesHelper = new THREE.AxesHelper(2);
scene.add(axesHelper);
// 添加OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 渲染函数
const animate = () => {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
animate();
}
}, []);
return <div ref={containerRef} style={{ width: "100vw", height: "100vh" }} />;
};

View File

@ -1,13 +0,0 @@
import { STLViewer } from "./STLViewer";
interface RootViewerProps {
children?: JSX.Element;
}
export const RootViewer = (props: RootViewerProps) => {
return (
<div>
123
</div>
);
};

View File

@ -1,202 +0,0 @@
import * as THREE from "three";
export const autoScale = (geometry: THREE.BufferGeometry) => {
// 计算模型的边界
geometry.computeBoundingBox();
// 获取模型的大小
const modelSize = geometry.boundingBox!.getSize(new THREE.Vector3());
const maxSize = Math.max(modelSize.x, modelSize.y, modelSize.z);
// 根据模型的大小设置一个缩放因子
const scaleFactor = 2 / maxSize; // 假设我们希望模型最大为2单位
return scaleFactor;
};
export const getTriangleVertexs = (
geometry: THREE.BufferGeometry
): THREE.Vector3[][] => {
const positions = geometry.attributes.position;
const triangles: THREE.Vector3[][] = [];
const getTriangleVertices = (
index1: number,
index2: number,
index3: number
) => [
new THREE.Vector3(
positions.getX(index1),
positions.getY(index1),
positions.getZ(index1)
),
new THREE.Vector3(
positions.getX(index2),
positions.getY(index2),
positions.getZ(index2)
),
new THREE.Vector3(
positions.getX(index3),
positions.getY(index3),
positions.getZ(index3)
),
];
if (geometry.index) {
const indices = geometry.index.array;
for (let i = 0; i < indices.length; i += 3) {
triangles.push(
getTriangleVertices(indices[i], indices[i + 1], indices[i + 2])
);
}
} else {
for (let i = 0; i < positions.count; i += 3) {
triangles.push(getTriangleVertices(i, i + 1, i + 2));
}
}
return triangles;
};
export const getOffsetTriangles = (
triangles: THREE.Vector3[][],
offset: number
): THREE.Vector3[][] => {
const newTriangles: THREE.Vector3[][] = [];
triangles.forEach((triangle) => {
// 计算三角形的法线
const normal = new THREE.Vector3();
const edge1 = new THREE.Vector3().subVectors(triangle[1], triangle[0]);
const edge2 = new THREE.Vector3().subVectors(triangle[2], triangle[0]);
normal.crossVectors(edge1, edge2).normalize();
// 使用法线和偏移量计算新的三角形顶点
const offsetNormal = normal.clone().multiplyScalar(offset);
const newTriangle = triangle.map((vertex) =>
vertex.clone().sub(offsetNormal)
);
newTriangles.push(newTriangle);
});
return newTriangles;
};
export const createEnclosedGeometry = (
triangles: THREE.Vector3[][],
newTriangles: THREE.Vector3[][]
): THREE.BufferGeometry => {
const geometry = new THREE.BufferGeometry();
const vertices: THREE.Vector3[] = [];
const indices: number[] = [];
const processedEdges: Set<string> = new Set();
function edgeId(v1: THREE.Vector3, v2: THREE.Vector3): string {
return `${v1.x},${v1.y},${v1.z}->${v2.x},${v2.y},${v2.z}`;
}
triangles.forEach((triangle, index) => {
const innerTriangle = newTriangles[index];
triangle.forEach((vertex) => {
vertices.push(vertex);
});
innerTriangle.forEach((vertex) => {
vertices.push(vertex);
});
// Process the three edges for each triangle
for (let i = 0; i < 3; i++) {
const next = (i + 1) % 3;
const edge = edgeId(triangle[i], triangle[next]);
if (!processedEdges.has(edge)) {
processedEdges.add(edge);
// Add the vertices for the quad (two triangles)
const quadVertices = [
triangle[i],
triangle[next],
innerTriangle[i],
innerTriangle[next],
];
quadVertices.forEach((vertex) => {
vertices.push(vertex);
});
const baseIndex = vertices.length - 4;
// First triangle of the quad
indices.push(baseIndex, baseIndex + 2, baseIndex + 1);
// Second triangle of the quad
indices.push(baseIndex + 1, baseIndex + 2, baseIndex + 3);
}
}
});
geometry.setFromPoints(vertices);
geometry.setIndex(indices);
return geometry;
};
// export const createEnclosedGeometry = (
// triangles: THREE.Vector3[][],
// newTriangles: THREE.Vector3[][]
// ): THREE.BufferGeometry => {
// const geometry = new THREE.BufferGeometry();
// const vertices: number[] = [];
// const indices: number[] = [];
// // 添加原始三角形和新三角形的顶点到vertices数组
// triangles.forEach((triangle) => {
// triangle.forEach((v) => {
// vertices.push(v.x, v.y, v.z);
// });
// });
// newTriangles.forEach((triangle) => {
// triangle.forEach((v) => {
// vertices.push(v.x, v.y, v.z);
// });
// });
// const totalTriangles = triangles.length;
// // 创建索引来连接triangles和newTriangles中的三角形
// for (let i = 0; i < totalTriangles; i++) {
// const offset = totalTriangles * 3; // newTriangles在vertices中的偏移量
// const a1 = i * 3;
// const b1 = a1 + 1;
// const c1 = a1 + 2;
// const a2 = offset + i * 3;
// const b2 = a2 + 1;
// const c2 = a2 + 2;
// // 添加原始和新三角形的索引
// indices.push(a1, b1, c1);
// indices.push(a2, c2, b2);
// // 为每一对相邻的三角形添加边的索引
// indices.push(a1, b1, a2);
// indices.push(b1, b2, a2);
// indices.push(b1, c1, b2);
// indices.push(c1, c2, b2);
// indices.push(c1, a1, c2);
// indices.push(a1, a2, c2);
// }
// geometry.setIndex(indices);
// geometry.setAttribute(
// "position",
// new THREE.Float32BufferAttribute(vertices, 3)
// );
// geometry.computeVertexNormals(); // 计算顶点法线
// return geometry;
// };

View File

@ -17,6 +17,10 @@ export const baseRoutes: (RouteObject & ExpandRouteProps)[] = [
element: <Login />, element: <Login />,
title: "登录 - CVPILOT Viewer", title: "登录 - CVPILOT Viewer",
}, },
{
path: "root/report/full",
element: <ReportFullVersion />,
},
]; ];
export const commonRoutes: (RouteObject & ExpandRouteProps)[] = [ export const commonRoutes: (RouteObject & ExpandRouteProps)[] = [
@ -41,10 +45,7 @@ export const commonRoutes: (RouteObject & ExpandRouteProps)[] = [
path: "root/viewer", path: "root/viewer",
element: <RootViewer />, element: <RootViewer />,
}, },
{
path: "root/report/full",
element: <ReportFullVersion />,
},
{ {
path: "peripheral/viewer", path: "peripheral/viewer",
element: <PeripheralViewer />, element: <PeripheralViewer />,

View File

@ -21,10 +21,11 @@ export class AuthController {
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,
) { ) {
const { username, password, phoneNumber } = userLoginDto; const { username, password, phoneNumber } = userLoginDto;
// TODO: isEnabled、phoneNumber用于后续验证 //* Step1: 询问认证中心服务,用户是否合法
const { isLegal, data, msg } = await firstValueFrom( const { isLegal, data, msg } = await firstValueFrom(
this.client.send('cert.user.account', { username, password }), this.client.send('cert.user.account', { username, password }),
); );
//* Step2: 上报登录日志
await firstValueFrom( await firstValueFrom(
this.client.send('logger.user.signIn', { this.client.send('logger.user.signIn', {
platform: 'dmp', platform: 'dmp',
@ -35,10 +36,11 @@ export class AuthController {
}), }),
); );
if (isLegal) { if (isLegal) {
// 签发token //* Step3: 签发token
const { token } = await firstValueFrom( const { token } = await firstValueFrom(
this.client.send('cert.token.create', { username }), this.client.send('cert.token.create', { username }),
); );
//* Step4: 询问认证中心token存在cookie中的key统一个业务的token的key以及过期时间
const { tokenKeyInCookie, expires } = await firstValueFrom( const { tokenKeyInCookie, expires } = await firstValueFrom(
this.client.send('cert.token.config', []), this.client.send('cert.token.config', []),
); );

View File

@ -15,10 +15,11 @@ export class AuthController {
@Res({ passthrough: true }) res: Response, @Res({ passthrough: true }) res: Response,
) { ) {
const { username, password } = userLoginDto; const { username, password } = userLoginDto;
//* Step1: 询问认证中心服务,用户是否合法
const { isLegal, data, msg } = await firstValueFrom( const { isLegal, data, msg } = await firstValueFrom(
this.client.send('cert.user.account', { username, password }), this.client.send('cert.user.account', { username, password }),
); );
// 日志 //* Step2: 上报登录日志
await firstValueFrom( await firstValueFrom(
this.client.send('logger.user.signIn', { this.client.send('logger.user.signIn', {
platform: 'dmp', platform: 'dmp',
@ -29,11 +30,12 @@ export class AuthController {
}), }),
); );
if (isLegal) { if (isLegal) {
// 签发token,签用户的角色,前端UI路由鉴权 //* Step3: 签发token,签用户的角色,前端UI路由鉴权
const { roles } = data; const { roles } = data;
const { token } = await firstValueFrom( const { token } = await firstValueFrom(
this.client.send('cert.token.create', { username, roles }), this.client.send('cert.token.create', { username, roles }),
); );
//* Step4: 询问认证中心token存在cookie中的key统一个业务的token的key以及过期时间
const { tokenKeyInCookie, expires } = await firstValueFrom( const { tokenKeyInCookie, expires } = await firstValueFrom(
this.client.send('cert.token.config', []), this.client.send('cert.token.config', []),
); );

File diff suppressed because it is too large Load Diff