feat: 列表

This commit is contained in:
mozzie 2023-09-04 16:34:39 +08:00
parent a84bfb028a
commit d63eb1a5af
19 changed files with 275 additions and 111 deletions

View File

@ -28,4 +28,8 @@ export class UserRepository {
async findArchiveTask() {
return await Apis.findArchiveTask();
}
async findDicoms() {
return await Apis.findDicoms();
}
}

View File

@ -54,7 +54,12 @@ export class UserService {
*
*/
async createArchiveTask(user: User, study: Study[]) {
return await this.userRepository.createArchiveTask({ user, study });
const { code, data } = await this.userRepository.createArchiveTask({
user,
study,
});
const { ignore } = data as { ignore: [] };
return { code, ignore };
}
/**
@ -63,4 +68,8 @@ export class UserService {
async findArchiveTask() {
return await this.userRepository.findArchiveTask();
}
async findDicoms(){
return await this.userRepository.findDicoms()
}
}

View File

@ -104,7 +104,7 @@ class AxiosRequestInstance {
public async post<T = any>(
url: string,
data?: any,
config?: RequestConfig & { onRequestSent?: RequestCallback }
config?: RequestConfig & { onRequestSent?: RequestCallback } & any
): Promise<T> {
const response = await this.instance.post<T>(url, data, config);
return response.data;

View File

@ -78,4 +78,6 @@ export const Apis = {
*/
findArchiveTask: (): ResponseType =>
Request.get(PREFIX + "/annotator/find/archiveTask"),
findDicoms: (): ResponseType => Request.get(PREFIX + "/admin/find/dicom/all"),
};

View File

@ -1,46 +0,0 @@
import { ROLE_NAME } from "@/constant";
import {
CloudUploadOutlined,
DatabaseOutlined,
UnorderedListOutlined,
} from "@ant-design/icons";
import { MenuProps } from "antd";
export type MenuItem = Required<MenuProps>["items"][number];
const getItem = (
label: React.ReactNode,
key: React.Key,
icon?: React.ReactNode,
children?: MenuItem[],
type?: "group"
): MenuItem => {
return {
key,
icon,
children,
label,
type,
} as MenuItem;
};
const adminMenuItems: MenuItem[] = [
getItem("影像", "dicom", <DatabaseOutlined />, [
getItem("上传", "/upload", <CloudUploadOutlined />),
getItem("列表", "/list", <UnorderedListOutlined />),
]),
];
const annotatorMenuItems: MenuItem[] = [
getItem("影像", "dicom", <DatabaseOutlined />, [
getItem("标注", "/list", <CloudUploadOutlined />),
]),
];
/**
* key对应roles的name字段key
*/
export const roleMenusMapping: Record<ROLE_NAME, MenuItem[]> = {
[ROLE_NAME.ADMIN]: adminMenuItems,
[ROLE_NAME.ANNOTATOR]: annotatorMenuItems,
};

View File

@ -1,7 +0,0 @@
interface ArchiveTaskProps {
children?: JSX.Element;
}
export const ArchiveTask = (props: ArchiveTaskProps) => {
return <div>ArchiveTask</div>
}

View File

@ -0,0 +1,35 @@
import { TableColumnsType } from "antd";
import { DataItemType } from ".";
export const columnsForStudy: TableColumnsType<DataItemType> = [
{ title: "PatientID", dataIndex: "PatientID", key: "PatientID" },
{ title: "患者姓名", dataIndex: "PatientName", key: "PatientName" },
{ title: "性别", dataIndex: "PatientSex", key: "PatientSex" },
{ title: "出生日期", dataIndex: "PatientBirthDate", key: "PatientBirthDate" },
{ title: "病例日期", dataIndex: "StudyDate", key: "StudyDate" },
{
title: "相关序列数",
dataIndex: "NumberPatientRelatedInstances",
key: "NumberPatientRelatedInstances",
},
];
export const columnsForSeries: TableColumnsType<DataItemType> = [
{ title: "序列号", dataIndex: "SeriesNumber", key: "SeriesNumber" },
{
title: "成像设备",
dataIndex: "Modality",
key: "Modality",
},
{
title: "序列描述",
dataIndex: "SeriesDescription",
key: "SeriesDescription",
},
{
title: "切片数",
dataIndex: "NumberSeriesRelatedInstances",
key: "NumberSeriesRelatedInstances",
},
];

View File

@ -1,7 +1,97 @@
import { useDomain } from "@/hook/useDomain";
import { Button, Space, Table } from "antd";
import { useEffect, useState } from "react";
import { columnsForStudy, columnsForSeries } from "./columns";
import { EyeOutlined } from "@ant-design/icons";
import { openOHIFViewer } from "../Upload/util";
interface DicomListProps {
children?: JSX.Element;
}
export const DicomList = (props: DicomListProps) => {
return <div>DicomList</div>;
export type DataItemType = {
StudyDate: string;
StudyTime: string;
AccessionNumber: string;
Modality: string;
PatientName: string;
PatientID: string;
PatientBirthDate: string;
PatientSex: string;
StudyInstanceUID: string;
SeriesInstanceUID: string;
CharacterSet: string;
SeriesDescription: string;
StudyID: string;
SeriesNumber: string | number;
NumberSeriesRelatedInstances: string | number;
NumberPatientRelatedInstances: string | number;
NumberPatientRelatedSeries: string | number;
subs: DataItemType[];
};
export const DicomList = (props: DicomListProps) => {
const [dataSource, setDataSource] = useState<DataItemType[]>([]);
const [tableLoading, setTableLoading] = useState(false);
const { userDomainService } = useDomain();
useEffect(() => {
setTableLoading(true);
userDomainService.findDicoms().then((result) => {
const { data } = result;
setDataSource(data as DataItemType[]);
setTableLoading(false);
});
}, []);
/**
*
*/
const expandedRowRenderForSeries = (record: DataItemType) => {
return (
<Table
rowKey="SeriesInstanceUID"
columns={[
...columnsForSeries,
{
title: "操作",
dataIndex: "operation",
render: (_: any, recordSeries: DataItemType) => (
<Space>
<Button
type="primary"
size="small"
icon={<EyeOutlined />}
onClick={() => onViewDicom(record, recordSeries)}
>
</Button>
</Space>
),
},
]}
dataSource={record.subs}
pagination={false}
/>
);
};
const onViewDicom = (record: DataItemType, recordSeries: DataItemType) => {
const { StudyInstanceUID } = record;
const { SeriesInstanceUID } = recordSeries;
openOHIFViewer(StudyInstanceUID, SeriesInstanceUID);
};
return (
<div>
<Table
dataSource={dataSource}
columns={columnsForStudy}
loading={tableLoading}
expandable={{
expandedRowRender: expandedRowRenderForSeries,
}}
rowKey="StudyInstanceUID"
/>
</div>
);
};

View File

@ -126,9 +126,19 @@ export const DicomUpload = (props: DicomUploadProps) => {
/**
*
*/
const onAssignConfirm = () => {
const onAssignConfirm = async () => {
if (!selectAnnotator?.id) return;
userDomainService.createArchiveTask(selectAnnotator, selectRows);
const { code, ignore } = await userDomainService.createArchiveTask(
selectAnnotator,
selectRows
);
if (code === 0) {
const info =
ignore?.length > 0
? `,其中${ignore.length}条序列,用户${selectAnnotator.username}已存在`
: ``;
message.info(`创建任务成功${info}`);
}
setSelectAnnotator(undefined);
setIsModalOpen(false);
};

View File

@ -0,0 +1,7 @@
interface LabelProps {
children?: JSX.Element;
}
export const Label = (props: LabelProps) => {
return <div>Label</div>
}

View File

@ -3,6 +3,7 @@ import { Layout } from "@/components/Layout";
import {
CloudUploadOutlined,
DatabaseOutlined,
TagsOutlined,
UnorderedListOutlined,
} from "@ant-design/icons";
import { Outlet } from "react-router";
@ -19,6 +20,7 @@ const adminMenuItems: MenuItem[] = [
getItem("上传", "/upload", <CloudUploadOutlined />),
getItem("列表", "/list", <UnorderedListOutlined />),
]),
getItem("标签", "/label", <TagsOutlined />),
];
export const AdminDashboard = (props: AdminDashboardProps) => {

View File

@ -6,6 +6,7 @@ import { ExpandRouteProps } from ".";
import { ROLE_NAME } from "@/constant";
import { AdminDashboard } from "@/modules/Admin";
import { AnnotatorDashBoard } from "@/modules/Annotator";
import { Label } from "@/modules/Admin/Label";
export const roleRoutes: Record<ROLE_NAME, (RouteObject & ExpandRouteProps)[]> =
{
@ -29,6 +30,10 @@ export const roleRoutes: Record<ROLE_NAME, (RouteObject & ExpandRouteProps)[]> =
path: "/upload",
element: <DicomUpload />,
},
{
path: "/label",
element: <Label />,
},
],
},
// {

View File

@ -5,4 +5,6 @@ NACOS_ADDR=127.0.0.1:8848
NACOS_NAMESPACE=56a3b295-f319-4ced-82b5-0df2e98cc541
# nacos配置中心
NACOS_DATAID='test'
NACOS_GROUP='DEFAULT_GROUP'
NACOS_GROUP='DEFAULT_GROUP'
# dicom配置可以后期转移到nacos配置中心
PACS_URL=http://localhost:8042/dicom-web/

View File

@ -34,7 +34,8 @@
"dayjs": "1.11.9",
"flatted": "3.2.7",
"crypto-js": "4.1.1",
"@tavi/util": "workspace:*"
"@tavi/util": "workspace:*",
"axios": "1.5.0"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",

View File

@ -1,7 +1,56 @@
import { Controller } from '@nestjs/common';
import { AppService } from './app.service';
import { EventPattern } from '@nestjs/microservices';
import { ConfigService } from '@nestjs/config';
import axios from 'axios';
const metaFormatter = (data) => {
return {
StudyDate: data['00080020']?.Value?.[0] ?? '',
StudyTime: data['00080030']?.Value?.[0] ?? '',
AccessionNumber: data['00080050']?.Value?.[0] ?? '',
Modality: data['00080060']?.Value?.[0] ?? '',
PatientName: (data['00100010']?.Value?.[0] as any).Alphabetic,
PatientID: data['00100020']?.Value?.[0] ?? '',
PatientBirthDate: data['00100030']?.Value?.[0] ?? '',
PatientSex: data['00100040']?.Value?.[0] ?? '',
StudyInstanceUID: data['0020000D']?.Value?.[0] ?? '',
SeriesInstanceUID: data['0020000E']?.Value?.[0] ?? '',
CharacterSet: data['00080005']?.Value?.[0] ?? '',
SeriesDescription: data['0008103E']?.Value?.[0] ?? '',
StudyID: data['00200010']?.Value?.[0] ?? '',
SeriesNumber: data['00200011']?.Value?.[0] ?? '',
NumberSeriesRelatedInstances: data['00201209']?.Value?.[0] ?? '',
NumberPatientRelatedInstances: data['00201206']?.Value?.[0] ?? '',
NumberPatientRelatedSeries: data['00201208']?.Value?.[0] ?? '',
SliceThickness: data['00180050']?.Value?.[0] ?? '',
};
};
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
constructor(
private readonly appService: AppService,
private readonly configService: ConfigService,
) {}
@EventPattern({ cmd: 'dicom.find.dicom' })
async findDicoms() {
const pacsUrl = this.configService.get('PACS_URL');
try {
const { data: studyData } = await axios.get(`${pacsUrl}/studies`);
const result = [];
for (const study of studyData) {
const studyItem = metaFormatter(study);
const { data: seriesData } = await axios.get(
`${pacsUrl}/studies/${studyItem.StudyInstanceUID}/series`,
);
const subs = seriesData.map((s) => metaFormatter(s));
result.push({ ...studyItem, subs });
}
return { data: result };
} catch (error) {
throw new Error(`Failed to fetch DICOM data: ${error.message}`);
}
}
}

View File

@ -12,7 +12,7 @@ export class AppController {
}
@EventPattern({ cmd: 'archive.task.find' })
async findArchiveTask({ username }) {
return await this.appService.findArchiveTask({ username });
async findArchiveTask(payload) {
return await this.appService.findArchiveTask(payload);
}
}

View File

@ -12,25 +12,36 @@ export class AppService {
async createArchiveTask(payload) {
const { username, study } = payload;
try {
// 跳过的数据
const ignore = [];
for (let i = 0; i < study.length; i++) {
const { StudyInstanceUID, PatientID } = study[i];
for (let j = 0; j < study[i].subs.length; j++) {
const { SeriesInstanceUID } = study[i].subs[j];
await this.archiveTaskRepository.save({
username,
PatientID,
StudyInstanceUID,
SeriesInstanceUID,
// 检查是否病已经分配过
const exist = await this.archiveTaskRepository.findOne({
where: { username, StudyInstanceUID, SeriesInstanceUID },
});
exist
? ignore.push(exist)
: await this.archiveTaskRepository.save({
username,
PatientID,
StudyInstanceUID,
SeriesInstanceUID,
});
}
}
return { success: true };
return { success: true, data: { ignore } };
} catch (error) {
return { success: false, error };
}
}
async findArchiveTask({ username }) {
return await this.archiveTaskRepository.find({ where: { username } });
return await this.archiveTaskRepository.find({
where: { username },
order: { createTime: 'DESC' },
});
}
}

View File

@ -18,9 +18,17 @@ export class AdminController {
async createArchiveTask(@Body() body) {
const { user, study } = body;
const { username } = user;
const { success, error } = await firstValueFrom(
const { success, data, error } = await firstValueFrom(
this.client.send({ cmd: 'archive.task.create' }, { username, study }),
);
return success ? { code: 0 } : { code: 1, msg: error.code };
return success ? { code: 0, data } : { code: 1, msg: error.code };
}
@Get('find/dicom/all')
async findDicom() {
const { data } = await firstValueFrom(
this.client.send({ cmd: 'dicom.find.dicom' }, {}),
);
return { code: 0, data };
}
}

View File

@ -430,7 +430,7 @@ importers:
dependencies:
'@nestjs/axios':
specifier: 2.0.0
version: 2.0.0(@nestjs/common@9.0.0)(axios@1.4.0)(reflect-metadata@0.1.13)(rxjs@7.8.1)
version: 2.0.0(@nestjs/common@9.0.0)(axios@1.5.0)(reflect-metadata@0.1.13)(rxjs@7.8.1)
'@nestjs/common':
specifier: ^9.0.0
version: 9.0.0(reflect-metadata@0.1.13)(rxjs@7.8.1)
@ -858,6 +858,9 @@ importers:
'@tavi/util':
specifier: workspace:*
version: link:../../../packages/util
axios:
specifier: 1.5.0
version: registry.npmmirror.com/axios@1.5.0
bcrypt:
specifier: 5.1.0
version: registry.npmmirror.com/bcrypt@5.1.0
@ -3327,7 +3330,7 @@ packages:
- supports-color
dev: false
/@nestjs/axios@2.0.0(@nestjs/common@9.0.0)(axios@1.4.0)(reflect-metadata@0.1.13)(rxjs@7.8.1):
/@nestjs/axios@2.0.0(@nestjs/common@9.0.0)(axios@1.5.0)(reflect-metadata@0.1.13)(rxjs@7.8.1):
resolution: {integrity: sha512-F6oceoQLEn031uun8NiommeMkRIojQqVryxQy/mK7fx0CI0KbgkJL3SloCQcsOD+agoEnqKJKXZpEvL6FNswJg==}
peerDependencies:
'@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0
@ -3336,7 +3339,7 @@ packages:
rxjs: ^6.0.0 || ^7.0.0
dependencies:
'@nestjs/common': 9.0.0(reflect-metadata@0.1.13)(rxjs@7.8.1)
axios: registry.npmmirror.com/axios@1.4.0
axios: registry.npmmirror.com/axios@1.5.0
reflect-metadata: 0.1.13
rxjs: 7.8.1
dev: false
@ -5028,9 +5031,6 @@ packages:
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
dev: false
/asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
/atob@2.1.2:
resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==}
engines: {node: '>= 4.5.0'}
@ -5524,12 +5524,6 @@ packages:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
dev: true
/combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
dependencies:
delayed-stream: 1.0.0
/commander@10.0.1:
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
engines: {node: '>=14'}
@ -6021,10 +6015,6 @@ packages:
object-keys: 1.1.1
dev: true
/delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
/denque@2.1.0:
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
engines: {node: '>=0.10'}
@ -6749,6 +6739,7 @@ packages:
peerDependenciesMeta:
debug:
optional: true
dev: false
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@ -6808,9 +6799,10 @@ packages:
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
engines: {node: '>= 6'}
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
asynckit: registry.npmmirror.com/asynckit@0.4.0
combined-stream: registry.npmmirror.com/combined-stream@1.0.8
mime-types: registry.npmmirror.com/mime-types@2.1.35
dev: false
/formidable@2.1.2:
resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==}
@ -7187,7 +7179,7 @@ packages:
engines: {node: '>=8.0.0'}
dependencies:
eventemitter3: 4.0.7
follow-redirects: 1.15.2
follow-redirects: registry.npmmirror.com/follow-redirects@1.15.2
requires-port: 1.0.0
transitivePeerDependencies:
- debug
@ -7997,15 +7989,11 @@ packages:
picomatch: registry.npmmirror.com/picomatch@2.3.1
dev: true
/mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
/mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
dependencies:
mime-db: 1.52.0
mime-db: registry.npmmirror.com/mime-db@1.52.0
/min-indent@1.0.1:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
@ -10324,7 +10312,7 @@ packages:
debug: registry.npmmirror.com/debug@2.6.9
escape-html: 1.0.3
http-errors: 1.6.3
mime-types: 2.1.35
mime-types: registry.npmmirror.com/mime-types@2.1.35
parseurl: 1.3.3
transitivePeerDependencies:
- supports-color
@ -10718,7 +10706,7 @@ packages:
cookiejar: 2.1.4
debug: registry.npmmirror.com/debug@4.3.4
fast-safe-stringify: registry.npmmirror.com/fast-safe-stringify@2.1.1
form-data: 4.0.0
form-data: registry.npmmirror.com/form-data@4.0.0
formidable: 2.1.2
methods: registry.npmmirror.com/methods@1.1.2
mime: registry.npmmirror.com/mime@2.6.0
@ -11512,7 +11500,7 @@ packages:
dependencies:
colorette: 2.0.20
memfs: 3.5.3
mime-types: 2.1.35
mime-types: registry.npmmirror.com/mime-types@2.1.35
range-parser: 1.2.1
schema-utils: 4.2.0
webpack: 5.75.0(webpack-cli@5.0.2)
@ -13590,12 +13578,11 @@ packages:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz}
name: asynckit
version: 0.4.0
dev: false
registry.npmmirror.com/axios@1.4.0:
resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/axios/-/axios-1.4.0.tgz}
registry.npmmirror.com/axios@1.5.0:
resolution: {integrity: sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/axios/-/axios-1.5.0.tgz}
name: axios
version: 1.4.0
version: 1.5.0
dependencies:
follow-redirects: registry.npmmirror.com/follow-redirects@1.15.2
form-data: registry.npmmirror.com/form-data@4.0.0
@ -14058,7 +14045,6 @@ packages:
engines: {node: '>= 0.8'}
dependencies:
delayed-stream: registry.npmmirror.com/delayed-stream@1.0.0
dev: false
registry.npmmirror.com/commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz}
@ -14336,7 +14322,6 @@ packages:
name: delayed-stream
version: 1.0.0
engines: {node: '>=0.4.0'}
dev: false
registry.npmmirror.com/delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz}
@ -14955,7 +14940,6 @@ packages:
peerDependenciesMeta:
debug:
optional: true
dev: false
registry.npmmirror.com/fork-ts-checker-webpack-plugin@7.2.11(typescript@4.7.4)(webpack@5.73.0):
resolution: {integrity: sha512-2e5+NyTUTE1Xq4fWo7KFEQblCaIvvINQwUX3jRmEGlgCTc1Ecqw/975EfQrQ0GEraxJTnp8KB9d/c8hlCHUMJA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.11.tgz}
@ -14995,7 +14979,6 @@ packages:
asynckit: registry.npmmirror.com/asynckit@0.4.0
combined-stream: registry.npmmirror.com/combined-stream@1.0.8
mime-types: registry.npmmirror.com/mime-types@2.1.35
dev: false
registry.npmmirror.com/formstream@1.3.1:
resolution: {integrity: sha512-FkW++ub+VbE5dpwukJVDizNWhSgp8FhmhI65pF7BZSVStBqe6Wgxe2Z9/Vhsn7l7nXCPwP+G1cyYlX8VwWOf0g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/formstream/-/formstream-1.3.1.tgz}
@ -15901,7 +15884,6 @@ packages:
name: mime-db
version: 1.52.0
engines: {node: '>= 0.6'}
dev: true
registry.npmmirror.com/mime-types@2.1.18:
resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mime-types/-/mime-types-2.1.18.tgz}
@ -15918,7 +15900,7 @@ packages:
version: 2.1.35
engines: {node: '>= 0.6'}
dependencies:
mime-db: 1.52.0
mime-db: registry.npmmirror.com/mime-db@1.52.0
registry.npmmirror.com/mime@1.6.0:
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz}