feat: 标签分类

This commit is contained in:
mozzie 2023-09-14 16:49:41 +08:00
parent 61a874ca6f
commit f902254909
12 changed files with 212 additions and 68 deletions

View File

@ -0,0 +1,10 @@
export type LabelCategoryType = {
name: string;
};
export class LabelCategory {
name: string;
constructor(props: LabelCategoryType) {
this.name = props.name;
}
}

View File

@ -0,0 +1,8 @@
import { Apis } from "@@/infra/api";
import { LabelCategory } from "./entities/labelCategory";
export class LabelRepository {
async createNewLabelCategory(labelCategory: LabelCategory) {
return await Apis.createNewLabelCategory(labelCategory);
}
}

View File

@ -0,0 +1,13 @@
import { LabelCategory } from "./entities/labelCategory";
import { LabelRepository } from "./labelRepository";
export class LabelService {
constructor(private labelRepository: LabelRepository) {}
async createNewLabelCategory(labelCategory: LabelCategory) {
const { code } = await this.labelRepository.createNewLabelCategory(
labelCategory
);
return { code };
}
}

View File

@ -0,0 +1,36 @@
import { Study } from "@/modules/Admin/Dicom/Upload/DicomUploader/util";
import { User } from "@@/domain/User/entities/User";
export type ResponseType = Promise<{
code?: number | string;
data?: unknown;
msg?: string;
}>;
export type ResponsePacsType = Promise<{
ID: string;
ParentPatient: string;
ParentSeries: string;
ParentStudy: string;
Path: string;
Status: string;
}>;
export type ExistInPacsDTO = {
StudyInstanceUID: string;
SeriesInstanceUID: string;
};
export type ArchiveTaskCreateDto = {
user: User;
study: Study[];
};
export type DownloadArchiveDTO = {
ID: string;
Type: "study" | "series" | "Study" | "Series";
};
export type labelCategoryDTO = {
name: string;
};

View File

@ -1,43 +1,20 @@
import { User } from "@@/domain/User/entities/User"; import { User } from "@@/domain/User/entities/User";
import { Request } from "./Request"; import { Request } from "./Request";
import { Study } from "@/modules/Admin/Dicom/Upload/DicomUploader/util";
import axios from "axios"; import axios from "axios";
import { saveAs } from "file-saver"; import { saveAs } from "file-saver";
import {
ArchiveTaskCreateDto,
DownloadArchiveDTO,
ExistInPacsDTO,
ResponsePacsType,
ResponseType,
labelCategoryDTO,
} from "./dto";
const PREFIX = "/api/dmp"; const PREFIX = "/api/dmp";
const PREFIX_CERT = "/cert"; const PREFIX_CERT = "/cert";
const PREFIX_PACS = "/dicom-web"; const PREFIX_PACS = "/dicom-web";
type ResponseType = Promise<{
code?: number | string;
data?: unknown;
msg?: string;
}>;
type ResponsePacsType = Promise<{
ID: string;
ParentPatient: string;
ParentSeries: string;
ParentStudy: string;
Path: string;
Status: string;
}>;
export type ExistInPacsDTO = {
StudyInstanceUID: string;
SeriesInstanceUID: string;
};
export type ArchiveTaskCreateDto = {
user: User;
study: Study[];
};
export type DownloadArchiveDTO = {
ID: string;
Type: "study" | "series" | "Study" | "Series";
};
export const Apis = { export const Apis = {
/** /**
* *
@ -105,4 +82,9 @@ export const Apis = {
.catch((error) => { .catch((error) => {
console.error("Download error:", error); console.error("Download error:", error);
}), }),
/**
*
*/
createNewLabelCategory: (p: labelCategoryDTO): ResponseType =>
Request.post(PREFIX + "/dicom/label/category/create", p),
}; };

View File

@ -1,5 +1,7 @@
import { DicomRepository } from "@@/domain/Dicom/DicomRepository"; import { DicomRepository } from "@@/domain/Dicom/DicomRepository";
import { DicomService } from "@@/domain/Dicom/DicomService"; import { DicomService } from "@@/domain/Dicom/DicomService";
import { LabelRepository } from "@@/domain/Label/labelRepository";
import { LabelService } from "@@/domain/Label/labelService";
import { UserRepository } from "@@/domain/User/UserRepository"; import { UserRepository } from "@@/domain/User/UserRepository";
import { UserService } from "@@/domain/User/UserService"; import { UserService } from "@@/domain/User/UserService";
import { createContext } from "react"; import { createContext } from "react";
@ -7,11 +9,13 @@ import { createContext } from "react";
export type Services = { export type Services = {
userDomainService: UserService; userDomainService: UserService;
dicomDomainService: DicomService; dicomDomainService: DicomService;
labelDomainService: LabelService;
}; };
const defaultServiceMap = { const defaultServiceMap = {
userDomainService: new UserService(new UserRepository()), userDomainService: new UserService(new UserRepository()),
dicomDomainService: new DicomService(new DicomRepository()), dicomDomainService: new DicomService(new DicomRepository()),
labelDomainService: new LabelService(new LabelRepository()),
}; };
export const DomainServiceContext = createContext<Services>(defaultServiceMap); export const DomainServiceContext = createContext<Services>(defaultServiceMap);

View File

@ -6,5 +6,42 @@
aside { aside {
padding: 20px 20px 0 20px; padding: 20px 20px 0 20px;
border-right: 1px solid rgba(5, 5, 5, 0.06); border-right: 1px solid rgba(5, 5, 5, 0.06);
.label-category-header {
padding: 6px !important;
background: transparent !important;
user-select: none;
}
.label-category-item {
margin-bottom: 10px;
border: none;
background: transparent;
// &.ant-collapse-item-active {
// background: rgba(204, 204, 204, .1);
// }
}
.label-catalog {
margin: 0;
padding: 0;
list-style: none;
li {
margin-bottom: 2px;
padding: 6px 0 6px 10px;
border-radius: 6px;
cursor: pointer;
&:hover {
background: rgba(204, 204, 204, .1);
}
&.active {
background: rgba(204, 204, 204, .2);
}
}
}
} }
} }

View File

@ -1,56 +1,105 @@
import { CSSProperties } from "react"; import { useState } from "react";
import "./index.less"; import "./index.less";
import { Collapse, CollapseProps, theme } from "antd"; import {
import { CaretRightOutlined } from "@ant-design/icons"; Button,
Collapse,
CollapseProps,
Form,
Input,
Modal,
theme,
Typography,
} from "antd";
import { CaretRightOutlined, PlusOutlined } from "@ant-design/icons";
import { useDomain } from "@/hook/useDomain";
const { Text } = Typography;
interface LabelProps { interface LabelProps {
children?: JSX.Element; children?: JSX.Element;
} }
const content = ( const content = (
<ul> <ul className="label-catalog">
<li></li> <li></li>
<li>{"层厚>1.0mm"}</li> <li className="active">{"层厚>1.0mm"}</li>
</ul> </ul>
); );
const getItems: (panelStyle: CSSProperties) => CollapseProps["items"] = ( const getItems = (): CollapseProps["items"] =>
panelStyle [
) => [ {
{ key: "1",
key: "1", label: "影像质量",
label: "影像质量", children: content,
children: content, },
style: panelStyle, {
}, key: "2",
{ label: "其他",
key: "2", children: <p>1</p>,
label: "其他", },
children: <p>1</p>, ].map((i) => ({
style: panelStyle, ...i,
}, headerClass: "label-category-header",
]; className: "label-category-item",
}));
export const Label = (props: LabelProps) => { export const Label = (props: LabelProps) => {
const { token } = theme.useToken(); const { token } = theme.useToken();
const [isModalOpen, setIsModalOpen] = useState(false);
const [createLabelCategoryForm] = Form.useForm<{ name: string }>();
const { labelDomainService } = useDomain();
const panelStyle: React.CSSProperties = { const handleOk = async () => {
marginBottom: 12, try {
background: token.colorFillAlter, await createLabelCategoryForm.validateFields();
borderRadius: token.borderRadiusLG, const { name } = createLabelCategoryForm.getFieldsValue();
border: "none", labelDomainService.createNewLabelCategory({ name });
} catch (error) {
console.log(error);
}
}; };
return ( return (
<div className="label-container"> <div className="label-container">
<aside> <aside>
<Button
block
type="dashed"
icon={<PlusOutlined />}
style={{ marginBottom: 10 }}
onClick={() => setIsModalOpen(true)}
>
</Button>
<Modal
title="新增标签分类"
open={isModalOpen}
onOk={handleOk}
width={350}
okText="确认"
cancelText="再想想"
onCancel={() => setIsModalOpen(false)}
>
<Form form={createLabelCategoryForm} style={{ marginTop: 20 }}>
<Form.Item
name="name"
rules={[
{ required: true, message: "标签分类名称不能为空" },
{ max: 10, message: "不能超过十个字符" },
]}
>
<Input placeholder="请输入标签分类名称" autoComplete="off" />
</Form.Item>
</Form>
</Modal>
<Collapse <Collapse
bordered={false} bordered={false}
defaultActiveKey={[]} defaultActiveKey={[]}
expandIcon={({ isActive }) => ( expandIcon={({ isActive }) => (
<CaretRightOutlined rotate={isActive ? 90 : 0} /> <CaretRightOutlined rotate={isActive ? 90 : 0} />
)} )}
style={{ background: token.colorBgContainer }} style={{ background: token.colorBgContainer, color: token.colorText }}
items={getItems(panelStyle)} items={getItems()}
/> />
</aside> </aside>
<main></main> <main></main>

View File

@ -2,11 +2,9 @@ import { Module } from '@nestjs/common';
import { LabelController } from './label.controller'; import { LabelController } from './label.controller';
import { LabelService } from './label.service'; import { LabelService } from './label.service';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { LabelCategory } from './entity/category.entity';
import { Label } from './entity/label.entity'; import { Label } from './entity/label.entity';
import { LabelCategory } from './entity/label.category.entity';
@Module({ @Module({
controllers: [LabelController],
imports: [ imports: [
TypeOrmModule.forRoot({ TypeOrmModule.forRoot({
type: 'mysql', type: 'mysql',
@ -21,6 +19,7 @@ import { LabelCategory } from './entity/label.category.entity';
}), }),
TypeOrmModule.forFeature([Label, LabelCategory]), TypeOrmModule.forFeature([Label, LabelCategory]),
], ],
controllers: [LabelController],
providers: [LabelService], providers: [LabelService],
}) })
export class LabelModule {} export class LabelModule {}

View File

@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { Label } from './entity/label.entity'; import { Label } from './entity/label.entity';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { LabelCategory } from './entity/label.category.entity'; import { LabelCategory } from './entity/category.entity';
@Injectable() @Injectable()
export class LabelService { export class LabelService {
@ -13,11 +13,8 @@ export class LabelService {
private readonly labelCategoryRepository: Repository<LabelCategory>, private readonly labelCategoryRepository: Repository<LabelCategory>,
) {} ) {}
async createLabelCategory(payload) { async createLabelCategory({ name }) {
console.log(payload); return await this.labelCategoryRepository.save({ name });
return await this.labelCategoryRepository.save({
name: '默认',
});
} }
async createLabel(payload) { async createLabel(payload) {

View File

@ -25,4 +25,13 @@ export class DicomController {
return { code: 1, msg: error }; return { code: 1, msg: error };
} }
} }
@Post('label/category/create')
async createLabelCategory(@Body() body) {
const { name } = body;
const { data } = await firstValueFrom(
this.client.send({ cmd: 'dicom.label.category.create' }, { name }),
);
return { code: 0, data };
}
} }